工厂模式
代码编写出来是为了给别人 (client) 调用的:
- 调用者 (client) 跟代码编写者 (provider),可能是同一个人,也可能是不同的人
- 提供给调用者的代码,有可能是源码可见的,也可能是源码不可见、不可修改的(比如 jar 包)
所以,为了简化代码的协作使用及管理维护,必须想尽办法简化代码逻辑,实现必要的分离。
1 最原始的方式
比如说,有一系列的代码,是用来创建不同品牌的手机。代码是这样的:
public class iPhone { public void getPhoneInfo() { System.out.println("我是iPhone"); } }
如果这样的代码提供给客户端调用,那么提供者必须要将所有类的名称以及对应的方法暴露给客户端。
iPhone ip = new iPhone(); ip.getPhoneInfo();
这样的方式非常原始,也很简单,但是代码的逻辑不清晰,暴露的内容过多。
解决的方案:
- 抽象逻辑,提供接口
public interface PhoneType { void getPhoneInfo(); } public class iPhone implements PhoneType { @Override public void getPhoneInfo() { System.out.println("我是iPhone"); } } PhoneType ip = new iPhone(); ip.getPhoneInfo();
简单工厂模式
public class PhoneFactory { public PhoneType getTheObject(String tag) { if (tag.equals("iPhone")) { return new iPhone(); } else if (tag.equals("xiaomi")) { return new xiaomi(); } return null } }
客户端调用
PhoneFactory pf = new PhoneFactory(); pf.getTheObject("iPhone").getPhoneInfo(); pf.getTheObject("xiaomi").getPhoneInfo();
简单工厂模式,本身已经为解耦合做出了很好的方案。但是它有缺点:
- PhoneFactory 代码跟 Phone 代码紧耦合
- 每次要添加/删除/修改某一个 Phone,都需要修改 PhoneFactory 这个类
解决方案就是工厂方法模式
工厂方法模式
为 Phone 工厂,创建一个接口:
public interface PhoneFactory { PhoneType getTheObject(); }
然后为每个品牌创建一个实现类继承Phone工厂
public class iPhoneFactoryImpl implements PhoneFactory {
@Override
public PhoneType getTheObject() {
return new iPhone();
}
}
如果再增加另外一款产品,比如 Huawei,那么只需要另外一个工厂就可以了:
public class xiaomiFactoryImpl implements PhoneFactory {
@Override
public PhoneType getTheObject() {
return new xiaomi();
}
}
客户端调用
PhoneFactory iPhoneFactory = new iPhoneFactoryImpl(); PhoneFactory xiaomiFactory = new xiaomiFactoryImpl(); xiaomiFactory.getTheObject().getPhoneInfo();
工厂方法模式,是最标准的一种工厂模式,也是应用广泛的一种模式。
适用性
1.当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
- 代码容易膨胀
- 不容易反应产品与产品之间的关系