【设计模式】抽象工厂模式 ( 简介 | 适用场景 | 优缺点 | 产品等级结构和产品族 | 代码示例 )_抽象工厂模式的原理和应用-程序员宅基地

技术标签: 抽象工厂模式  设计模式  





一、抽象工厂模式简介



抽象工厂模式 : 提供 一个 创建 一系列 相关 或 相互依赖 对象 的接口 ;

创建目标对象时 , 只需要直到对象的抽象类型或接口类型即可 , 不需要知道具体的实现类型 ;

抽象工厂模式类型 : 创建型 ;


抽象工厂模式 可以将 一组具有同一主题 , 单独的工厂 封装起来 ;
在使用时 , 客户端 创建 抽象工厂 的实现 , 使用 抽象工厂 作为接口 , 来创建这一主题的对象 ;
使用的时候 , 不需要知道 从内部 工厂方法中获得的 对象 的具体类型 ;
客户端 只 使用这些对象的 通用接口 ;

抽象工厂模式 实现了 一组对象的 实现细节使用 分离 ;





二、抽象工厂模式适用场景



抽象工厂模式适用场景 :

  • 忽略创建细节 : 客户端 不关心 产品实例 如何 被创建 , 实现等细节 ;
  • 创建产品族 : 强调 一系列 相关的 产品对象 , 一般是 同一个产品族 , 一起使用 创建对象需要大量重复的代码 ;
  • 产品类库 : 提供 一个 产品类 的库 , 所有的产品 以 同样的接口出现 , 使 客户端不依赖于具体实现 ;

使用抽象工厂模式 , 可以在工厂变化时 , 不需要修改 客户端 使用工厂的 代码 ;





三、抽象工厂模式优缺点



抽象工厂模式优点 :

  • 隔离产品代码 :应用层 隔离 具体产品的代码 , 客户端 无须关心 产品创建 的细节 ;
  • 创建产品族 :一个系列 的 产品族 , 统一到一起创建 ;

抽象工厂模式缺点 :

  • 扩展困难 : 规定了 所有 可能 被创建 产品集合 , 产品族扩展 新的产品 困难 , 需要 修改抽象工厂的接口 ;
  • 增加难度 : 增加了系统的 抽象性理解难度 ;




四、产品等级结构和产品族



下图中 , 有 椭圆形 , 圆形 , 正方形 , 三种产品 ;

  • 产品族 : 相同颜色的代表一个产品族 ;
  • 产品等级结构 : 相同形状的代表同一个产品等级结构 ;

在这里插入图片描述

如 : 方型 - 洗衣机 , 圆形 - 空调 , 椭圆 - 冰箱 ;

  • 横向 看 产品族 : 某 品牌下 有 方型 - 洗衣机 , 圆形 - 空调 , 椭圆 - 冰箱 , 这是一个产品族 ;
  • 纵向看产品等级结构 : 椭圆 - 冰箱 , 纵向指的是不同品牌的冰箱 ;

工厂方法模式 针对的是 产品等级结构 , 可以 扩展多个相同的产品 ;

抽象工厂模式 针对的是 产品族 , 在 某个品牌 的工厂中取出 洗衣机 类 , 取出的肯定是 该品牌的洗衣机实例对象 ;

只要指出 产品所在的 产品族 以及 产品所在的 产品等级结构 , 就可以唯一确定一个产品 ;


左侧的 纵坐标轴 上的 工厂 是 具体的工厂 , 从该具体的工厂中 创建的实例该产品族中的实例 ;

在这里插入图片描述


使用 工厂模式 还是 抽象工厂模式 , 要看具体的业务场景 ;
当一个工厂 可以 创建 分属于 不同 产品等级结构一个 产品族 中的 不同对象时 , 使用 抽象工厂模式 ;

如 :

  • 工厂 中可以创建 相同品牌的 洗衣机 , 冰箱 , 空调 等产品 , 使用 抽象工厂模式 ;
  • 如果 工厂中创建 不同品牌的空调 , 则使用 工厂方法模式 ;




五、抽象工厂模式代码示例



如果要新增 产品族 , 只需要增加 产品族工厂 , 对应的产品类 即可 ;
如果要新增 产品等级 , 很麻烦 , 需要修改所有的产品族工厂 , 这就违背了开闭原则 ;

产品等级结构固定 , 需要多个产品组合在一起形成产品族的 业务场景 , 适合使用抽象工厂模式 ;


业务场景 : 有两个电器品牌 , 美的 和 格力 ; 每个品牌下都有 冰箱 和 空调 产品 ;


1、冰箱抽象类


package abstractfactory;

/**
 * 冰箱抽象类
 */
public abstract class Fridge {
    
    public abstract void produce();
}

2、美的冰箱实现类


package abstractfactory;

/**
 * 美的冰箱
 */
