设计模式-三大工厂模式

三大工厂模式分别是:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

1. 简单工厂模式

  • 由一个工厂决定创建哪一种产品类型的实例,只给外界一个获得产品的接口,不对外开放制造产品的细节。

说直白点,简单工厂模式就是在原本通过自己手动new出对象(产品),进行了一个优化,不想让构建细节被外部所感知到,所以加了一个工厂,由工厂执行对应的构建细节,而外部的人想要对应的产品的时候,只需要以某种标识进行获得产品这一接口的调用。

1.1 代码示例

一个Course 产品基类:

java 复制代码
public abstract class Course {
    //制作
    public abstract void make();
}

一个具体的JavaCourse 产品子类:

java 复制代码
public class JavaCourse extends Course{
    @Override
    public void make() {
        System.out.println("制作Java课程");
    }
}

一个具体的PythonCourse 产品子类:

java 复制代码
public class PythonCourse extends Course{
    @Override
    public void make() {
        System.out.println("制作Python课程");
    }
}

一个CourseFactory 工厂类:

java 复制代码
public class CourseFactory {

    //由工厂来进行产品的制作,不对外展示细节
    public static Course getCourse(String courseType) {
        if ("java".equalsIgnoreCase(courseType)) {
            return new JavaCourse();
        } else if ("python".equalsIgnoreCase(courseType)) {
            return new PythonCourse();
        } else {
            throw new RuntimeException("没有这种类型的课程");
        }
    }
}

测试

java 复制代码
public class Test {

    public static void main(String[] args) {
//        String name = "java";
        String name = "python";
        Course course = CourseFactory.getCourse(name);
        course.make();
    }
}

1.2 总结

简单工厂模式对外部隐藏了产品(对象)的构建,只需要执行工厂对外开放的接口,并进行需要产品的唯一标识告知,就可以获得需要的产品。

但是,简单工厂模式如果需要添加新的产品,需要修改本身的工厂代码,违反开放封闭原则 ,而且一个工厂进行了很多产品的制作,也不符合单一职责原则。基于这些,引出了工厂方法模式。

2. 工厂方法模式

对于一系列的同一类别的产品(对象),抽象出一个抽象工厂来确定所有类别的产品的共有逻辑。对于不同的产品,由不同类别的工厂实现类,执行自己的产品制作。需要添加新的产品的时候,就新建一个工厂实现类(满足开放封闭,也满足单一职责)。

2.1 代码示例

一个Course 产品基类:

java 复制代码
public abstract class Course {
    //制作
    public abstract void make();
}

一个具体的JavaCourse 产品子类:

java 复制代码
public class JavaCourse extends Course{
    @Override
    public void make() {
        System.out.println("制作Java课程");
    }
}

一个具体的PythonCourse 产品子类:

java 复制代码
public class PythonCourse extends Course{
    @Override
    public void make() {
        System.out.println("制作Python课程");
    }
}

一个CourseFactory 抽象工厂

java 复制代码
public abstract class CourseFactory {
    public abstract Course getCourse();
}

一个JavaCourseFactory 工厂实现类:

java 复制代码
public class JavaCourseFactory extends CourseFactory{
    @Override
    public Course getCourse() {
        return new JavaCourse();
    }
}

一个PythonCourseFactory 工厂实现类:

java 复制代码
public class PythonCourseFactory extends CourseFactory{
    @Override
    public Course getCourse() {
        return new JavaCourse();
    }
}

测试

java 复制代码
public class Test {
    public static void main(String[] args) {
//        CourseFactory factory = new JavaCourseFactory();
        CourseFactory factory = new PythonCourseFactory();

        Course course = factory.getCourse();
        course.make();
    }
}

2.2 总结

工厂方法模型,对简单工厂模型进行了优化,对于一类别的产品的共有逻辑进行抽象,对各自的实现逻辑进行了解耦,把一个复杂工厂进行了职责分离。且增加了程序的扩展性。但是,如果需要的是一系列的产品,也就是说不是管理一个产品,而是管理一系列产品,不可能一系列产品也分为多个类别,每个类别都抽象自己的抽象工厂,有各自的工厂实现,这样的话我需要一个系列产品的时候,我还得找到一系列的工厂进行产品获取。既然每次都是需要一个系列的产品,也就是套餐售卖嘛,那把一个系列的套餐封装进行一个工厂,引出了抽象工厂模型。

3. 抽象工厂模型

