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

工厂模式

工厂模式有许多变体,其中最常见的有三种

  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. 抽象工厂模式增加了系统的抽象性和理解难度。

猜你喜欢

转载自blog.csdn.net/yvge669/article/details/130676295
今日推荐