欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【23种设计模式】工厂模式

程序员文章站 2022-06-04 23:16:13
...
  • 这是一篇以代码为主的博客,没有那么多的定义和概念,希望能通过代码讲解来帮助你理解工厂模式

工厂模式对OOP的七大原则的体现

  • 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
  • 依赖倒转原则:要针对接口变成,不要针对实现编程
  • 迪米特原则:只与你直接的朋友通信,而避免和陌生人通信

工厂模式的作用

  • 核心思想:实现了创建者和调用者的分离
  • 核心本质:
    • 实例化对象不使用new,用工厂方法代替
    • 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
  • 工厂模式分为三种:
    • 简单工厂模式:用来生产统一等级结构中的任意产品(对于增加新的产品,需要修改已有代码)
    • 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
    • 抽象工厂模式围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂

【 注意 】产品结构和产品族的定义产品族内的产品是由同一个工厂生产出来的;产品结构指的是产品所处的类别。举个例子,小米生产小米手机和小米路由器,华为生产华为手机和华为路由器,那么小米路由器和华为路由器就处于同一个产品结构等级;小米手机和小米路由器就处于同一个产品族,同理,华为手机和华为路由器也是处于同一个产品族。

简单工厂模式

Car对象

public interface Car {
    /**
     * car name
     */
    public void name();
}
-------------------------------------
public class Tesla implements Car{
    @Override
    public void name() {
        System.out.println("特斯拉");
    }
}
-------------------------------------
public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("五菱宏光");
    }
}

Consumer对象

package simple;

public class Consumer {
    public static void main(String[] args) {
        // 这是原来s获取car对象的样子
        // 需要了解接口以及所有的实现类,如果你不知道这些就无法编码
        // 面向对象编码就只需要你知道这是一个Car就够了,里面有什么不需要管
        // 映射到现实生活中就是如果要买车,直接去买工厂已经做好的车就行了,不需要自己造一台车
        // 但是这里却要自己new一个
        Car car1 = new WuLing();
        Car car2 = new Tesla();

        car1.name();
        car2.name();
    }
}

CarFactory对象

  • 使用简单工厂模式改造代码
package simple;

/**
 * 简单工厂模式,也称静态工厂模式
 * 里面的方法都是静态的,根据接收的不同的参数返回不同的对象实例
 * 弊端:如果要增加一个产品,必须要修改代码
 * 但是大部分情况下都是使用这个模式
 * @author Hey
 */
public class CarFactory {
    // 方法一:根据传入的参数判断需要的是什么然后就返回什么
    public static Car getCar(String car){
        if(car.equals("五菱")){
            return new WuLing();
        }else if(car.equals("特斯拉")){
            return new Tesla();
        }else{
            return null;
        }
    }
    // 方法二:根据自己的需要自己取得相应的车
    public static Car getWuLing(){
        return new WuLing();
    }
    public static Car getTesla(){
        return new WuLing();
    }
}

使用工厂方法之后的Consumer对象

package simple;

public class Consumer {
    public static void main(String[] args) {
        // 使用工厂创建的方式
        // 就可以直接通过工厂获取,而不是自己创建
        // 假设我们自己new一个Car需要要传入很多的参数
        // 那么通过Car工厂的方式,我们就不需要再传入那么多的参数,直接在工厂里面配置即可
        Car car3 = CarFactory.getCar("五菱");
        //添加car3非空的断言
        assert car3 != null;
        car3.name();
        // 但是这样做会导致使用不灵活
        // 假设我们要新增一个车,那么我们就得更改车工厂里面的代码
        // 这就违背了开闭原则
    }
}

简单工厂模式小结

  • 最开始的时候,我们在使用一个类的时候,我们需要自己去new一个类,需要去管实现的细节
  • 有了简单工厂模式之后,我们只需要面对工厂,工厂里面的细节怎么实现的就不需要管了

工厂方法模式

  • 简单工厂模式从设计原则上来看违背了开闭原则,如果要解决这个问题,我们可以直接建一个工厂的接口,然后通过实现工厂的接口来创建不同类型的工厂,这样我们就可以通过具体的工厂获取需要的实例对象

CarFactory接口

package method;

public interface CarFactory{
    /**
     * @return car
     */
    Car getCar();
}

实现CarFactory接口

// WuLingFactory 
public class WuLingFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new WuLing();
    }
}
-----------------------------------------------------
// TeslaFactory 
public class TeslaFactory implements CarFactory {
    @Override
    public Car getCar() {
        return new Tesla();
    }
}
-----------------------------------------------------
// 如果我们要增加一个车,可以直接通过创建一个新的Factory来实现
// MoBaiFactory 
public class MoBaiFactory implements CarFactory {
    @Override
    public Car getCar() {
        return new MoBai();
    }
}

Consumer对象

public class Consumer {
    public static void main(String[] args) {
        Car car = new WuLingFactory().getCar();
        Car car1 = new TeslaFactory().getCar();
        // 此时当我们再需要拿到车时,就直接去到对应的工厂获取即可
        car.name();
        car1.name();

        // 这个时候增加一个车
        // 此时发现 扩展的时候并没有对原来的类进行修改,满足了开闭原则,但是也多了很多的类
        // 这样每增加一个车,就会多一个工厂类,会越来越庞大
        Car car2 = new MoBaiFactory().getCar();
        car2.name();
    }
}

简单工厂模式与工厂方法模式比较

工厂方法模式更符合设计原则,但是在实际应用的时候,会显得较为复杂,代码量也较大

  • 结构复杂度来看:两者比较,简单工厂模式更好
  • 代码复杂度来看:两者比较,简单工厂模式更好
  • 编程复杂度来看:两者比较,简单工厂模式更好
  • 管理复杂度来看:两者比较,简单工厂模式统一管理工厂的实现,会更好
  • 根据设计原则,两者比较,工厂方法模式更优
  • 根据实际业务,选择简单工厂模式的会更多

抽象工厂模式

详情请查看另一篇博客

小结

  • 简单工厂模式(静态工厂模式):虽然某种程度上不符合设计原则,但是实际使用确实最多的
  • 工厂方法模式:不修改已有类的前提下,通过新增新的工厂类来实现扩展
  • 抽象工厂模式:不可以增加产品,但是可以增加产品族!

应用场景

  • JDK中CalendargetInstance()方法
  • JDBC中的Connection对象的获取
  • Spring中IOC容器创建管理bean对象
  • 反射中Class对象的newInstance()方法
相关标签: 23种设计模式