工厂模式
工厂模式是一种创建者设计模式,细分之下可以分成三类简单工厂模式,工厂方法模式和抽象工厂模式。
简单工厂模式
最简单的工厂模式,它采用静态方法的方式来决定应该应该生产什么商品。- public class StoreFactory {
- public static ICommodity getCommodityService(Integer commodityType) {
- if (null == commodityType) {
- return null;
- }
- switch (commodityType) {
- case 1:
- return new CouponCommodityService();
- case 2:
- return new GoodsCommodityService();
- case 3:
- return new CardCommodityService();
- }
- throw new RuntimeException("不存在的商品服务类型");
- }
- }
复制代码 它的优点在于
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦
- 把初始化实例时的工作放到工厂里进行,使代码更容易维护,更符合面向对象的原则面向接口编程,而不是面向实现编程
它的缺点在于
- 工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响
- 违背开闭原则,一旦添加新的产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂
- 简单工厂模式使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构
它适用于
- 客户只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时;
- 当工厂类负责创建的对象比较少时。
工厂方法模式
工厂方法模式中,工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
它把类的实例化延迟到工厂类的子类中,由子类来决定应该实例化哪个类。
由此,它解决了简单工厂模式违背了开闭原则的问题。
它的优点在于
- 更符合开闭原则
- 符合单一责任原则,每个具体工厂类只负责创建对应的产品
- 不使用静态工厂方法,可以形成基于继承的等级结构
它的缺点在于
- 需要的类的数量非常多,每添加一个新产品,就要相应的添加一个新的工厂。
- 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另一种产品,仍然需要修改实例化的具体工厂类
- 一个工厂只能创建一种具体产品
它适用于:
- 当一个类不需要知道它所需要的对象的类时
- 当一个类希望通过其子类来指定创建对象时
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂的类名存储在配置文件或数据库中(比如spring中的FactoryBean)
抽象工厂模式
抽象工厂模式定义了一个能生产一个产品族的超级抽象工厂,然后交给子类工厂去生产某一个产品族的产品。
产品族和产品等级
产品等级结构既是产品的继承结构。比如一个抽象类是电视机,其子类有海尔电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构。
产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔生产的海尔电视机、海尔洗衣机和海尔冰箱,构成了一个产品族。
设计模式详解
图中,IProductFactory是工厂接口,定义了生产手机和路由器组成的产品族的方法。而子类工厂HuaweiFactory负责生产华为产品族,XiaomiFactory负责生产小米产品族。
另外,IPhoneProduct和IRouterProduct分别定义了手机和路由器两个产品等级。
它的优点在于
- 一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
- 可以很方便地添加一个新的产品族
它的缺点在于
- 产品族的拓展非常困难,要增加一个系列的某一个产品,既要修改工厂抽象类里添加代码,又要在具体的实现类里面添加代码
- 增加了系统的抽象性和理解难度
它适用于
- 一系列相关产品对象(属于同一产品族)一起创建时需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |