zoukankan      html  css  js  c++  java
  • 【设计模式】抽象工厂模式

    使用频率:★★★★★

    一、什么是抽象工厂模式

    就是对一组具有相同主题的工厂进行封装(维基百科解释的很到位);

    例如:生产一台PC机,使用工厂方法模式的话,一般会有cpu工厂,内存工厂,显卡工厂...但是使用抽象工厂模式的话,只有一个工厂就是PC工厂,但是一个PC工厂涵盖了cpu工厂,内存工厂,显卡工厂等要做的所有事;

    二、补充说明

    • 注意这里的“相同主题”的概念,表示的是同一个产品族,不能将cpu工厂,面粉工厂封装成一个工厂,因为他们不属于同一个产品族;
    • 另外,还有一个产品等级的概念,还是以生产PC机为例,所谓的产品等级指的是不同厂商生产的CPU,如Intel和AMD的CPU,他们是同一个产品等级,如果只涉及产品等级的话,是不需要应用抽象工厂模式,使用工厂方法模式即可;
    • 工厂方法模式解决的范畴是产品等级(AMD处理器,Intel处理器等);抽象工厂模式解决的范畴是产品族等级(联想PC、惠普PC等);

    三、角色

    • 抽象工厂
    • 具体工厂
    • 抽象产品
    • 具体产品
    • 产品使用者

    说明:

    • 具体工厂“继承”抽象工厂;
    • 具体产品”继承“抽象产品;
    • 每个具体工厂(如PC工厂)包含若干个子工厂方法(如cpu工厂方法、显卡工厂方法...),子工厂方法负责生产对应的具体子产品,所有具体子产品(cpu、内存、显卡...)组合成一个具体产品(如惠普XXX型号PC);
    • 产品使用者使用每个具体工厂生产的具体产品;

    四、例子

    这里就不用PC这个例子了,继续前一个工厂模式的例子,在上一篇工厂模式的例子中,我们使用的是创建父亲对象这个例子,其中中国父亲和美国父亲指的就是同一个产品等级;

    但是当我们要创建一个家庭对象的时候,需要创建父亲对象、母亲对象、孩子对象等等,所谓的父亲、母亲、孩子就构成了一个产品族,中国家庭、美国家庭就是产品族等级;这个时候就需要使用抽象工厂模式了;

    类之间的关系图:

    代码实现:

    先创建抽象产品(抽象母亲、抽象父亲),具体产品(具体母亲、具体父亲):

    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public interface IMother {
        public void printName();
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public interface IFather {
        public void printName();
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class ChineseMother implements IMother{
        private String name;
        public ChineseMother(String name) {
            this.name = name;
            System.out.println("create a cn mother.");
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public void printName() {
            System.out.println(this.getClass().getName() + ":" + this.name);
            
        }
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class AmericanMother implements IMother{
        private String name;
        public AmericanMother(String name) {
            this.name = name;
            System.out.println("create a us mother.");
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public void printName() {
            System.out.println(this.getClass().getName() + ":" + this.name);
            
        }
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class ChineseFather implements IFather{
        private String name;
        public ChineseFather(String name) {
            this.name = name;
            System.out.println("create a cn father.");
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public void printName() {
            System.out.println(this.getClass().getName() + ":" + this.name);
            
        }
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class AmericanFather implements IFather{
        private String name;
        public AmericanFather(String name) {
            this.name = name;
            System.out.println("create a us father.");
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public void printName() {
            System.out.println(this.getClass().getName() + ":" + this.name);
            
        }
    }

    创建一个抽象家庭工厂接口:

    package com.pichen.dp.creationalpattern.abstractfactory;
    
    /**
     * 
     * abstract factory
     * father + mother + sister + ... = Product Family
     * cnfather + usfather + ukfather + ... = Product grade  //factory method
     * 〈功能详细描述〉
     * @author    pi chen
     * @version   cp-lib V1.0.0, 2015年11月25日
     * @see       
     * @since     cp-lib V1.0.0
     */
    public interface IFamilyFactory {
        public IFather createFather(String name);
        public IMother createMother(String name);
    }

    分别创建具体的中国家庭工厂和美国家庭工厂:

    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class ChineseFamilyFactory implements IFamilyFactory{
    
        @Override
        public IFather createFather(String name) {
            return new ChineseFather(name);
        }
    
        @Override
        public IMother createMother(String name) {
            return new ChineseMother(name);
        }
    
    }
    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class AmericanFamilyFactory implements IFamilyFactory{
    
        @Override
        public IFather createFather(String name) {
            return new AmericanFather(name);
        }
    
        @Override
        public IMother createMother(String name) {
            return new AmericanMother(name);
        }
    
    }

    创面产品使用者main方法:

    package com.pichen.dp.creationalpattern.abstractfactory;
    
    public class Main {
        public static void main(String[] args) {
            IFamilyFactory cnFamilyFactory = new ChineseFamilyFactory();
            IFamilyFactory usFamilyFactory = new AmericanFamilyFactory();
            
            IFather cnFather = cnFamilyFactory.createFather("cn father-test");
            IMother cnMother = cnFamilyFactory.createMother("cn mother-test");
            
            IFather usFather = usFamilyFactory.createFather("us father-test");
            IMother usMother = usFamilyFactory.createMother("us mother-test");
            
            cnFather.printName();
            cnMother.printName();
            usFather.printName();
            usMother.printName();
        }
    }

    结果打印如下,功能正常:

    create a cn father.
    create a cn mother.
    create a us father.
    create a us mother.
    com.pichen.dp.creationalpattern.abstractfactory.ChineseFather:cn father-test
    com.pichen.dp.creationalpattern.abstractfactory.ChineseMother:cn mother-test
    com.pichen.dp.creationalpattern.abstractfactory.AmericanFather:us father-test
    com.pichen.dp.creationalpattern.abstractfactory.AmericanMother:us mother-test
  • 相关阅读:
    mysql数据库常用指令
    解决windows的mysql无法启动 服务没有报告任何错误的经验。
    “Can't open file for writing”或“operation not permitted”的解决办法
    启动Apache出现错误Port 80 in use by "Unable to open process" with PID 4!
    如何打开windows的服务services.msc
    常见的HTTP状态码 404 500 301 200
    linux系统常用的重启、关机指令
    (wifi)wifi移植之命令行调试driver和supplicant
    linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
    alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号
  • 原文地址:https://www.cnblogs.com/chenpi/p/5156801.html
Copyright © 2011-2022 走看看