书接上回,本篇讲一下创建型模式-工厂方法设计模式
上一篇简单工厂设计模式,设计上存在一定瑕疵:当增加新的华为平板商品时需要修改HWProductFactory类,违背了开闭原则,不好。本篇讲的就是如何优雅解决掉这个小瑕疵。
最佳实践:工厂方法设计模式
定义:通过让子类决定该创建对象是什么,来达到将对象创建过程封装的目的。
需求:华为工厂创建华为手机/华为电脑/华为平板,要求:不能违背开闭原则
注意:UML图是最终代码图,已经加上华为平板了
产品:
//华为商品
public abstract class HWProduct {
public abstract void show();
}
//华为手机
public class HWPhoneProduct extends HWProduct {
@Override
public void show() {
System.out.println("HWPhone被创建了.....");
}
}
//华为电脑
public class HWComputerProduct extends HWProduct {
@Override
public void show() {
System.out.println("HWComputer被创建了.....");
}
}
工厂:
因为需要让工厂类符合开闭原则,这里改进:
抽象出一个父工厂,负责生产规则的定制
分离出2个产品子工厂:
1>HWPhoneFactory 负责华为手机的生产
2>HWComputerFactory负责华为电脑的生产
//华为工厂
public abstract class HWProductFactory {
//父类定规则,具体创建过程由子类实现
public abstract HWProduct produce();
}
//华为手机工厂
public class HWPhoneFactory extends HWProductFactory{
@Override
public HWProduct produce() {
return new HWPhoneProduct();
}
}
//华为电脑工厂
public class HWComputerFactory extends HWProductFactory{
@Override
public HWProduct produce() {
return new HWComputerProduct();
}
}
测试:
public class App {
public static void main(String[] args) {
//电脑工厂
HWProductFactory factory = new HWComputerFactory();
//创建出电脑
HWProduct computer = factory.produce();
computer.show();
//手机工厂
factory = new HWPhoneFactory();
//创建出手机
HWProduct phone = factory.produce();
phone.show();
//平板工厂--后续补充平板类与工厂类即可
//factory = new HWTabletFactory();
//创建出平板
//HWProduct tablet = factory.produce();
//tablet.show();
}
}
分析:
当出现新的产品:HWTabletProduct 时,此时并不需要修改任何工厂类,只需要新加一个HWTabletFactory工厂了即可,这满足开闭原则要求:对扩展开放,对修改关闭
//华为平板
public class HWTabletProduct extends HWProduct {
@Override
public void show() {
System.out.println("HWTablet被创建了.....");
}
}
//华为平板工厂
public class HWTabletFactory extends HWProductFactory{
@Override
public HWProduct produce() {
return new HWTabletProduct();
}
}
一般好的代码结构设计都建议使用工厂方法设计模式以适应需求变动造成原先代码结构改变。尽量做到增加新功能,只增加新类,不修改旧代码。
1>创建对象(产品)需要大量重复的代码
2>客户端(应用层)关心对象创建结果,不关心创建对象过程
3>一个类通过其子类来指定创建哪个对象
这个模式使用需要结合里氏替换原则使用, 子类替换父类使用,程序不改原先逻辑。
优点:
1>客户端只需要关心所需产品对应的工厂,无须关心产品具体创建细节
2>加入新产品符合开闭原则,提高可拓展性
缺点:
1>如果过度设计,类的个数容易膨胀,增加系统复杂度
2>增加了系统的抽象性和理解难度
工厂方法设计模式也可以在JDK中找例子-集合中的ListIterator
工厂体系:
Collection--AbstractCollection-AbstractList-ArrayList
Collection--AbstractCollection-AbstractList-LinkedList
产品体系:
ListIterator--ArrayList$ListItr
ListIterator--LinkedList$ListItr
ArrayList 跟LinkedList就是具体的工厂, 规范遵循AbstractList, 每个list中都有自己独有的迭代器类
ArrayList$ListItr, LinkedList$ListItr可以理解为不同工厂,生成不同的产品。而产品都遵循共同的规范:ListIterator
完整的体系:
1>工厂方法设计模式本质是选择实现,选择不同工厂类创建对象
2>工厂方法设计模式将对象实例创建实现延迟到子类或者接口实现类。
2>工厂方法模式基础理论是开闭原则,设计时必须遵守