工厂模式简介
在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。
如果有许多地方都需要生成A的对象,那么你需要写很多A a=new A()。如果需要修改的话,你要修改许多地方。
但是如果用工厂模式,你只需要修改工厂代码。其他地方引用工厂,可以做到只修改一个地方,其他代码都不动,就是解耦了。
- 还没有工厂时代
假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
工厂模式分类
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:
工厂方法模式(Factory Method)与抽象工厂 模式(Abstract Factory)。
将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
简单工厂模式
后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马,想要什么车,这个工厂就可以建。比如想要宝马520i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
UML 类图
简单工厂组成
工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。
抽象产品以及具体产品
- BMW.java
/**
* 抽象的产品BMW
* @author LingDu
*/
public interface BMW {
}
- BMW520i.java , BMWi8.java
public class BMW520i implements BMW {
public BMW520i() {
System.out.println("BMW 520i系列");
}
}
public class BMWi8 implements BMW {
public BMWi8() {
System.out.println("BMW i8 系列");
}
}
创建工厂类
- Factory.java
public class Factory {
public BMW create(String type){
if(type.equalsIgnoreCase("520i")){
return new BMW520i();
}
if(type.equalsIgnoreCase("i8")){
return new BMWi8();
}
return null;
}
}
创建测试类(客户)
- Customer.java
Factory factory = new Factory();
factory.create("520i");
factory.create("i8");
每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(create(String type)方法需要新增if),这显然是违背开闭原则的。
工厂方法模式
为了满足客户,宝马车系列越来越多,如520i,i8 等系列,一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。
UML 类图
工厂方法模式组成
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必 须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的 具体产品的对象。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象 类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的 类来实现。
抽象产品以及具体产品
- BMW.java
/**
* 抽象的产品BMW
* @author LingDu
*/
public interface BMW {
}
- BMW520i.java , BMWi8.java
public class BMW520i implements BMW {
public BMW520i() {
System.out.println("BMW 520i系列");
}
}
public class BMWi8 implements BMW {
public BMWi8() {
System.out.println("BMW i8 系列");
}
}
创建抽象工厂以及具体工厂
- FactoryBMW .java
/**
* 抽象的工厂
* @author LingDu
*/
interface FactoryBMW {
BMW createBMW();
}
- FactoryBMW520i.java,FactoryBMWi8.java
public class FactoryBMW520i implements FactoryBMW {
@Override
public BMW createBMW() {
return new BMW520i();
}
}
public class FactoryBMWi8 implements FactoryBMW {
@Override
public BMW createBMW() {
return new BMWi8();
}
}
创建测试类(客户)
- Customer.java
FactoryBMW520i factoryBMW520i = new FactoryBMW520i();
factoryBMW520i.createBMW();
FactoryBMWi8 factoryBMWi8 = new FactoryBMWi8();
factoryBMWi8.createBMW();
工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。
抽象工厂模式
随着客户的要求越来越高,宝马车需要不同配置的空调等配件。于是这个工厂开始生产空调等配件,宝马520i系列配置Air520i型号空调,宝马i8系列配置Airi8型号空调
UML 类图
抽象产品以及具体产品
宝马车的抽象产品以及具体型号
- BMW.java
/**
* 抽象的产品BMW
* @author LingDu
*/
public interface BMW {
}
- BMW520i.java,BMWi8.java
public class BMW520i implements BMW {
public BMW520i() {
System.out.println("BMW 520i系列");
}
}
public class BMWi8 implements BMW {
public BMWi8() {
System.out.println("BMW i8 系列");
}
}
空调的抽象产品以及具体型号
- AirCondition.java
/**
* 抽象的空调
* @author LingDu
* */
public interface AirCondition {
}
- Air520i.java,Airi8.java
public class Air520i implements AirCondition {
public Air520i() {
System.out.println("520i 系列空调");
}
}
public class Airi8 implements AirCondition {
public Airi8() {
System.out.println("i8 系列空调");
}
}
创建抽象工厂以及具体工厂
- FactoryBMW .java
/**
* 抽象工厂
* @author LingDu
*/
public interface FactoryBMW {
public BMW createBMW();
public AirCondition createAir();
}
- FactoryBMW520i.java,FactoryBMWi8.java
public class FactoryBMW520i implements FactoryBMW {
@Override
public BMW createBMW() {
return new BMW520i();
}
@Override
public AirCondition createAir() {
return new Air520i();
}
}
public class FactoryBMWi8 implements FactoryBMW {
@Override
public BMW createBMW() {
return new BMWi8();
}
@Override
public AirCondition createAir() {
return new Airi8();
}
}
创建测试类(客户)
- Customer.java
//生产宝马520i系列车以及配件
FactoryBMW520i factoryBMW520i = new FactoryBMW520i();
factoryBMW520i.createBMW();
factoryBMW520i.createAir();
//生产宝马i8系列车已经配件
FactoryBMWi8 factoryBMWi8 = new FactoryBMWi8();
factoryBMWi8.createBMW();
factoryBMWi8.createAir();
工厂方法模式与抽象工厂模式的区别
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
两者区别
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。两者皆可。