设计模式-三种工厂模式

工厂模式包括:

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

将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提升项目的扩展和维护性。工厂模式都是实现建立者和调用者分离,下面开始逐一介绍:程序员

  • 简单工厂模式

模式UML类图

角色分析

  • Factory:工厂角色
  • Product:抽象产品角色
  • ConcreteProduct:具体产品角色
工厂角色(Creator) 是简单工厂模式的核心,它负责实现建立全部具体产品类的实例。工厂类能够被外界直接调用,建立所需的产品对象。
抽象产品角色(Product) 是全部具体产品角色的父类,它负责描述全部实例所共有的公共接 口 。
具体产品角色(Concrete Product) 继承自抽象产品角色,通常为多个,是简单工厂模式的建立目标。工厂类返回的都是该角色的某一具体产品。

示例程序:经过汽车工厂生产汽车(奔驰和奥迪两种车型),消费者(客户端)只须要与汽车工厂联系(依赖)

示意图

代码实现

package Factory;
interface Car{
    void run();
}
class Aodi implements Car{
    @Override
    public void run() {
        System.out.println("我是奥迪汽车...");
    }
}
class Benchi implements Car{
    @Override
    public void run() {
        System.out.println("我是奔驰汽车...");
    }
}
class CarFactory{
    static public Car createCar(String name) {
        Car car = null;
        if(name.equals("奥迪")) {
            car = new Aodi();
        }else if(name.equals("奔驰")) {
            car = new Benchi();
        }
        return car;
    }
}
/**
 * @author Moti
 * @Time 2019年9月21日
 */
public class Main {
    public static void main(String[] args) {
        Car car = CarFactory.createCar("奔驰");
        car.run();
    }
}

分析简单工厂模式的优缺点

  • 优势

工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该建立哪一个具体类的对象.经过使用工厂类,外界能够从直接建立具体产品对象的尴尬局面摆脱出来,仅仅须要负责“消费”对象就能够了。而没必要管这些对象究竟如何建立及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。ide

  • 缺点

因为工厂类集中了全部实例的建立逻辑,违反了高内聚责任分配原则,将所有建立逻辑集中到了一个工厂类中;它所能建立的类只能是事先考虑到的,若是须要添加新的类,则就须要改变工厂类了。违反开闭原则 。性能

当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不一样条件建立不一样实例的需求.这种对条件的判断和对具体产品类型的判断交错在一块儿,很难避免模块功能的蔓延,对系统的维护和扩展很是不利;优化

这些缺点在工厂方法模式中获得了必定的克服。this

  • 工厂方法模式

模式UML类图

每个产品都有本身独立的工厂设计

角色分析

  • 抽象产品(Product)
  • 具体产品(Concrete Product)
  • 抽象工厂(Factory)
  • 具体工厂(Concrete Factory)
抽象产品(Product) 具体产品的父类
描述具体产品的公共接口
具体产品(Concrete Product) 抽象产品的子类;工厂类建立的目标类
描述生产的具体产品
抽象工厂(Factory) 具体工厂的父类
描述具体工厂的公共接口
具体工厂(Concrete Factory) 抽象工厂的子类;被外界调用描述具体工厂;实现FactoryMethod工厂方法建立产品的实例

示例程序:经过奥迪汽车工厂或者奔驰汽车工厂生产汽车,消费者(客户端)只须要与汽车工厂联系(依赖)

示意图

实例程序UML类图

代码实现

1. 汽车的抽象类3d

package AbstractFactory;
/**
 * 定义汽车的抽象类
 * @author Moti
 * @Time 2019年9月27日 下午3:04:23
 */
public abstract class Car {
    public abstract void run();
}

2. 奥迪汽车类code

package AbstractFactory;
/**
 * 定义奥迪车,继承抽象类Car实现run方法
 * @author Moti
 * @Time 2019年9月27日 下午3:06:10
 */
public class Aodi extends Car {
    @Override
    public void run() {
        System.out.println("我是奥迪车..滴滴滴..");
    }
}

3. 奔驰汽车类对象

package AbstractFactory;
/**
 * 定义奔驰车,继承抽象类Car实现run方法
 * @author Moti
 * @Time 2019年9月27日 下午3:07:29
 */
public class Benchi extends Car {
    @Override
    public void run() {
        System.out.println("我是奔驰车..滴滴滴..");
    }
}

4. 抽象汽车工厂的接口blog

package AbstractFactory;
/**
 * 汽车工厂的接口,将具体实例的生成交给子类
 * @author Moti
 * @Time 2019年9月27日 下午3:08:35
 */
public interface CarFactory {
    Car createCar();
}

5. 奥迪汽车工厂的类,实现了抽象汽车工厂接口

package AbstractFactory;
/**
 * 定义奥迪车的工厂
 * @author Moti
 * @Time 2019年9月27日 下午3:09:53
 */
public class AodiCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Aodi();
    }
}

6. 奔驰汽车工厂的类,实现了抽象汽车工厂接口

package AbstractFactory;
/**
 * 定义奔驰车的工厂
 * @author Moti
 * @Time 2019年9月27日 下午3:10:57
 */
