设计模式详解:抽象工厂模式

2023-05-16

今天我们来看一下另一个使用频率非常高的抽象工厂模式,看完原理分别给出.NET和JAVA两种语言的实现源码。

定义:

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

Abstract Factory Pattern: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

又称为工具(Kit)模式

抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品

一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时抽象工厂模式比工厂方法模式更为简单、更有效率

分析:

每个具体工厂只有一个或者一组重载的工厂方法只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销

一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量

产品等级结构:产品等级结构即产品的继承结构

产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品

类图:

抽象工厂模式包含以下4个角色:

AbstractFactory(抽象工厂)

ConcreteFactory(具体工厂)

AbstractProduct(抽象产品)

ConcreteProduct(具体产品)

 适用性:

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节

系统中有多于一个的产品族,但每次只使用其中某一产品族

属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来

产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构

优点:

隔离了具体类的生成,使得客户端并不需要知道什么被创建

当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象

增加新的产品族很方便,无须修改已有系统,符合开闭原则

缺点:

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则

@增加产品族

    对于增加新的产品族,抽象工厂模式很好地支持开闭原则,只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改

@增加新的产品等级结构

    对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,违背了开闭原则


案例1:(.NET代码)

 代码清单包括:

ü (1) Button :按钮接口,充当抽象产品
ü (2) SpringButton Spring 按钮类,充当具体产品
ü (3) SummerButton Summer 按钮类,充当具体产品
ü (4) TextField :文本框接口,充当抽象产品
ü (5) SpringTextField Spring 文本框类,充当具体产品
ü (6) SummerTextField Summer 文本框类,充当具体产品
ü (7) ComboBox :组合框接口,充当抽象产品
ü (8) SpringComboBox Spring 组合框类,充当具体产品
ü (9) SummerComboBox Summer 组合框类,充当具体产品
ü (10) SkinFactory :界面皮肤工厂接口,充当抽象工厂
ü (11) SpringSkinFactory Spring 皮肤工厂,充当具体工厂
ü (12) SummerSkinFactory Summer 皮肤工厂,充当具体工厂
ü (13) 配置文件 App.config
ü (14) Program :客户端测试类

Program.cs

using System;
using System.Configuration;
using System.Reflection;

namespace AbstractFactorySample
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用抽象层定义
		    SkinFactory factory;
		    Button bt;
		    TextField tf;
		    ComboBox cb;

            //读取配置文件
            string factoryType = ConfigurationManager.AppSettings["factory"];

            //反射生成对象
            factory = (SkinFactory)Assembly.Load("AbstractFactorySample").CreateInstance(factoryType);

            bt = factory.CreateButton();
            tf = factory.CreateTextField();
            cb = factory.CreateComboBox();
            bt.Display();
            tf.Display();
            cb.Display();

            Console.Read();
        }
    }
}

Button.cs

namespace AbstractFactorySample
{
    interface Button
    {
        void Display();
    }
}

SpringButton.cs

using System;

namespace AbstractFactorySample
{
    class SpringButton : Button 
    {
	    public void Display() 
        {
		    Console.WriteLine("显示浅绿色按钮。");
	    }
    }
}

SummerButton.cs

using System;

namespace AbstractFactorySample
{
    class SummerButton : Button 
    {
	    public void Display() 
        {
		   Console.WriteLine("显示浅蓝色按钮。");
	    }	
    }
}

TextField.cs

namespace AbstractFactorySample
{
    interface TextField
    {
        void Display();
    }
}

SpringTextField.cs

using System;

namespace AbstractFactorySample
{
    class SpringTextField : TextField 
    {
	    public void Display() 
        {
		    Console.WriteLine("显示绿色边框文本框。");
	    }
    }
}

SummerTextField.cs

using System;

namespace AbstractFactorySample
{
    class SummerTextField : TextField 
    {
	    public void Display() 
        {
		    Console.WriteLine("显示蓝色边框文本框。");
	    }	
    }
}

ComboBox.cs

namespace AbstractFactorySample
{
    interface ComboBox
    {
        void Display();
    }
}

SpringComboBox.cs

using System;

