真刀实枪之抽象工厂方法模式
-
女娲失误了
- 人是造出来,世界也热闹了,可是低头一看,都是清一色的类型,缺少了关爱、仇恨、喜怒哀乐等情绪,人的生命太平淡了,女娲一想,猛然一拍脑袋,忘记给人类定义性别了,那怎么办?抹掉重来,于是人类经过了一次大洗礼,所有的人种都给消灭了,世界又是空无一物,寂静而又寂寞。
- 现有条件下重新造人,废物利用
1. Product类定义互斥的性别 2. 生产的工厂类--生产设备--八卦炉(男性八卦生产炉和女性八卦生产炉)
- 改造类图
-
代码
-
Human接口
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public interface Human { // 每个人种都有相应的人种 public void getColor(); // 人类都会说话 public void talk(); // 每个人都有性别 public void getSex(); }
-
AbstractBlackHuman抽象类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public abstract class AbstractBlackHuman implements Human { @Override public void getColor() { System.out.println("黑人的皮肤是黑色的!"); } @Override public void talk() { System.out.println("黑人说话是听不大懂的!"); } }
-
AbstractYellowHuman抽象类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public abstract class AbstractYellowHuman implements Human { @Override public void getColor() { System.out.println("黄人的皮肤是黄色的!"); } @Override public void talk() { System.out.println("黄人说话是双字节的!"); } }
-
AbstractWhiteHuman抽象类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public abstract class AbstractWhiteHuman implements Human { @Override public void getColor() { System.out.println("白人的皮肤是白色的!"); } @Override public void talk() { System.out.println("白人说话是单字节的!"); } }
-
FemaleBlackHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class FemaleBlackHuman extends AbstractBlackHuman { @Override public void getSex() { System.out.println("黑色女性!"); } }
-
MaleBlackHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class MaleBlackHuman extends AbstractBlackHuman { @Override public void getSex() { System.out.println("黑色男性!"); } }
-
FemaleYellowHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class FemaleYellowHuman extends AbstractYellowHuman { @Override public void getSex() { System.out.println("黄色女性!"); } }
-
MaleYellowHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class MaleYellowHuman extends AbstractYellowHuman { @Override public void getSex() { System.out.println("黄色男性!"); } }
-
FemaleWhiteHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class FemaleWhiteHuman extends AbstractWhiteHuman { @Override public void getSex() { System.out.println("白色女性!"); } }
-
MaleWhiteHuman类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class MaleWhiteHuman extends AbstractWhiteHuman { @Override public void getSex() { System.out.println("白色男性!"); } }
-
HuamnFactory接口
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public interface HumanFactory { public Human createWhiteHuman(); public Human createBlackHuman(); public Human createYellowHuman(); }
-
FemaleFactory类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class FemaleFactory implements HumanFactory { @Override public Human createWhiteHuman() { return new FemaleWhiteHuman(); } @Override public Human createBlackHuman() { return new FemaleBlackHuman(); } @Override public Human createYellowHuman() { return new FemaleYellowHuman(); } }
-
MaleFactory类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class MaleFactory implements HumanFactory { @Override public Human createWhiteHuman() { return new MaleWhiteHuman(); } @Override public Human createBlackHuman() { return new MaleBlackHuman(); } @Override public Human createYellowHuman() { return new MaleYellowHuman(); } }
-
测试类
package com.peng.patern; /** * @author kungfu~peng * @data 2017年11月15日 * @description */ public class Test { public static void main(String[] args) { // 第一条生产线,男性生产线 HumanFactory maleHumanFactory = new MaleFactory(); // 第二条生产线,女性生产线 HumanFactory femaleHumanFactory = new FemaleFactory(); // 生产黄色人 Human maleYellowHuman = maleHumanFactory.createYellowHuman(); Human femaleYellowHuman = femaleHumanFactory.createYellowHuman(); maleYellowHuman.getColor(); maleYellowHuman.talk(); maleYellowHuman.getSex(); femaleYellowHuman.getColor(); femaleYellowHuman.talk(); femaleYellowHuman.getSex(); // 生产白色人 Human maleWhiteHuman = maleHumanFactory.createWhiteHuman(); Human femaleWhiteHuman = femaleHumanFactory.createWhiteHuman(); maleWhiteHuman.getColor(); maleWhiteHuman.talk(); maleWhiteHuman.getSex(); femaleWhiteHuman.getColor(); femaleWhiteHuman.talk(); femaleWhiteHuman.getSex(); // 生产黑色人 Human maleBlackHuman = maleHumanFactory.createBlackHuman(); Human femaleBlackHuman = femaleHumanFactory.createBlackHuman(); maleBlackHuman.getColor(); maleBlackHuman.talk(); maleBlackHuman.getSex(); femaleBlackHuman.getColor(); femaleBlackHuman.talk(); femaleBlackHuman.getSex(); } }
-
-
各种肤色的男性、女性都制造出来了,两性之间产生了相互吸引力,于是情感产生,这个世界产生了一种小说的题材“爱情”。不知道大家去过工厂没,每个工厂划分为很多的车间,每个车间又分多条生产线,分别生产不同的产品,我们可以把八卦炉比喻为车间,把八卦炉生产的工艺(生产白人,黑人,黄人)称之为生产线,如此看来一个女性的生产车间就是专门生产各种肤色的女性。各个车间和生产线的职责非常明确,在车间生产出来的产品可以有耦合关系,在一个车间协调好。
抽象工厂的定义
- Provide an interface for creating families of related or dependent objects whihout specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类)
- 类图
- 通用:
- 首先有两个影响的产品线(也叫产品族)
- 通用类图
- 代码形如女娲造人,注意下面这几点
1. 接口方法全,抽象实现接口,共有方法实现,特别方法为抽象 2. 具体工厂针对的是具体产品的一个分支 1. 【Creator_1-----(ProductA_1、ProductB_1)】 2. 【Creator_2-----(ProductA_2、ProductB_2)】
- 在场景类中,没有任何一个方法与实现类有关系,对于任意一个产品来说,我们只要知道它的工厂方法就可以生产一个对应的产品,无需关心它的实现类。
抽象方法的应用
- 优点
1. 封装性 2. 产品族内的约束为非公开状态--高层模块不关心约束
- 缺点
1. 产品族的扩展非常困难:增加产品ProductA_3,哈哈哈,代码改动大吧! 2. 违反了开闭原则--“有毒代码”--产生侵害的危险
抽象方法的使用场景
- 一个对象族,或是一组没有任何关系的对象,都有相同的约束,则可以使用抽象方法模式
- 例如:一个文本编辑器和一个图片编辑器--不同操作系统下生产出不同的文本编辑器和图片编辑器
- 注意事项
- 横向扩展容易(产品等级),纵向扩展难--从横向来说是符合开闭原则的
最佳实践
- 涉及不同操作系统的时候--考虑下抽象方法模式
- 软件功能
- 应用逻辑
- UI
声明
- 摘自秦小波《设计模式之禅》第2版;
- 仅供学习,严禁商业用途;
- 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正。