设计模式之禅【抽象工厂模式】

真刀实枪之抽象工厂方法模式

  • 女娲失误了

    • 人是造出来,世界也热闹了,可是低头一看,都是清一色的类型,缺少了关爱、仇恨、喜怒哀乐等情绪,人的生命太平淡了,女娲一想,猛然一拍脑袋,忘记给人类定义性别了,那怎么办?抹掉重来,于是人类经过了一次大洗礼,所有的人种都给消灭了,世界又是空无一物,寂静而又寂寞。
    • 现有条件下重新造人,废物利用
      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版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值