工厂模式的核心思想是:将实例的生成交给子类。
单例模式是框架核心,工厂模式更是框架核心的核心。
1. 简单工厂模式
1.1 概要介绍
该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象,其UML类图如下:
1.2、实例演示
1.2.1、IPhone定义手机-AbstractProduct
public interface IPhone {
void call();
}
1.2.2、MIPhone小米手机-product1
public class MIPhone implements IPhone {
@Override
public void call() {
System.out.println("小米打电话信号有点弱!");
}
}
1.2.3、HWPhone华为手机-product2
public class HWPhone implements IPhone {
@Override
public void call() {
System.out.println("华为手机打电话信号很棒!");
}
}
1.2.3、PhoneFactory手机代工厂-Factory
public class PhoneFactory {
public IPhone makePhone(String phoneType) {
if (phoneType.equalsIgnoreCase("MI")) {
return new MIPhone();
} else if (phoneType.equalsIgnoreCase("HW")) {
return new HWPhone();
}
return null;
}
}
1.2.4、client 测试
@Test
public void FactoryTest() {
String poneType = "HW";
PhoneFactory phoneFactory = new PhoneFactory();
IPhone phone = phoneFactory.makePhone(poneType);
phone.call();
}
2、工厂方法模式(Factory Method)
2.1、类图和概要介绍
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:
也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
接下来继续使用生产手机的例子来讲解该模式。
2.2、实例演示
2.2.1、AbstractFactory类:生产不同产品的工厂的抽象类
package com.wht.schema.factory.basic;
/**
* 抽象工厂接口,也可以是抽象类
* @author JDIT
*/
public interface AbstractFactory {
IPhone makePhone();
}
2.2.2、XiaoMiFactory类:生产小米手机的工厂(ConcreteFactory1)
/**
* 小米工厂生产小米手机
* @author JDIT
*/
public class XiaoMiFactory implements AbstractFactory {
@Override
public IPhone makePhone() {
return new MIPhone();
}
}
2.2.3、HWFactory类:生产华为手机的工厂(ConcreteFactory2)
/**
* 华为工厂生产华为手机
* @author JDIT
*/
public class HWFactory implements AbstractFactory {
@Override
public IPhone makePhone() {
return new HWPhone();
}
}
2.2.4、client测试
@Test
public void FactoryTest() {
AbstractFactory xiaoMiFactory = new XiaoMiFactory();
AbstractFactory hwFactory = new HWFactory();
HWPhone phone = (HWPhone) hwFactory.makePhone();
phone.call();
MIPhone xiaomi = (MIPhone) xiaoMiFactory.makePhone();
xiaomi.call();
}
3、抽象工厂模式(Abstract Factory)
3.1、类图和概要介绍
上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?
最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。
抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。
其UML类图如下:
从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。
接下来我们继续通过小米和苹果产品生产的例子来解释该模式。
为了弄清楚上面的结构,我们使用具体的产品和工厂来表示上面的UML类图,能更加清晰的看出模式是如何演变的:
3.2、实例演示
3.2.1、PC类:定义PC产品的接口(AbstractPC)
/**
* 定义产品PC
* @author JDIT
*/
public interface PC {
void online();
}
3.2.2、XiaomiPc类:定义XiaomiPc产品
public class XiaomiPc implements PC {
@Override
public void online() {
System.out.println("小米PC为发烧友而生,性价比体验无极限。");
}
}
3.2.3、ShenzhouPc类:定义ShenzhouPc产品
/**
* @author JDIT
*/
public class ShenzhouPc implements PC {
@Override
public void online() {
System.out.println("神州小本人手一本");
}
}
3.2.4、增加小米工厂能力
public class XiaoMiFactory implements AbstractFactory {
@Override
public IPhone makePhone() {
return new MIPhone();
}
@Override
public PC makePC() {
return new XiaomiPc();
}
}
3.2.5、华为工厂预定生产能力
public class HWFactory implements AbstractFactory {
@Override
public IPhone makePhone() {
return new HWPhone();
}
@Override
public PC makePC() {
//目前还没有生产线,来年就有了
return null;
}
}
3.2.6、client测试
@Test
public void FactoryTest() {
AbstractFactory xiaoMiFactory = new XiaoMiFactory();
AbstractFactory hwFactory = new HWFactory();
HWPhone phone = (HWPhone) hwFactory.makePhone();
phone.call();
MIPhone xiaomi = (MIPhone) xiaoMiFactory.makePhone();
xiaomi.call();
XiaomiPc xiaomiPc = (XiaomiPc)xiaoMiFactory.makePC();
xiaomiPc.online();
}
4、小结
- 工厂模式是为了解决IS-A父子继承关系的耦合问题。
- 可以满足开闭原则:对类扩展开放,对类修改关闭。
- 可以满足单一职责原则:每个类应该只有一个发生变化的原因。
- 框架肯定离不开工厂模式,这是获取多种实例的非常通用的模式,但是框架可能更多的使用反射功能甚至匿名内部类,完成对象的多态构造。