namespace AbstractFactorySample
{
    class SpringComboBox : ComboBox 
    {
	    public void Display() 
        {
		    Console.WriteLine("显示绿色边框组合框。");
	    }
    }
}

SummerComboBox.cs

using System;

namespace AbstractFactorySample
{
    class SummerComboBox : ComboBox 
    {
	    public void Display() 
        {
		    Console.WriteLine("显示蓝色边框组合框。");
	    }	
    }
}

SkinFactory.cs

namespace AbstractFactorySample
{
    interface SkinFactory
    {
        Button CreateButton();
        TextField CreateTextField();
        ComboBox CreateComboBox();
    }
}

SpringSkinFactory.cs

namespace AbstractFactorySample
{
    class SpringSkinFactory : SkinFactory 
    {
	    public Button CreateButton() 
        {
		    return new SpringButton();
	    }

	    public TextField CreateTextField() 
        {
		    return new SpringTextField();
	    }

	    public ComboBox CreateComboBox() 
        {
		    return new SpringComboBox();
	    }
    }
}

SummerSkinFactory.cs

namespace AbstractFactorySample
{
    class SummerSkinFactory : SkinFactory 
    {
	    public Button CreateButton() 
        {
		    return new SummerButton();
	    }

	    public TextField CreateTextField() 
        {
		    return new SummerTextField();
	    }

	    public ComboBox CreateComboBox() 
        {
		    return new SummerComboBox();
	    }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="factory" value="AbstractFactorySample.SpringSkinFactory"/>
  </appSettings>
</configuration>

案例2:(JAVA代码)

 AbstractFactory

public interface IAnimalFactory {

    ICat createCat();
	
    IDog createDog();
}

ConcreteFactory

public class BlackAnimalFactory implements IAnimalFactory {

    public ICat createCat() {
        return new BlackCat();
    }

    public IDog createDog() {
        return new BlackDog();
    }

}

public class WhiteAnimalFactory implements IAnimalFactory {

    public ICat createCat() {
        return new WhiteCat();
    }

    public IDog createDog() {
        return new WhiteDog();
    }

}

AbstractProduct

public interface ICat {

    void eat();
}

public interface IDog {

    void eat();
}

ConcreteProduct

public class BlackCat implements ICat {

    public void eat() {
        System.out.println("The black cat is eating!");
    }

}

public class WhiteCat implements ICat {

    public void eat() {
        System.out.println("The white cat is eating!");
    }

}

public class BlackDog implements IDog {

    public void eat() {
        System.out.println("The black dog is eating");
    }

}

public class WhiteDog implements IDog {

    public void eat() {
        System.out.println("The white dog is eating!");
    }

}

Test

public static void main(String[] args) {
    IAnimalFactory blackAnimalFactory = new BlackAnimalFactory();
    ICat blackCat = blackAnimalFactory.createCat();
    blackCat.eat();
    IDog blackDog = blackAnimalFactory.createDog();
    blackDog.eat();
    
    IAnimalFactory whiteAnimalF*ctory = new WhiteAnimalFactory();
    ICat whiteCat = whiteAnimalFactory.createCat();
    whiteCat.eat();
    IDog whiteDog = whiteAnimalFactory.createDog();
    whiteDog.eat();
}

程序运行返回结果:


The black cat is eating!
The black dog is eating!
The white cat is eating!
The white dog is eating!  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式详解:抽象工厂模式 的相关文章

  • 抽象工厂模式

    工厂模式 工厂方法模式 xff08 Fatory Method Pattern xff09 提供一个接口 xff0c 一个可创建一系列相关对象的 无需指定他们的具体类 一个抽象工厂类 xff0c 不同的具体工厂产生不同的对象实体 eg 冰箱
  • 设计模式详解:模式汇总与索引清单

    从本篇开始 xff0c 和您一起进入设计模式的世界 之前用C 做微信微信公众号开发系列文章 xff0c 更多的是原生模式 xff0c 帮助猿友们理解业务流程和基本实现方法 xff0c 但是那些类的实现仍然是用面向过程的思维方式 xff0c
  • 设计模式详解:面向对象设计的七大原则

