工厂模式的引入是为了管理对象的构造,对用户屏蔽构造过程,用户只从工厂拿取新对象。
简单工厂模式
用一个场景介绍简单工厂模式:某工厂想包揽所有产品生产,不仅提供很多不同类型的产品(iPhone 5,6,7...),还时不时生产新类型的产品(三星S8),而且客户不关心产品的类型细节只想使用公共方法。工厂采用如下方式:
- 根据客户要求/订单生产出不同产品
- 所有产品都由本工厂(类)唯一生产线制造出售(静态方法)
- 每增删一种新产品,就直接修改生产逻辑。
实例代码如下
abstract class Phone{
public abstract void use();
}
class iPhone extends Phone{
@Override
public void use(){System.out.print("iPhone");}
}
class S8 extends Phone{
@Override
public void use(){System.out.print("S8");}
}
class PhoneFactory{
public static Phone Manufacture(String type){
switch(type){
case "iPhone":return new iPhone();
case "S8":return new S8();
...
default: return null;
}
}
}
这就是简单工厂模式,这种策略有明显缺点:
第2条静态方法导致工厂类继承无效
第3条对正常工作的方法进行入侵式修改违反了关闭开放原则,即有可能不慎影响到其他产品对象的的构造逻辑(比如误删字符)或者判断对象类型的逻辑,导致出错。而且这对负责生产对象的方法负担过重,引起参数过于复杂等问题,不易于调用者使用。
工厂方法模式
既然一个工厂生产多种产品类型负担过重,那就开分厂吧~,每一个工厂各司其职,客户需要什么产品就从什么专用工厂取就好了。但是约定每个工厂生产出来的产品需要符合规范,故在这些分工厂之上加以继承接口/抽象类的约束。避免了简单工厂模式的缺点
abstract class Phone{
public abstract void use();
}
class iPhone extends Phone{
@Override
public void use(){System.out.print("iPhone");}
}
class S8 extends Phone{
@Override
public void use(){System.out.print("S8");}
}
abstract class PhoneFactory{
public abstract Phone Manumfacture();
}
class iPhoneFactory extends PhoneFactory{
@Override
public Phone Manumfacture() {
return new iPhone();
}
}
class S8Factory extends PhoneFactory{
@Override
public Phone Manumfacture() {
return new S8();
}
}
不过工厂方法模式也有缺点:工厂类的数量多,带来各种复杂性