zoukankan      html  css  js  c++  java
  • 抽象工厂模式

    初学编程模式,请读者指出不正确指出,多谢!

        抽象工厂模式的作用是为了灵活地生产产品。如果产品能够从一维的角度进行分类的话,可以直接使用普通的工厂模式即可。但是,在真实环境下,产品的属性可能是二维或者更高维的,所以这个时候就要用到抽象工厂了。本文完全参考CBF4LIFE缩写的《Java设计模式》,网上可下,文中的抽象工厂使用了女娲补天,不是,是女娲造人的例子来阐明抽象工厂模式,诙谐生动。在这里,我就借助这个例子来描述本人对抽象工厂的理解。

         首先,把人看作产品,那么人首先有肤色之分:白,黑,黄;同时也有性别之分:男,女;这两种属性是交叉存在的,也就是说既有黄色的男人,也有白色的女人等等。如果使用普通工厂的思路来考虑的话,直接在单一的工厂里设计六个方法,分别生产需要的人种即可。但是,这样太麻烦了。而且灵活度很低,对于我们这里的需求,先定义抽象工厂的基本功能就是生产三个颜色的人种,不分男女,即,工厂的基本方法就有:生产黄人,黑人,白人。然后,在定义两种具体的工厂,男人工厂,女人工厂。这样,通过调用男人工厂的三个函数可以生产黑男人,白男人和黄男人;调用女人工厂可以生产黑女人,白女人和黄女人。这样,能够灵活地生产这几个人种了。

          有人可能疑问,为什么不设计三个工厂:黑人工厂,白人工厂,黄人工厂?这样当然也是可以的,只是从另一个角度来决定工厂的作用,这种情况下,工厂的基本功能就是生产男人和女人了。

          整理的程序结构如下(摘抄至《java设计模式》):

          1、定义接口(interface)Human,包含了所有人的全部特征

    package com.cbf4life;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 定义一个人类的统称,问题出来了,刚刚定义的时候忘记定义性别了 这个重要的问题非修改不可,否则这个世界上太多太多的东西不存在了
     */
    public interface Human {
        // 首先定义什么是人类
        // 人是愉快的,会笑的,本来是想用smile表示,想了一下laugh更合适,好长时间没有大笑了;
        public void laugh();
    
        // 人类还会哭,代表痛苦
        public void cry();
    
        // 人类会说话
        public void talk();
    
        // 定义性别
        public void sex();
    }
    View Code

          2、定义了人所有种类的枚举变量HumanEnum,共六种变量,在通过工厂创建产品的时候,工厂通常需要将创建的产品的类名传入,生成类的实例。用枚举变量可以很好地保存六种产品类(就是这里的人种)的名称,这个技巧非常值得学习

    package com.cbf4life;
    
    public enum HumanEnum {
        // 把世界上所有人类型都定义出来
        YelloMaleHuman("com.cbf4life.yellowHuman.YellowMaleHuman"), YelloFemaleHuman(
                "com.cbf4life.yellowHuman.YellowFemaleHuman"), WhiteFemaleHuman(
                "com.cbf4life.whiteHuman.WhiteFemaleHuman"), WhiteMaleHuman(
                "com.cbf4life.whiteHuman.WhiteMaleHuman"), BlackFemaleHuman(
                "com.cbf4life.blackHuman.BlackFemaleHuman"), BlackMaleHuman(
                "com.cbf4life.blackHuman.BlackMaleHuman");
    
        private String value = "";
    
        // 定义构造函数,目的是Data(value)类型的相匹配
        private HumanEnum(String value) {
            this.value = value;
        }
    
        public String getValue() {
            return this.value;
        }
    
    }
    View Code

          3、接下来,需要定义一个工厂的接口,这个接口中包含了所有基本的工厂操作,也就是上文提到的生产黄人,黑人,白人的三个方法

    package com.cbf4life;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 这次定一个接口,应该要造不同性别的人,需要不同的生产线 那这个八卦炉必须可以制造男人和女人
     */
    public interface HumanFactory {
        // 制造黄色人种
        public Human createYellowHuman();
    
        // 制造一个白色人种
        public Human createWhiteHuman();
    
        // 制造一个黑色人种
        public Human createBlackHuman();
    }
    View Code

          4、然后定义造人工厂的抽象类,该抽象类的作用自然就是造人了,它只负责根据传入的类的名称造人,管你造男人女人黑人白人

    package com.cbf4life.humanFactory;
    
    import com.cbf4life.Human;
    import com.cbf4life.HumanEnum;
    import com.cbf4life.HumanFactory;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 编写一个抽象类,根据enum创建一个人类出来
     */
    public abstract  class AbstractHumanFactory implements HumanFactory {
        /*
         * 给定一个性别人种,创建一个人类出来专业术语是产生产品等级
         */
        protected Human createHuman(HumanEnum humanEnum) {
            Human human = null;
            // 如果传递进来不是一个Enum中具体的一个Element的话,则不处理
            if (!humanEnum.getValue().equals("")) {
                try {
                    // 直接产生一个实例
                    human = (Human) Class.forName(humanEnum.getValue())
                            .newInstance();
                } catch (Exception e) {
                    // 因为使用了enum,这个种异常情况不会产生了,除非你的enum有问题;
                    e.printStackTrace();
                }
    
            }
            return human;
        }
    }
    View Code

          5、在抽象类工厂类额基础上,就是具体的工厂类了,分为男人类MaleHumanFactory和女人类FemaleHumanFactory,每个类中的具体方法也要对应体现

    package com.cbf4life.humanFactory;
    
    import com.cbf4life.Human;
    import com.cbf4life.HumanEnum;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 女性创建工厂
     */
    public class FemaleHumanFactory extends AbstractHumanFactory {
        // 创建一个女性黑种人
        public Human createBlackHuman() {
            return super.createHuman(HumanEnum.BlackFemaleHuman);
        }
    
        // 创建一个女性白种人
        public Human createWhiteHuman() {
            return super.createHuman(HumanEnum.WhiteFemaleHuman);
        }
    
        // 创建一个女性黄种人
        public Human createYellowHuman() {
            return super.createHuman(HumanEnum.YelloFemaleHuman);
        }
    }
    View Code
    package com.cbf4life.humanFactory;
    
    import com.cbf4life.Human;
    import com.cbf4life.HumanEnum;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 男性创建工厂
     */
    public class MaleHumanFactory extends AbstractHumanFactory {
        // 创建一个男性黑种人
        public Human createBlackHuman() {
            return super.createHuman(HumanEnum.BlackMaleHuman);
        }
    
        // 创建一个男性白种人
        public Human createWhiteHuman() {
            return super.createHuman(HumanEnum.WhiteMaleHuman);
        }
    
        // 创建一个男性黄种人
        public Human createYellowHuman() {
            return super.createHuman(HumanEnum.YelloMaleHuman);
        }
    }
    View Code

          不好意思把女人类放在前面了,谁让现在男人没地位呢。

          6、接下来,就是各个产品(人)的具体情况了

          首先定义黑人的抽象类AbstractBlackHuman,以及具体类,黑男人BlackMaleHuman(应该说男黑人,意思都差不多),黑女人(听起来很别扭)BlackFemaleHuman

    package com.cbf4life.blackHuman;
    
    import com.cbf4life.Human;
    
    public abstract class AbstractBlackHuman implements Human {
        public void cry() {
            System.out.println("黑人会哭");
        }
    
        public void laugh() {
            System.out.println("黑人会笑");
        }
    
        public void talk() {
            System.out.println("黑人可以说话,一般人听不懂");
        }
    }
    View Code
    package com.cbf4life.blackHuman;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 女性黑种人
     */
    public class BlackFemaleHuman extends AbstractBlackHuman {
        public void sex() {
            System.out.println("该黑种人的性别为女...");
        }
    }
    View Code
    package com.cbf4life.blackHuman;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 男性黑种人
     */
    public class BlackMaleHuman extends AbstractBlackHuman {
        public void sex() {
            System.out.println("该黑种人的性别为男...");
        }
    }
    View Code

         然后是黄人

    package com.cbf4life.yellowHuman;
    
    import com.cbf4life.Human;
    
    public abstract class AbstractYellowHuman implements Human {
        public void cry() {
            System.out.println("黄色人种会哭");
        }
    
        public void laugh() {
            System.out.println("黄色人种会大笑,幸福呀!");
        }
    
        public void talk() {
            System.out.println("黄色人种会说话,一般说的都是双字节");
        }
    }
    View Code
    package com.cbf4life.yellowHuman;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 女性黄种人
     */
    public class YellowFemaleHuman extends AbstractYellowHuman {
        public void sex() {
            System.out.println("该黄种人的性别为女...");
        }
    }
    View Code
    package com.cbf4life.yellowHuman;
    
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 男性黄种人
    */
    public class YellowMaleHuman extends AbstractYellowHuman {
    public void sex() {
    System.out.println("该黄种人的性别为男....");
    }
    }
    View Code

          最后是白人

    package com.cbf4life.whiteHuman;
    
    import com.cbf4life.Human;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 白色人人种 为了代码整洁,新建一个包,这里是白种人的天下了
     */
    public abstract class AbstractWhiteHuman implements Human {
        public void cry() {
            System.out.println("白色人种会哭");
        }
    
        public void laugh() {
            System.out.println("白色人种会大笑,侵略的笑声");
        }
    
        public void talk() {
            System.out.println("白色人种会说话,一般都是但是单字节!");
        }
    }
    View Code
    package com.cbf4life.whiteHuman;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 女性白种人
     */
    public class WhiteFemaleHuman extends AbstractWhiteHuman {
        public void sex() {
    
            System.out.println("该白种人的性别为女....");
        }
    }
    View Code
    package com.cbf4life.whiteHuman;
    
    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 男性白种人
     */
    public class WhiteMaleHuman extends AbstractWhiteHuman {
        public void sex() {
            System.out.println("该白种人的性别为男....");
        }
    }
    View Code

          7,任何工厂都定义好了,女娲娘娘,可以开始了!(!要叫我女王大人!)

    package com.cbf4life;
    
    import com.cbf4life.humanFactory.FemaleHumanFactory;
    import com.cbf4life.humanFactory.MaleHumanFactory;
    
    public class NvWa {
        public static void main(String[] args) {
            // 第一条生产线,男性生产线
            HumanFactory maleHumanFactory = new MaleHumanFactory();
            // 第二条生产线,女性生产线
            HumanFactory femaleHumanFactory = new FemaleHumanFactory();
            // 生产线建立完毕,开始生产人了:
            Human maleYellowHuman = maleHumanFactory.createYellowHuman();
            Human femaleYellowHuman = femaleHumanFactory.createYellowHuman();
            maleYellowHuman.cry();
            maleYellowHuman.laugh();
            femaleYellowHuman.sex();
            /*
             * ..... 后面你可以续了
             */
        }
    }
    View Code

          以上便是本人对抽象工厂的理解,所有代码全部盗版CBF4LIFE的《Java设计模式》。如有错误或者不妥,欢迎留言。

  • 相关阅读:
    3.live555源码分析----延时队列
    RTP包的结构
    2.live555源码分析----服务端doEventLoop()函数分析
    1.live555源码分析----RSTPServer创建过程分析
    RTSP协议介绍 (转)
    搭建最简单的流媒体系统(服务器和客户端)
    谈一谈 MPU6050 姿态融合(转)
    Nginx的优化
    LAMP与LNMP加速与缓存优化
    Nginx在LNMP架构中的作用与虚拟主机配置
  • 原文地址:https://www.cnblogs.com/Joy06/p/3669373.html
Copyright © 2011-2022 走看看