public class BenchiCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benchi();
    }
}

7. 客户端调用

package AbstractFactory;
/**
 * @author Moti
 * @Time 2019年9月27日 下午3:12:45
 */
public class Client {
    public static void main(String[] args) {
        CarFactory carFactory1 = new AodiCarFactory();
        CarFactory carFactory2 = new BenchiCarFactory();
        Car car1 = carFactory1.createCar();
        Car car2 = carFactory2.createCar();
        car1.run();
        car2.run();
    }
}

分析工厂方法模式的优缺点

  • 优势

用户只须要关心所需产品对应的工厂,无需关心建立细节,甚至无需知道具体产品类名;全部的具体工厂类都具备同一抽象父类;符合开闭原则,新增产品只须要添加工厂类和具体产品,无需修改代码,扩展性好;

  • 缺点

添加一个新的产品,系统中类的个数增长,致使增长了系统的复杂性,有更多的类须要编译和运行,会增长系统性能的开销;因为考虑到系统的可扩展性,须要引入抽象层,在客户端代码中均使用抽象层进行定义,增长了系统的抽象性和理解难度;

  • 抽象工厂模式

前言

  1. 抽象工厂模式:定义了一个interface用于建立相关或有依赖关系的对象簇,而无需指明具体的类
  2. 抽象工厂模式能够将简单工厂模式和工厂方法模式进行整合。
  3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
  4. 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员能够根据建立对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

产品等级:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不一样产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。

模式UML类图

这里,1号工厂(ConcreteFactory1)能够生产A,B,C三种产品(ConcreteProductA,B,C)
一样,2号工厂也能够生产A,B,C三种产品

那么1号工厂生产的这三种产品构成一个产品族,2号工厂生产的这三种产品也构成一个产品族.

1号工厂生产的A产品和2号工厂生产的A产品构成一个产品等级
1号工厂生产的B产品和2号工厂生产的B产品 构成一个产品等级
1号工厂生产的C产品和2号工厂生产的C产品 构成一个产品等级

角色分析

  • 抽象产品(Product)
  • 具体产品(Concrete Product)
  • 抽象工厂(Factory)
  • 具体工厂(Concrete Factory)
抽象产品(Product) 具体产品的父类
描述具体产品的公共接口
具体产品(Concrete Product) 抽象产品的子类;工厂类建立的目标类
描述生产的具体产品
抽象工厂(Factory) 具体工厂的父类
描述具体工厂的公共接口
具体工厂(Concrete Factory) 抽象工厂的子类;被外界调用描述具体工厂;实现抽象工厂中建立产品的实例

示例程序:得到三种电子元件(RAM,CPU,Mouse),有日本工厂和中国工厂,这两个工厂均可以生产这三种电子元件

注意:这里日本工厂生产的全部产品构成一个产品族,中国工厂生产的全部产品也构成一个产品族,共两个产品族.示例程序中出现了两种RAM,两种CPU,两种Mouse(分别来自中国工厂和日本工厂),这些同种商品分类构成一个产品等级,也就是说有三个产品等级.

示例程序UML类图

代码实现

1.抽象产品和具体产品

//设备接口(产品的抽象)
public interface Device {
    String getDeviceName();
}
//RAM(具体的产品)
public class RAM implements Device {
    private String factoryName;
    public RAM(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生产的RAM";
    }
}
//CPU(具体的产品)
public class CPU implements Device {
    private String factoryName;
    public CPU(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生产的CPU";
    }
}
//Mouse(具体的产品)
public class Mouse implements Device {
    private String factoryName;
    public Mouse(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生产的Mouse";
    }
}

2.抽象工厂和具体工厂

//抽象工厂
public interface DeviceFactory {
    Device createCPU();
    Device createARM();
    Device createMouse();
}
//具体工厂
public class ChinaFactoy implements DeviceFactory {
    @Override
    public Device createCPU() {
        return new CPU("中国");
    }
    @Override
    public Device createARM() {
        return new RAM("中国");
    }
    @Override
    public Device createMouse() {
        return new Mouse("中国");
    }
}
//具体工厂
public class JapanFactory implements DeviceFactory{
    @Override
    public Device createCPU() {
        return new CPU("日本");
    }
    @Override
    public Device createARM() {
        return new RAM("日本");
    }
    @Override
    public Device createMouse() {
        return new Mouse("日本");
    }
}

3.客户端Client

public class Client {
    public static void main(String[] args) {
        DeviceFactory factory = new JapanFactory();
        Device device = factory.createMouse();
        String string = device.getDeviceName();
        System.out.println(string);
    }
}

分析抽象工厂模式的优缺点

  • 优势

分离了具体的类。客户经过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出如今客户代码中。

易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂便可使用不一样的产品配置。

有利于产品的一致性。当一个系列的产品对象被设计成一块儿工做时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。 

  • 缺点

难以支持新种类的产品。由于抽象工厂接口肯定了能够被建立的产品集合(产品族),因此难以扩展抽象工厂以生产新种类的产品。

相关文章
相关标签/搜索