设计模式-三大工厂模式

三大工厂模式分别是:

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

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 总结

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

相关推荐
番茄去哪了4 分钟前
Java基础面试题day01
java·开发语言·后端·javase·八股·面向对象编程
遇事不决问清风8 分钟前
AI 驱动开发实战复盘:从 0 到上线,一个真实项目的工程化总结
java·ai编程
wuqingshun3141599 分钟前
说说进程和线程的区别?
java·开发语言·jvm
Memory_荒年1 小时前
自定义 Spring Boot Starter:手搓“轮子”,但要搓出兰博基尼!
java·后端
栈外1 小时前
我是IDEA重度用户,试了4款AI编程插件:有一款有并发Bug,有一款越用越香
java·后端
架构师沉默1 小时前
为什么说 Go 做游戏服务器就有人皱眉?
java·后端·架构
a5629916191 小时前
【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目
java·spring boot·spring
秃了也弱了。1 小时前
ElasticSearch:优化案例实战解析(持续更新)
android·java·elasticsearch
文心快码BaiduComate2 小时前
Comate内置模型已支持 MiniMax-M2.7!
设计模式·程序员·前端框架
一叶落4382 小时前
LeetCode 54. 螺旋矩阵(C语言详解)——模拟 + 四边界收缩
java·c语言·数据结构·算法·leetcode·矩阵