当前位置: 首页 > news >正文

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

使用频率:★★★★★

一、什么是抽象工厂模式

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

例如:生产一台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

转载于:https://www.cnblogs.com/chenpi/p/5156801.html

相关文章:

  • oracle——06表查询中需要注意的一些问题
  • 佛山Uber优步司机奖励政策(1月25日~1月31日)
  • 携程一万亿交易额的市场逻辑
  • java27:集合框架
  • 使用 JavaScript 将网站后台的数据变化实时更新到前端-【知乎总结】
  • 随机IP代理
  • html 中几次方,平方米,立方米.
  • OCaml已经做好iOS开发准备
  • spring MVC自定义视图实现jsonp
  • 怎么提高ArcGIS for Desktop10.x的性能
  • python文件相关操作
  • socket.io+angular.js+express.js做个聊天应用(四)
  • BUG系列
  • openstack环境准备
  • MYSQL远程登录权限设置(转)
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【Leetcode】104. 二叉树的最大深度
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • express如何解决request entity too large问题
  • Invalidate和postInvalidate的区别
  • Mysql优化
  • Travix是如何部署应用程序到Kubernetes上的
  • zookeeper系列(七)实战分布式命名服务
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 我这样减少了26.5M Java内存!
  • 怎么将电脑中的声音录制成WAV格式
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • #每日一题合集#牛客JZ23-JZ33
  • $GOPATH/go.mod exists but should not goland
  • (1)虚拟机的安装与使用,linux系统安装
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (全注解开发)学习Spring-MVC的第三天
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)一些感悟
  • .jks文件(JAVA KeyStore)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .Net程序帮助文档制作
  • .NET建议使用的大小写命名原则
  • @Responsebody与@RequestBody
  • @Transactional 竟也能解决分布式事务?
  • @vue/cli 3.x+引入jQuery
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [1204 寻找子串位置] 解题报告
  • [2010-8-30]
  • [2016.7.test1] T2 偷天换日 [codevs 1163 访问艺术馆(类似)]
  • [8-23]知识梳理:文件系统、Bash基础特性、目录管理、文件管理、文本查看编辑处理...
  • [Android]竖直滑动选择器WheelView的实现
  • [ANT] 项目中应用ANT
  • [bbk5179]第66集 第7章 - 数据库的维护 03