工厂模式中简单工厂模式、工厂方法模式、抽象工厂模式的分析与总结

简介: 工厂模式中简单工厂模式、工厂方法模式、抽象工厂模式的分析与总结

工厂模式

工厂模式有许多变体,其中最常见的有三种
  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式
简单工厂代码分析

UML图中我们可以清晰的看到代码结构 ,首先我们创建一个Car的汽车接口,定制汽车的基本规范,汽车可以的方法是可以跑,所以我们定义了一个抽象的run方法.

  • 定义汽车接口Car
public interface Car {
     void run();
}

接着我们分别定义实现了汽车接口的不同车型

  • 宝马类BMW
public class BMW implements Car{
    @Override
    public void run() {
        System.out.println("宝马正在启动~~");
    }
}
  • 奔驰类Benz
public class Benz implements Car{
    @Override
    public void run() {
        System.out.println("奔驰正在启动~~");
    }
}
  • 比亚迪类BYD
public class BYD implements Car{
    @Override
    public void run() {
        System.out.println("比亚迪启动发现没电了~~");
    }
}
  • 接着我们创建工厂类
public class CarFactory {
    public static Car createCar(String type){
        if ("宝马".equals(type)){
            return new BMW();
        }else if ("奔驰".equals(type)){
            return new Benz();
        }else if ("比亚迪".equals(type)){
            return new BYD();
        }else{
            return null;
        }
    }
}

在上面这个工厂类中,我们通过传入的字符串equals我们要创建的车型是哪一款,匹配上的就创建并返回

  • 编写测试类进行测试
public class Main {
    public static void main(String[] args) {
        //用工厂创建一辆宝马
        Car car1 = CarFactory.createCar("宝马");
        if (car1!=null){
            car1.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆奔驰
        Car car2 = CarFactory.createCar("奔驰");
        if (car2!=null){
            car2.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆宝骏
        Car car3 =CarFactory.createCar("宝骏");
        if (car3!=null){
            car3.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
    }
}

运行结果

为什么工厂模式多种变体呢? 其实每一种变体都有优缺点,没有任何一种设计模式是完美的

对于简单工厂模式来说,他的工厂类是一般是静态的,因此可以直接用类名直接调用工厂方法,来创建实例对象

优点是实现简单,

缺点是缺点是当需要新增产品的时候,要修改工厂类的代码,不符合开闭原则.

工厂方法模式

工厂方法模式代码分析

在类图中,相比简单工厂模式,我们新增了一个工厂接口,不同的汽车厂商实现了工厂类

汽车接口和各个不同的品牌车代码同上

  • 工厂接口
public interface Factory {
    Car creatCar();
}

我们在接口中声明了一个创建汽车的抽象方法

接下来,我们编写不同的汽车实现类

  • 宝马汽车工厂类BMWFactory
public class BMWFactory implements Factory{
    @Override
    public Car creatCar() {
        return new BMW();
    }
}
  • 奔驰汽车工厂类BenzFactory
public class BenzFactory implements Factory{
    @Override
    public Car creatCar() {
        return new Benz();
    }
}
  • 比亚迪汽车工厂类BYDFactory
public class BYDFactory implements Factory{
    @Override
    public Car creatCar() {
        return new BYD();
    }
}

以上三个类它们都实现了工厂接口

接下类我们编写测试方法,来创建汽车实例,并调用汽车的方法

public class Main {
    public static void main(String[] args) {
        BMWFactory bmwFactory = new BMWFactory();
        Car BMWx5 = bmwFactory.creatCar();
        BMWx5.run();
    }
}

运行结果

工厂方法模式定义一个抽象工厂接口,该接口中声明了一个用于创建产品的工厂方法,具体的产品类由具体的工厂类来实现。工厂方法模式可以有多个具体的工厂类,每个具体工厂类负责创建一种产品。

优点是符合开闭原则,当需要新增产品时,只需要新增具体的产品类和对应的具体工厂类即可,不需要修改抽象工厂接口和抽象工厂类的代码。

缺点是增加了系统的复杂程度

抽象工厂模式

为了方便包管理,我们将包进行了分类,如下

新增了一个包Logos,在该包中定义了一个名字叫做Logos的接口

  • Logos接口
public interface Logos {
    void showLogos();
}

我们可以看到,这个接口的接口方法是用于创建车标的,接下类每一个实现它的类,都要重写这个接口方法

  • BMWLogos类 (Logos的实现类,用于创建宝马车标)
public class BMWLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是宝马");
    }
}
  • BenzLogos类 (Logos的实现类,用于创建奔驰车标)
public class BuziLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是奔驰~");
    }
}
  • BYDLogos类 (Logos的实现类,用于创建BYD车标)
public class BYDLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是 比亚迪");
    }
}

接着我们创建工厂接口

  • 工厂接口Factory
public interface Factory {
    Car createCar();
    Logos createLogos();
}

这个接口中,我们声明了两个接口方法,一个用于创建车辆,一个用于创建车标,接下来每一个实现工厂的接口都要进行重写这两个方法

  • 宝马族工厂类 BMWFamilyFactory
public class BMWFamilyFactory implements Factory {
    @Override
    public Car createCar() {
        return new BMW();
    }
    @Override
    public Logos createLogos() {
        return new BMWLogos();
    }
}
  • 奔驰族工厂类 BenzFamilyFactory
