工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。
场景:假设我们的业务代码当中,有一个被广泛引用的“手机类”,这个类实例需要在许多地方被创建和初始化,而初始化的代码也比较复杂,那么我们就可以通过工厂模式来创建这个手机对象。
1、简单工厂模式
该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象,其UML类图如下:
针对上述场景情况,我们可以构建一个工厂专门提供创建对象方法的接口,相关子类分别实现这个接口
Phone:手机标准规范类(AbstractProduct)
public interface Phone {
//生产手机
void createPhone();
}
MiPhone:生产小米手机类(Product)
public class MiPhone implements Phone{
public MiPhone() {
this.createPhone();
}
@Override
public void createPhone() {
System.out.println("生产小米手机");
}
}
IPhone:生产苹果手机类(Product)
public class IPhone implements Phone{
public IPhone() {
this.createPhone();
}
@Override
public void createPhone() {
System.out.println("生产苹果手机");
}
}
那么工厂该如何创建这两种类型的对象呢?很简单,在创建方法中传入参数,根据参数来做条件判断,决定创建什么样的对象:
PhoneFactory:手机工厂(Factory)
public class PhoneFactory {
public Phone makePhone(String type) {
Phone phone = null;
if ("MiPhone".equals(type)){
phone = new MiPhone();
}
else if ("IPhone".equals(type)){
phone = new IPhone();
}
return phone;
}
}
演示:
public class Test {
public static void main(String[] args) {
PhoneFactory factory = new PhoneFactory();
factory.makePhone("MiPhone");
factory.makePhone("IPhone");
}
}
2、工厂方法模式
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:
也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
AbstractFactory:生产不同产品的工厂抽象类(AbstractFactory)
public interface AbstractFactory {
Phone makePhone();
}
MiPhoneFactory:生产小米手机工厂(ConcreteFactory)
public class MiPhoneFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
}
IPhoneFactory:生产苹果手机工厂(ConcreteFactory)
public class IPhoneFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
}
演示:
public class Test {
public static void main(String[] args) {
MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
miPhoneFactory.makePhone();
IPhoneFactory iPhoneFactory = new IPhoneFactory();
iPhoneFactory.makePhone();
}
}
3、抽象工厂模式
上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。
抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。其UML类图如下:
PC:PC标准规范类(AbstractProduct)
public interface PC {
void createPC();
}
MiPC:生产小米电脑类(Product)
public class MiPC implements PC {
public MiPC() {
this.createPC();
}
@Override
public void createPC() {
System.out.println("生产小米电脑");
}
}
Mac:生产苹果电脑类(Product)
public class Mac implements PC {
public Mac() {
this.createPC();
}
@Override
public void createPC() {
System.out.println("生产苹果电脑");
}
}
下面需要修改工厂相关的类的定义:
AbstractFactory:增加PC生产方法
public interface AbstractFactory {
Phone makePhone();
PC makePC();
}
MiPhoneFactory:增加小米电脑生产方法实现
public class MiPhoneFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
@Override
public PC makePC() {
return new MiPC();
}
}
IPhoneFactory:增加苹果电脑生产方法实现
public class IPhoneFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
@Override
public PC makePC() {
return new Mac();
}
}
演示:
public static void main(String[] args) {
MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
miPhoneFactory.makePhone();
miPhoneFactory.makePC();
IPhoneFactory iPhoneFactory = new IPhoneFactory();
iPhoneFactory.makePhone();
iPhoneFactory.makePC();
}