public class MideaFridge extends Fridge {
    
    @Override
    public void produce() {
    
        System.out.println("生产美的冰箱");
    }
}

3、格力冰箱实现类


package abstractfactory;

/**
 * 格力冰箱
 */
public class GreeFridge extends Fridge {
    
    @Override
    public void produce() {
    
        System.out.println("生产格力冰箱");
    }
}

4、空调抽象类


package abstractfactory;

/**
 * 空调抽象类
 */
public abstract class AirConditioner {
    
    public abstract void produce();
}

5、美的空调实现类


package abstractfactory;

/**
 * 美的空调
 */
public class MideaAirConditioner extends AirConditioner {
    
    @Override
    public void produce() {
    
        System.out.println("生产美的空调");
    }
}

6、格力空调实现类


package abstractfactory;

/**
 * 格力空调
 */
public class GreeAirConditioner extends AirConditioner {
    
    @Override
    public void produce() {
    
        System.out.println("生产格力空调");
    }
}

7、工厂抽象接口 ( 重点 )


package abstractfactory;

/**
 * 抽象工厂方法
 */
public interface Factory {
    
    /**
     * 生产冰箱
     * @return
     */
    Fridge getFridge();

    /**
     * 生产空调
     * @return
     */
    AirConditioner getAirConditioner();
}

8、美的工厂实现类 ( 重点 )


package abstractfactory;

/**
 * 美的工厂
 */
public class MideaFactory implements Factory {
    
    @Override
    public Fridge getFridge() {
    
        return new MideaFridge();
    }

    @Override
    public AirConditioner getAirConditioner() {
    
        return new MideaAirConditioner();
    }
}

9、格力工厂实现类 ( 重点 )


package abstractfactory;

/**
 * 格力抽象工厂
 */
public class GreeFactory implements Factory {
    
    @Override
    public Fridge getFridge() {
    
        return new GreeFridge();
    }

    @Override
    public AirConditioner getAirConditioner() {
    
        return new GreeAirConditioner();
    }
}

10、测试类


package abstractfactory;

public class Main {
    
    public static void main(String[] args) {
    
        // 生产 美的 品牌的 冰箱 和 空调
        Factory mideaFactory = new MideaFactory();

        // 美的冰箱
        Fridge mideaFridge = mideaFactory.getFridge();
        mideaFridge.produce();

        // 美的空调
        AirConditioner mideaAirConditioner = mideaFactory.getAirConditioner();
        mideaAirConditioner.produce();

        System.out.println();

        // 生产 格力 品牌的 冰箱 和 空调
        Factory greeFactory = new GreeFactory();

        // 格力冰箱
        Fridge greeFridge = greeFactory.getFridge();
        greeFridge.produce();

        // 格力空调
        AirConditioner greeFridgeAirConditioner = greeFactory.getAirConditioner();
        greeFridgeAirConditioner.produce();
    }
}

执行结果 :

生产美的冰箱
生产美的空调

生产格力冰箱
生产格力空调

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/han1202012/article/details/119859243

智能推荐

【生产问题--服务器宕机解决】_生产服务宕机了,我们通过哪些方式去定位问题-程序员宅基地

文章浏览阅读539次,点赞3次,收藏3次。线上服务器宕机问题的解决。如果你也有类似的问题,可以参考下。主要思路用mat 工具分析下.hprof文件_生产服务宕机了,我们通过哪些方式去定位问题

Qt on Android:图文详解Hello World全过程_qt kids-程序员宅基地