    单一职责原则 xff1a 一个对象应该只包含单一的职责 xff0c 并且该职责被完整地封装在一个类中 Single Responsibility Principle SRP Every object should have a single
  • 设计模式详解:抽象工厂模式

    今天我们来看一下另一个使用频率非常高的抽象工厂模式 xff0c 看完原理分别给出 NET和JAVA两种语言的实现源码 定义 xff1a 抽象工厂模式 xff1a 提供一个 创建一系列相关或相互依赖对象的接口 xff0c 而无须指定它们具体的
  • 抽象工厂模式(C++)

    define win 0 define mac 1 include lt iostream gt using namespace std class button public button virtual button virtual v
  • 抽象工厂模式

    抽象工厂模式针对的是对产品族 xff0c 而不是产品等级结构 产品族 xff1a 同一厂商生产的产品 产品等级 xff1a 同一产品 xff0c 不同厂商的产品 比如水果类里面由苹果和香蕉 xff0c 水果就是产品族 xff0c 苹果香蕉就
  • [C++]抽象工厂模式

    抽象工厂模式 Abstract Factory Pattern 是围绕一个超级工厂创建其他工厂 该超级工厂又称为其他工厂的工厂 这种类型的设计模式属于创建型模式 它提供了一种创建对象的最佳方式 在抽象工厂模式中 接口是负责创建一个相关对象的
  • 工厂模式(分简单工厂模式、工厂方法模式、抽象工厂模式)

    1 工厂模式概述 1 1 简单工厂模式 简单工厂模式是一种创建型设计模式 它实现了创建对象的功能 但不使用任何具体类的名称 客户端通过调用工厂类的静态方法来创建一个具体的对象 无需关心对象创建的细节 1 2 工厂方法模式 工厂方法模式是一种
  • 设计模式精讲-抽象工厂方法模式

    设计模式 抽象工厂方法模式 定义 示例 应用场景 优点 定义 提供一个创建一系列相关或互相依赖对象的接口 而无需指定它们具体的类 定义和图不理解的 可以先看下面的示例 回头再去理解 示例 以数据库为例 1 变化的部分 Mysq Oracle
  • 2022-15-Java 设计模式-抽象工厂模式

    在工厂方法模式中 我们使用一个工厂创建一个产品 一个具体工厂对应一个具体产品 但有时候我们需要一个工厂能够提供多个产品对象 而不是单一的对象 这个时候我们就需要使用抽象工厂模式 在介绍抽象工厂模式前 我们先厘清两个概念 产品等级结构 产品等
  • Java与设计模式(3):抽象工厂模式

    一 定义 抽象工厂模式是一种创建型设计模式 它提供了一种将相关对象组合在一起创建的方式 而无需指定它们的具体类 在抽象工厂模式中 有一个抽象工厂接口 该接口定义了一组创建相关对象的方法 每个具体的工厂类都实现了这个接口 并负责创建一组相关的
  • 简单工厂模式(静态工厂方法模式)

    概述 简单工厂模式专门定义一个类来负责创建其他类的实例 被创建的实例通常都具有共同的父类 不是23种模式中的一种 是一种编码习惯 优点 1 工厂类含有必要的判断逻辑 可以决定在什么时候创建哪一个产品类的实例 客户端可以免除直接创建产品对象的
  • 设计模式--工厂模式--抽象工厂模式

    工厂模式属于创建型模式基本原理 使用一个工厂类统一生产各种产品 主要流程 1 创建产品的基类 便于统一返回创建的产品 2 创建各种产品 继承基类 注意多态 3 创建工厂类 对每种产品进行区分创建 4 在使用时要先实例化工厂类 在调用期内生产
  • 创建型设计模式之抽象工厂(Abstract Factory)模式

    定义 为创建一组相关或相互依赖的对象提供一个接口 而且无需指定他们的具体类 用意 客户端在不必指定产品的具体类型情况下 创建多个产品族中某个产品对象 定义图 参与者 抽象工厂 Creator 工厂方法核心 由一个接口或抽象类实现 具体工厂类
  • 设计模式---抽象工厂(AbstractFactory)模式

