1. 模式名称及概念
软件系统经常不断变化,而且不稳定。我们必须考虑对象和关系的松耦合。松耦合是软件设计时一个非常重要的特性,可以帮助系统不做或者做很少的变更就能扩展新功能。
工厂顾名思义就是创建产品。
根据产品时具体产品还是具体工厂可以分为简单工厂模式和工厂方法模式。
根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。
该模式用于封装和管理对象的创建,是一种创建型模式。
工厂设计模式属于创造型设计模式,工厂设计模式分为简单工厂、工厂方法和抽象工厂设计模式。
- 简单工厂设计模式:简单工厂并不是严格意义上的设计模式。它更多的是一种用于封装对象实例化过程的编程技术。
- 工厂方法设计模式:定义了一个创建对象的接口,决定哪个类实例化,工厂方法允许将类的实例化延迟到子类。
- 抽象工厂设计模式:提供一个接口,用于创建相关或依赖对象,而无需指定它们。
2. 工厂模式的好处
- 客户端不需要知道它创建的每一个子类。仅仅需要一个抽象类接口或者接口的引用和工厂对象。
- 工厂封装了对象的创建。当创建过程非常复杂的时候,这是非常有用的。
- 工厂模式增强了可扩展性。
3.简单工厂模式
该模式对对象创建管理的方式最为简单,因为这个工厂就仅仅只封装了生产两个product的方法。
下面使用手机生产来讲解该模式:
- Phone.java :手机标准规范类(AbstractProduct)
public interface Phone {
void make();
}
- MiPhone.java:制造小米手机(Product1)
public class MiPhone implements Phone {
public MiPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi phone!");
}
}
- IPhone.java:制造苹果手机(Product2)
public class IPhone implements Phone {
public IPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make iphone!");
}
}
- PhoneFactory.java:手机代工厂(Factory)
public class PhoneFactory {
public Phone makePhone(String phoneType) {
if(phoneType.equalsIgnoreCase("MiPhone")){
return new MiPhone();
}
else if(phoneType.equalsIgnoreCase("iPhone")) {
return new IPhone();
}
return null;
}
}
- 演示:
public class Demo {
public static void main(String[] arg) {
PhoneFactory factory = new PhoneFactory();
Phone miPhone = factory.makePhone("MiPhone"); // make xiaomi phone!
IPhone iPhone = (IPhone)factory.makePhone("iPhone"); // make iphone!
}
}
简单工厂模式例子UML类图如下:
4. 工厂方法模式
与工厂方法模式中,工厂负责生产所有产品相比,
工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:
即定义一个抽象抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
接下来继续使用生产手机的例子来讲解该模式。
其中和产品相关的Phone类,MiPhone类和IPhone类的定义不变。
- AbstractFactory.java:生产不同产品的工厂的抽象类(AbstractFactory)
public interface AbstractFactory {
Phone makePhone();
}
- XiaoMiFactory.java:生产小米手机的工厂(ConcreteFactory1)
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
}
- AppleFactory.java:生产苹果手机的工厂(ConcreteFactory2)
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
}
- 演示
public class Demo {
public static void main(String[] arg) {
AbstractFactory miFactory = new XiaoMiFactory();
AbstractFactory appleFactory = new AppleFactory();
miFactory.makePhone(); // make xiaomi phone!
appleFactory.makePhone(); // make iphone!
}
}
5.抽象工厂模式
上述两种模式不管工厂怎么拆分抽象,都只能针对一类产品Phone(AbstractProduct),如果要生成另一种PC,应该怎么表示?
抽象工厂模式通过在AbstractFactory
中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生成该类产品。否则继承这个接口可以什么也不干。
其UML类图如下:
从上面的类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加。
接下来我们继续通过小米和苹果生产的例子来解释该模式。
- PC类:定义PC产品的接口(AbstractPC)
public interface PC {
void make();
}
- MIPC类:定义小米电脑产品(MIPC)
public class MiPC implements PC {
public MiPC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi PC!");
}
}
- MAC类:定义苹果电脑产品(MAC)
public class MAC implements PC {
public MAC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make MAC!");
}
}
下面定义需要修改工厂相关的类的定义:
- AbstractFactory类:增加PC产品制造接口
public interface AbstractFactory {
Phone makePhone();
PC makePC();
}
- XiaoMiFactory类:增加小米PC的制造(ConcreteFactory1)
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
@Override
public PC makePC() {
return new MiPC();
}
}
- AppleFactory类:增加苹果的PC的制造(ConcreteFactory2)
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
@Override
public PC makePC() {
return new MAC();
}
}
- 演示
public class Demo {
public static void main(String[] arg) {
AbstractFactory miFactory = new XiaoMiFactory();
AbstractFactory appleFactory = new AppleFactory();
miFactory.makePhone(); // make xiaomi phone!
miFactory.makePC(); // make xiaomi PC!
appleFactory.makePhone(); // make iphone!
appleFactory.makePC(); // make MAC!
}
}
上述案例的UML类图如下所示:
6.简单工厂和抽象工厂的比较
- 简单工厂编程简单,但是扩展性差,新增加产品时,需要改动原有生产代码。
- 抽象工厂是在简单工厂之上又构建了一层工厂,扩展性比简单工厂模式好,一般性新增业务时只需要新增具体工厂实现即可。