public class BenzFamilyFactory implements Factory{
    @Override
    public Car createCar() {
        return new Benz();
    }
    @Override
    public Logos createLogos() {
        return new BuziLogos();
    }
}
  • 比亚迪族工厂类 BYDFamilyFactory
public class BYDFamilyFactory implements Factory{
    @Override
    public Car createCar() {
        return new BYD();
    }
    @Override
    public Logos createLogos() {
        return new BYDLogos();
    }
}

细心的你会发现,相比于上面的工厂方法模式,这里的工厂实现类名字都会多一个Family,为什么呢?

因为抽象工厂方法模式是用来创建产品的一系列实例的,每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。

  • 测试类
public class Main {
    public static void main(String[] args) {
        //创建奔驰工厂
        Factory benzFamilyFactory = new BenzFamilyFactory();
        benzFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        benzFamilyFactory.createLogos().showLogos();
        BMWFamilyFactory bmwFamilyFactory = new BMWFamilyFactory();
        bmwFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        bmwFamilyFactory.createLogos().showLogos();//创建一辆奔驰LOGO并且显示LOGO
    }
}

运行结果

抽象工厂模式的优点在于,它能够保证创建的产品对象之间的兼容性。因为每个具体工厂类只能创建属于自己产品族的产品对象,所以不同产品族之间的产品对象不会产生冲突。此外,抽象工厂模式还支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。但是,抽象工厂模式也有一些缺点。由于抽象工厂接口需要定义一组用于创建不同产品族的方法,因此当新增加一个产品族时,需要修改抽象工厂接口及其所有实现类,这可能会导致一定的代码修改工作量。

总结

简单工厂模式:

由一个工厂类根据传入的参数决定创建哪种产品类的实例。简单工厂模式将对象的创建和使用分离开来,客户端只需要传入参数,就可以得到所需的对象,无需关心对象的创建细节。

工厂方法模式:

定义一个创建产品对象的接口,由子类决定实例化哪一个产品类。工厂方法模式将对象的创建延迟到子类中去实现,客户端只需要知道所需产品的工厂类即可,无需关心具体的产品类。

抽象工厂模式:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式可以看作是工厂方法模式的升级版,它支持创建一组相关的产品对象。抽象工厂模式能够保证创建的产品对象之间的兼容性,但是新增加一个产品族时需要修改抽象工厂接口及其所有实现类。

简单工厂模式:

优点:

  1. 工厂类中包含了必要的逻辑判断,可以根据客户端的请求动态地创建相关的产品对象,客户端无需知道具体的产品类。
  2. 简单工厂模式将对象的创建和使用分离开来,客户端只需要关心所需产品的参数,无需关心对象的创建细节。

缺点:

  1. 简单工厂模式工厂类职责过重,增加新的产品需要修改工厂类的判断逻辑,违背了开闭原则。
  2. 简单工厂模式只支持一种产品族的创建,不支持扩展。

工厂方法模式:

优点:

  1. 工厂方法模式将对象的创建延迟到子类中去实现,符合开闭原则,新增加产品时只需要添加对应的工厂类即可。
  2. 工厂方法模式支持扩展,可以创建多个产品族的对象。

缺点:

  1. 工厂方法模式需要新增加相应的工厂类,增加了代码的复杂度。
  2. 工厂方法模式增加了系统的抽象性和理解难度。

抽象工厂模式:

优点:

  1. 抽象工厂模式能够保证创建的产品对象之间的兼容性,因为每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。
  2. 抽象工厂模式支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。

缺点:

  1. 抽象工厂模式需要新增加相应的接口及实现类,增加了代码的复杂度。
    单工厂模式只支持一种产品族的创建,不支持扩展。

工厂方法模式:

优点:

  1. 工厂方法模式将对象的创建延迟到子类中去实现,符合开闭原则,新增加产品时只需要添加对应的工厂类即可。
  2. 工厂方法模式支持扩展,可以创建多个产品族的对象。

缺点:

  1. 工厂方法模式需要新增加相应的工厂类,增加了代码的复杂度。
  2. 工厂方法模式增加了系统的抽象性和理解难度。

抽象工厂模式:

优点:

  1. 抽象工厂模式能够保证创建的产品对象之间的兼容性,因为每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。
  2. 抽象工厂模式支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。

缺点:

  1. 抽象工厂模式需要新增加相应的接口及实现类,增加了代码的复杂度。
  2. 抽象工厂模式增加了系统的抽象性和理解难度。
相关文章
|
6月前
|
Java
简单工厂模式
简单工厂模式
39 0
|
6月前
|
Java API 数据库
工厂方法模式
工厂方法模式
37 0
|
设计模式 C++
2023-6-10-第一式工厂方法模式
2023-6-10-第一式工厂方法模式
81 0
|
编译器
简单工厂模式~
简单工厂模式~
|
前端开发
简单工厂模式
简单工厂模式
81 0
|
设计模式 监控 uml
剖析工厂方法模式、从开电脑店开始
工厂类负责把实例化类时,复杂的过程透明化,同时避免大量实例化类的重复代码的出现。
剖析工厂方法模式、从开电脑店开始
|
设计模式 算法 搜索推荐
工厂方法模式的两个极端
概念:是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。
|
设计模式
工厂方法模式详细介绍
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种将对象的创建逻辑封装在工厂类中的方式,使得客户端代码无需直接依赖具体的类来创建对象。
101 0