    1 名词解释 产品等级 指产品的类型一样 品牌不一样 例如空调是一种产品类型 美的空调与格力空调是不同的品牌 产品族 同一个品牌的不同产品 例如美的的空调 电饭锅 热水器属于同一产品族 这里引用一个图片来具体说明这两个名词解释 来自引用2
  • java设计模式——抽象工厂模式(Abstract Factory Pattern)

    抽象工厂模式产生的动机 为了更清晰地理解工厂方法模式 需要先引入两个概念 产品等级结构 产品等级结构即产品的继承结构 如一个抽象类是电视机 其子类有海尔电视机 海信电视机 TCL电视机 则抽象电视机与具体品牌的电视机之间构成了一个产品等级结
  • 2.Java设计模式-----抽象工厂模式(Abstract Factory Pattern)

    抽象工厂模式 Abstract Factory 是23种设计模式之一 抽象工厂模式是这样子定义的 抽象工厂模式 提供一个创建一系列相关或互相依赖对象的接口 而无需指定它们具体的类 在学习抽象工厂模式之前 最好熟悉简单工厂模式以及工厂方法模式
  • Gof23设计模式之工厂方法模式和抽象工厂模式

    在java中 万物皆对象 这些对象都需要创建 如果创建的时候直接new该对象 就会对该对象耦合严重 假如我们要更换对象 所有new对象的地方都需要修改一遍 这显然违背了软件设计的开闭原则 如果我们使用工厂来生产对象 我们就只和工厂打交道就可
  • C++设计模式之抽象工厂模式

    之前讲到了C 设计模式 工厂方法模式 我们可能会想到 后期产品会越来越多了 建立的工厂也会越来越多 工厂进行了增长 工厂变的凌乱而难于管理 而且由于工厂方法模式创建的对象都是继承于Product的 所以工厂方法模式中 每个工厂只能创建同一产
  • C++抽象工厂模式:Abstract Factory Pattern

    抽象工厂模式是工厂方法模式的升级版本 工厂方法模式只有一个抽象产品类 而抽象工厂模式有多个 工厂方法模式的具体工厂类只能创建一个具体产品类的实例 而抽象工厂模式可以创建多个 案例 在上一章节工厂方法模式的基础上 将披萨的各种原料生产抽象成一

随机推荐

  • Ubuntu下将rm命令替换为trash命令

    Ubuntu下将rm命令替换为trash命令 rm命令是一个很可怕的命令 xff0c 因为它不会给你后悔的机会 xff0c 删了就是删了 xff0c 再也找不回来了 xff08 据说能在lost 43 found里面恢复 xff0c 但是操
  • 正则表达式_排除特定字符/字符串

    正则表达式 排除特定字符 字符串 使用场景 xff1a 使用git add A指令提交一个文件夹中所有的代码文件 xff0c 忽略所有的可执行文件 抽象化 匹配一些字符串 xff0c 找出其中不含后缀 xff0c 即 的字符串 理解 排除特
  • 什么是操作系统?操作系统的定义、功能、特性

    什么是操作系统 xff1f 操作系统的定义 功能 特性 什么是操作系统 xff1f 首先 xff0c 计算机的资源可以分为硬件资源和软件资源 CPU 存储设备 各种类型的输入输出设备与外设等 xff0c 共同构成计算机的硬件资源 各种程序
  • 计算机网络第六课

    计算机网络第六课 奈式准则未考虑噪声 噪声 xff1a 模拟信号 gt 数字信号转换 信道复用技术 xff08 续 xff09 在单一物理通信线路上 xff0c 传输若干个独立的信号 三种信道复用技术 xff1a FDMTDMWDM TDM
  • libc_hidden_def、libc_hidden_weak、libc_hidden_proto

    libc hidden def libc hidden weak libc hidden proto 在阅读glibc源码的时候 xff0c 遇见了几个没见过的宏 xff0c 几乎所有的函数都会使用这几个宏 xff1a libc hidde
  • GLIBC源码——putchar

    GLIBC源码 putchar GLIBC源码 从我认为最简单的putchar开始 putchar放在putchar c中 xff0c 而putchar c放在libio文件夹里 加上注释 xff0c 一共只有36行 span class
  • 【汇编】正确使用IDIV指令

    汇编 正确使用IDIV指令 div为无符号除法 xff0c idiv为有符号除法 idiv进行的是128 64位除法 xff0c 即被除数为128位 除数为64位 64位操作系统中寄存器大小当然只有64位 xff0c 因此 xff0c id
  • 【acwj】04,An Actual Compiler 一个真正的编译器

    搬运自https github com DoctorWkt acwj xff0c 一个介绍如何使用C语言编写一个可自举的类C语言编译器的说明 进行了粗略的翻译 acwj 04 xff0c An Actual Compiler 一个真正的编译
  • 设计模式详解:工厂方法模式

    今天我们来看一下使用频率非常高的工厂方法模式 xff0c 看完原理分别给出 NET和JAVA两种语言的实现源码 定义 xff1a 工厂方法模式 xff1a 定义一个用于创建对象的接口 xff0c 但是 让子类决定将哪一个类实例化 工厂方法模
  • 【acwj】05,Statements 实现“Statements”

    搬运自https github com DoctorWkt acwj xff0c 一个介绍如何使用C语言编写一个可自举的类C语言编译器的说明 进行了粗略的翻译 acwj 05 xff0c Statements 实现 Statements I
  • diff命令实现

    diff命令实现 diff是类UNIX系统下的一个重要的系统工具 xff0c 用于比较两个文本文件的差异 它有三种输出格式 先给大家看看两个用于比对的文件原文 file1 a e b a g h b g g file2 b c d g e
  • verilog 常见位宽问题集合

    verilog 常见的位宽问题集合 1 位宽不等 wire b 31 0 assign b 61 5 39 b0 这种错误常见于赋值操作中 2 保留最低位 wire b assign b 61 32 39 h5 此时因为b缺省定义为1位长度
  • glibc源码阅读

    FBI warning 本文仅仅是试图以二进制选手的方式来理解mallo c中所使用的堆机制 xff0c 不会对具体操作以及堆块结构作过多叙述 xff0c 敬请谅解 水平欠佳 xff0c 有问题也欢迎留言指出 先解释一些常用的宏与常量 变量
  • github copilot插件安装

    首先是github copilot的官网地址 xff1a https copilot github com 现在要使用copilot首先要先通过申请才可以使用 xff0c 点击 Sign up 登录 xff0c 这里最好已经有github的
  • 操作系统第一章知识点小结

    第一章 操作系统概述 1 1操作系统的概念 xff0c 功能和目标 资源管理者 xff08 接下来的4给章节就是对这四个功能的详细学习 xff09 处理机处理 xff1a 处理机管理因为是为进程分配处理机资源 xff0c 也称为进程管理 存
  • SerDes基础知识

    SerDes是什么 SerDes是Serializer Deserializer 的缩写 xff0c 即串行器和解串器 xff0c 顾名思义是一种将并行数据转换成串行数据发送 xff0c 将接收的串行数据转换成并行数据的 器件 对于FPGA
  • 安装Pycharm

    文章目录 Ubuntu使用pycharm解压安装使用pycharmwindows 使用Pycharmpip install cryptography 报错 Ubuntu使用pycharm 官网地址 这里以Ubuntu1604 LTS 下载p
  • 找完数(用数组实现)

    找完数 所谓完数就是该数恰好等于除自身外的因子之和 例如 xff1a 6 61 1 43 2 43 3 xff0c 其中1 2 3为6的因子 本题要求编写程序 xff0c 找出任意两正整数m和n之间的所有完数 输入格式 xff1a 输入在一
  • Ubuntu系统使用图形化界面来创建一个用户

  • 设计模式详解:抽象工厂模式

    今天我们来看一下另一个使用频率非常高的抽象工厂模式 xff0c 看完原理分别给出 NET和JAVA两种语言的实现源码 定义 xff1a 抽象工厂模式 xff1a 提供一个 创建一系列相关或相互依赖对象的接口 xff0c 而无须指定它们具体的