抽象工厂模式提供了创建一系列相关或互相依赖对象的接口,对这些系列产品抽象出系列产品中各个产品各自的共有逻辑,得到抽象工厂。对不同的系列,由不同的工厂实现类来确定各自的实现逻辑。

直白的说,抽象工厂模型就是一个套餐售卖,原本的一个产品一个产品的逻辑太杂乱了,外部根本无法自己完成整个系列的获取(压根不知道市面上有些什么沙发、衣柜、壁橱等等,干脆你给我一堆一堆的方案,我只负责方案的选择)。

3.1 代码

车门的抽象类

java 复制代码
/**
 * 车门系列的抽象类
 */
public abstract class CarDoor {
    public abstract void open();
}

A 品牌车门的实现类

java 复制代码
public class CarDoorBrandA extends CarDoor{
    @Override
    public void open() {
        System.out.println("A牌的车门可以正常开关");
    }
}

B 品牌车门的实现类

java 复制代码
public class CarDoorBrandB extends CarDoor{
    @Override
    public void open() {
        System.out.println("B牌的车门可以正常开关");
    }
}

车架的抽象类

java 复制代码
/**
 * 车架系列的抽象类
 */
public abstract class CarFrame {
    public abstract void hard();
}

A 品牌车架的实现类

java 复制代码
public class CarFrameBrandA extends CarFrame{
    @Override
    public void hard() {
        System.out.println("A牌的车架很牢固");
    }
}

B 品牌车架的实现类

java 复制代码
public class CarFrameBrandB extends CarFrame{
    @Override
    public void hard() {
        System.out.println("B牌的车架很牢固");
    }
}

底盘的抽象类

java 复制代码
/**
 * 底盘系列的抽象类
 */
public abstract class CarBasePlate {
    public abstract void stable();
}

A 品牌底盘的实现类

java 复制代码
public class CarBasePlateBrandA extends CarBasePlate{
    @Override
    public void stable() {
        System.out.println("A牌的底盘很平稳");
    }
}

B 品牌底盘的实现类

java 复制代码
public class CarBasePlateBrandB extends CarBasePlate{
    @Override
    public void stable() {
        System.out.println("B牌的底盘很平稳");
    }
}

一个抽象工厂CarFactory ,规范了车门,车架,底盘这属于一个系列产品的各自共有逻辑

java 复制代码
/**
 * 一个抽象工厂,定义了一系列的抽象产品的获取方法
 */
public abstract class CarFactory {
    public abstract CarDoor getCarDoor();

    public abstract CarFrame getCarFrame();

    public abstract CarBasePlate getCarBasePlate();
}

A 品牌系列 的工厂实现类

java 复制代码
public class CarBrandAFactory extends CarFactory{
    @Override
    public CarDoor getCarDoor() {
        return new CarDoorBrandA();
    }

    @Override
    public CarFrame getCarFrame() {
        return new CarFrameBrandA();
    }

    @Override
    public CarBasePlate getCarBasePlate() {
        return new CarBasePlateBrandA();
    }
}

B 品牌系列 的工厂实现类

java 复制代码
public class CarBrandBFactory extends CarFactory{
    @Override
    public CarDoor getCarDoor() {
        return new CarDoorBrandB();
    }

    @Override
    public CarFrame getCarFrame() {
        return new CarFrameBrandB();
    }

    @Override
    public CarBasePlate getCarBasePlate() {
        return new CarBasePlateBrandB();
    }
}

测试

java 复制代码
public class Test {
    public static void main(String[] args) {
//        CarFactory carFactory = new CarBrandAFactory();
        CarFactory carFactory = new CarBrandBFactory();

        CarDoor carDoor= carFactory.getCarDoor();
        CarFrame carFrame = carFactory.getCarFrame();
        CarBasePlate carBasePlate = carFactory.getCarBasePlate();

        carDoor.open();
        carFrame.hard();
        carBasePlate.stable();
    }
}

3.2 总结

工厂方法模式是为了管理一个产品而出现的工厂,抽象工厂模式是为了进一步管理一套产品系列而出现的工厂。

相关推荐
苹果醋318 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader37 分钟前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭1 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪1 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生1 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
ssr——ssss1 小时前
SSM-期末项目 - 基于SSM的宠物信息管理系统
java·ssm
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言
鲤籽鲲2 小时前
C# Random 随机数 全面解析
android·java·c#
zquwei2 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring