设计模式成长记(一) 抽象工厂模式(Abstract Factory)
时间:2022-05-06
本文章向大家介绍设计模式成长记(一) 抽象工厂模式(Abstract Factory),主要内容包括目录、定义、UML类图、参与者、编写代码、特点、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
目录
- 定义
- UML类图
- 参与者
- 编写代码
- 特点
定义
提供一个创建一系列相关或相互依赖的对象的接口,而无需指定具体的类。
使用频率:
UML类图
参与者
AbstractFactory:声明一个创建抽象产品的的接口。
ConcreteFactory:实现接口创建具体的产品对象。
AbstractProduct:产品的抽象。
Product:具体的产品,实现抽象产品的接口。
Client:使用抽象工厂和抽象产品。
编写代码
1.新建控制台程序AbstractFactory,新增Abstract.cs类文件
using System;
/// <summary>
/// 抽象工程模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定具体的类。
/// </summary>
namespace AbstractFactory
{
/// <summary>
/// 抽象产品A
/// </summary>
public abstract class AbstractProductA
{
public abstract void SayHello();
}
/// <summary>
/// 抽象产品B
/// </summary>
public abstract class AbstractProductB
{
public abstract void SayHello();
}
/// <summary>
/// 具体产品A1
/// </summary>
public class ProductA1 : AbstractProductA
{
public override void SayHello()
{
Console.WriteLine("Hello,我是具体产品A1");
}
}
/// <summary>
/// 具体产品A2
/// </summary>
public class ProductA2 : AbstractProductA
{
public override void SayHello()
{
Console.WriteLine("Hello,我是具体产品A2");
}
}
/// <summary>
/// 具体产品B1
/// </summary>
public class ProductB1 : AbstractProductB
{
public override void SayHello()
{
Console.WriteLine("Hello,我是具体产品B1");
}
}
/// <summary>
/// 具体产品B2
/// </summary>
public class ProductB2 : AbstractProductB
{
public override void SayHello()
{
Console.WriteLine("Hello,我是具体产品B2");
}
}
/// <summary>
/// 抽象工厂:提供创建抽象产品的接口
/// </summary>
public abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
/// <summary>
/// 具体工厂:实现抽象工厂创建产品的接口
/// </summary>
public class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
public class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
public class Client
{
private AbstractProductA _productA;
private AbstractProductB _productB;
public Client(AbstractFactory factory)
{
_productA = factory.CreateProductA();
_productB = factory.CreateProductB();
}
public void Run()
{
_productA.SayHello();
_productB.SayHello();
}
}
}
2.编写Program.cs
using System;
namespace AbstractFactory
{
class Program
{
static void Main(string[] args)
{
//使用工厂1
AbstractFactory factory = new ConcreteFactory1();
Client client = new Client(factory);//依赖注入
client.Run();
Console.WriteLine();
//使用工厂2
factory = new ConcreteFactory2();
client = new Client(factory);
client.Run();
Console.Read();
}
}
}
3.输出结果
特点
1) 分离了具体的类
Abstract Factory 模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。客户通过它们的抽象接口操纵实例。产品的类名也在具体工厂的实现中被分离;它们不出现在客户代码中。
2) 使得易于交换产品系列 一个具体工厂类在一个应用中仅出现一次—即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。
3) 有利于产品的一致性
当一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要。而AbstractFactory很容易实现这一点。
4) 难以支持新种类的产品
难以扩展抽象工厂以生产新种类的产品,这是因为AbstractFactory接口确定了可以被创建的产品集合。 支持新种类的产品就需要扩展该工厂接口,这将涉及 AbstractFactory类及其所有子类的改变。
- GridView控件使用经验
- WordPress登陆文件wp-login.php添加相关参数,安全有保障
- WordPress在RSS Feed 中输出自定义特色图像(缩略图)
- 单拼域名can.com以高达99.2万元成交!
- CI学习 CCNET Config 第一天
- IBatisNet基础组件
- 学习altas笔记[客户端JS和Altas环境初始化关系和DataTable返回数据的客户端处理]
- 在Windows 8 Hyper-V下的安装CentOS 6和SSH配置
- WordPress RSS Feed 优化/设置技巧六则
- SourceTree 基本介绍
- 学习Altas 笔记[JS简单调用服务端方法]
- 使用WinSCP软件在windows和Linux中进行文件传输
- 线程安全的Generic Dictionary
- Python 项目实践三(Web应用程序)第五篇
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 太刺激了,面试官让我手写跳表,而我用两种实现方式吊打了TA!
- 被 Google 选择的下一代数据面 Cilium 是什么 - 上手实践
- K8S 生态周报| 是时候从 k8s v1.16 升级了
- ESP8266(一)| 基于OneNet的温度采集显示系统
- 隐秘的 MySQL 类型转换
- 对Jenkinsfile语法说不,开源项目Jenkins Json Build挺你
- Volatile概述
- SparkStreaming和Kafka基于Direct Approach如何管理offset
- Spark在处理数据的时候,会将数据都加载到内存再做处理吗?
- 美团点评2020年测试工程师笔试题
- Pytest之重运行及生成测试报告
- 一条SQL的奇妙旅行
- 表格的融合
- 解放双手,使用批处理达到账号密码之类再也用不着手动输入!
- 教你在几分钟内构建一个Python包