GoF23——工厂模式

✯ 面向对象设计原则

  • 对接口编程而不是对实现编程
  • 优先使用对象组合而不是继承

介绍说明

工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

作用:实现了创建者和调用者的分离;主要解决接口选择的问题。

工厂模式核心本质:

  • 实例化对象不使用new,而是用工厂方法代替
  • 将选择实现类型,创建对象统一管理和控制。从而将掉哟哦你跟着跟我们实现类解藕

三种模式:

  1. 简单工厂模式:用来生产同一等级结构中的任意产品(支持增加新产品,需覆盖已有代码)
  2. 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
  3. 抽象工厂模式:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

应用场景

  1. JDK中Calendar的getInstance方法
  2. JDBC中的Connection对象的获取
  3. Spring中IOC容器创建管理bean对象
  4. 反射中Class对象的newInstance方法

简单工厂模式(静态工厂模式)

某种程度上不符合设计原则规范没,但使用它最多。

应用实例: 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现(创建过程在其子类执行)

1. 定义一个车类接口

public interface Car {
    public void name();
}

2.编写两个实现类去实现Car接口,分别是:五菱汽车、大众汽车

public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("五菱汽车!");
    }
}
public class DaZhong implements Car{
    @Override
    public void name() {
        System.out.println("大众汽车!");
    }
}

3.编写一个车的工厂类,消费者从工厂里提取具体车

// 也叫静态工厂模式,不满足开闭原则,增加一个产品就要修改原代码
public class CarFactory {

    // 方式一:根据类型返回不同的car
    public static Car getCar(String type){
        if("五菱".equals(type)){
            return new WuLing();
        }else if("大众".equals(type)){
            return new DaZhong();
        }else {
            return null;
        }
    }

    // 方式二,拒绝臃肿的if else代码,相对于较好扩展,但也是增加一个产品需要改代码
    public static Car getWuLingCar(){
        return new WuLing();
    }
    public static Car getDaZhongCar(){
        return new DaZhong();
    }
}

4.测试类

/**
 简单工厂模式:用来生产同一等级结构中的任意产品(支持增加新产品,需要扩展已有代码)
 */
public class Zmain {

    public static void main(String[] args) {
        // 1.传统方式,需要去new每一个具体的实现类
        // 假设此类初始化需要很多额外的参数,那需要一个个传参数进去,代码不美观
        //Car car = new WuLing();
        //Car car2 = new DaZhong();

        // 2.使用工厂模式获取具体类,特点是只关心去工厂里拿,而不new具体实现
        Car car = CarFactory.getCar("五菱");
        Car car2 = CarFactory.getDaZhongCar();

        car.name();
        car2.name();
    }
}

5.运行结果

GoF23——工厂模式_第1张图片

 

结论:简单工厂模式无非就是去工厂里获取具体类,而不是直接暴露的new具体类,消费者只在车工厂里获取具体车。

但这也有一个非常突出的缺点,假设我此时扩展一个特斯拉车辆,那每次都需要去改造CarFactory车工厂里的代码,无脑补if else代码,或者再写一个获取特斯拉车的方法,不方便横向扩展,也不符合开闭原则(对扩展开放,对修改关闭)

GoF23——工厂模式_第2张图片

 

工厂方法模式

在不修改已有类的情况下,通过增加新的工厂类实现扩展

工厂方法模式是简单工厂模式的升级版本,符合开闭原则,但同样的代码维护量也更多了,核心思想是为每一个车都制造一个自己的工厂,消费者从各个工厂里提取车

1. CarFactory 类改造

/**
 * 定义一个公共factory接口,新增加一个产品去实现这个规范的工厂接口,而无需改这个接口
 */
public interface CarFactory {
    Car getCar();
}

2.每一个车都去实现公共的CarFactory类,自己搭建一个工厂类

public class WuLingFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new WuLing();
    }
}
public class DaZhongFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new DaZhong();
    }
}

此时我们扩展一个特斯拉车辆

public class Tesla implements Car{
    @Override
    public void name() {
        System.out.println("特斯拉!");
    }
}
public class TeslaFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Tesla();
    }
}

3.测试类

public class Zmain {
    public static void main(String[] args) {

        // 需要什么车,就从什么车工厂里去获取
        Car car = new WuLingFactory().getCar();
        Car car2 = new DaZhongFactory().getCar();

        car.name();
        car2.name();

        // 增加一个特斯拉车,每扩展一个产品,写一个自己的factory,而无需改原代码
        Car car3 = new TeslaFactory().getCar();
        car3.name();
    }
}

4.运行结果

GoF23——工厂模式_第3张图片

结论:工厂方法模式符合开闭原则,增加新的产品不涉及修改原已存在的代码,支持横向拓展,但是从代码、结构、编程、管理四个复杂度维度来说,简单工厂模式都是最简单明了的,工厂方法模式代码量变得臃肿,根据情况场景去选择哪种模式应用。

GoF23——工厂模式_第4张图片

 

 

你可能感兴趣的:(23种设计模式,java,spring,设计模式)