文章浏览阅读1.6k次。这是系列文章中的一篇,阅读本文前请先阅读《Windows下Qt 5.2 for Android开发入门》,以便确保开发环境和作者一致。部分文章被转发/转载却没有注明出处,特此声明:版权所有 foruok ,如需转载敬请注明出处(http://blog.csdn.net/foruok)。我将从实践出发,带领大家一步一步完成在 Android 上的第一个 Qt 应用: Hello Qt_qt kids

RIP、OSPF、BGP协议之间的区别_rip,ospf,bgp三个协议的区别-程序员宅基地

文章浏览阅读1.5k次,点赞3次,收藏11次。③只有当链路状态发生变化时,路由器才用洪泛法向所有路由器发送此信息,并且更新过程收敛的快,不会出现RIP“坏消息传得慢”的问题。②发送的信息是与本路由器相邻的所有路由器的链路状态,但这只是路由器所知道的部分信息。③网络出现故障时,会出现慢收敛现象,俗称“坏消息传得慢”,使更新过程的收敛时间长。②路由器之间交换的是路由器中的完整路由表,因此网络规模越大,开销也越大。:BGP是不同自治系统的路由器之间交换路由信息的协议,是一种外部网关协议。②路由器交换的信息是当前路由器所知道的全部信息,即。_rip,ospf,bgp三个协议的区别

uni-app运行到微信小程序报错[ pages/index/index.json 文件内容错误] pages/index/index.json: [“usingComponents“][“u-nav-程序员宅基地

文章浏览阅读6.1k次。uni-app运行到微信小程序时报错:“[ pages/index/index.json 文件内容错误] pages/index/index.json: [“usingComponents”][“u-navbar”] 未找到”这是由于引用了第三方UI库,比如uview,pages.json配置easycom规则(按需引入),使用了npm安装方式,但微信开发者工具没有构建npm,可以改下下载方式// pages.json{ "easycom": { // 下载安装的方式需要前面_[ pages/index/index.json 文件内容错误] pages/index/index.json: ["usingcompon

五分钟了解物联网SIM卡——这个文章刷新了我对sim卡的认识_中移物联nb-iot模块 不认识sim卡-程序员宅基地

文章浏览阅读6.7k次,点赞32次,收藏108次。嵌入式软件自留地 今天编者荐语:五分钟了解物联网SIM卡——这个文章刷新了我对sim卡的认识,不熟悉的可以看看~~以下文章来源于华为云IoT ,作者我是卤蛋这个文章来自网络,看了觉得不错,因此特意整理转载下。是华为iot小助手分享的,都知道华为在物联网领域是国内老大的地位,分享的文章还是比较有价值的。【摘要】SIM卡是移动通信中不可或缺的组成部分,在物联网解决方案中,设备移动上网也需要使用SIM卡。那么,SIM卡是什么?SIM卡有几种?各种SIM卡有什么区别?本文将为您答疑.._中移物联nb-iot模块 不认识sim卡

js获取当前Unix时间戳_js unix时间戳-程序员宅基地

文章浏览阅读1.1w次。JavaScript 获取当前时间戳:第一种方法:var timestamp = Date.parse(new Date());第二种方法:var timestamp=new Date().getTime();第三种方法:var timestamp = (new Date()).valueOf();第一种:获取的时间戳是把毫秒改成000显示,_js unix时间戳

随便推点

源码分析Dubbo服务提供者启动流程-下篇-程序员宅基地

文章浏览阅读838次,点赞17次,收藏27次。还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。图片转存中…(img-lrSLZmoK-1710427356248)]由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)

PHP/MySQL开发环境:MAMP Pro for Mac_mamp pro 5.7-程序员宅基地

文章浏览阅读519次。mamp pro mac版是mac平台上最优秀的本地服务器搭配软件,也是最好的mysql开发环境和php开发环境,包含了acintosh、Apache、MySQL和PHP四大开发环境,用户只要轻松点选就能对架站、讨论区、论坛等必备的元件进行安装,让你轻松在mac平台上架设自己的web运行环境。Web运行环境——MAMP Pro功能亮点将wordPress主机发布到您的Live Hosting..._mamp pro 5.7

python抛出异常会终止程序吗_Python学习笔记之类型判断,异常处理,终止程序操作小结...-程序员宅基地

文章浏览阅读4.9k次。python学习笔记 类型判断,异常处理,终止程序,实例代码:#idle中按F5可以运行代码#引入外部模块 import xxx#random模块,randint(开始数,结束数) 产生整数随机数import randomimport sysimport ossecret = random.randint(1,10)temp = input("请输入一个数字\n")#print(type(temp..._程序抛出异常不一定终止程序

引用Dll失败-程序员宅基地

文章浏览阅读583次。C#中添加引用Dll文件必须先注册!!注册方法:regsvr32 *.dll (*代表Dll文件名称)!!_引用dll失败

vscode-python的debug 教学(最全)_vscode python debug_python vs debug-程序员宅基地

文章浏览阅读685次,点赞14次,收藏25次。Visual Studio Code 的主要功能之一是其强大的调试支持。VS Code 的内置调试器有助于加速编辑、编译和调试循环。在插件库内搜索python Debugger,安装插件(1)创建debug_learning.py测试文件(2)设置断点(2)启动debug模式(3)debug的各个按钮的介绍以下文档基于内置的 Node.js 调试器,但大多数概念和功能也适用于其他调试器。在阅读有关调试的信息之前,首先创建一个示例Node.js应用程序会很有帮助。您可以按照Node.js演练安_python vs debug

[附源码]计算机毕业设计Python+uniapp家校通微信小程序rjeuh(程序+lw+远程部署)_家校互通小程序开源-程序员宅基地

文章浏览阅读112次。Python3.7.7+Django+Mysql5.7+pip list+HBuilderX(Vscode也行)+uni+Vue+Pychram社区版。[附源码]计算机毕业设计Python+uniapp家校通微信小程序rjeuh(程序+lw+远程部署)2. 前端:uni+css+javascript+jQuery+easyUI+highcharts。Django + uni小程序 +Python+Mysql 等等组成,B/S模式等等。该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。_家校互通小程序开源