服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 详解C#的设计模式编程之抽象工厂模式的应用

详解C#的设计模式编程之抽象工厂模式的应用

2021-11-12 15:17张龙豪 C#

这篇文章主要介绍了C#的设计模式编程之抽象工厂模式的应用,注意区分一下简单工厂模式、工厂方法模式和抽象工厂模式概念之间的区别,需要的朋友可以参考下

这里首先以一个生活中抽象工厂的例子来实现一个抽象工厂,然后再给出抽象工厂的定义和UML图来帮助大家更好地掌握抽象工厂模式,同时大家在理解的时候,可以对照抽象工厂生活中例子的实现和它的定义来加深抽象工厂的UML图理解。抽象工厂模式比其它工厂模式更加抽象,抽象工厂模式适用与多个抽象类的情况下,通过工厂返回多个抽象类中你需要得到的具体子类实例。

抽象工厂模式比其它工厂模式更加抽象,抽象工厂模式适用与多个抽象类的情况下,通过工厂返回多个抽象类中你需要得到的具体子类实例。

举例阐述抽象工厂模式:
假如中国对邪恶国家开战。

中国装备:炸弹类,坦克类,来消灭邪恶国家。

炸弹类:导弹,核弹;

坦克类:越野车,主站坦克;

战略:

前期中国兵工厂生产:导弹,越野车,打击邪恶国家。

后期中国兵工厂生产:核弹,主站坦克,毁灭邪恶国家。

类图:

详解C#的设计模式编程之抽象工厂模式的应用

装备类代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#region 炸弹系列
abstract class Bomb
{
  abstract public void baozha();
}
/// <summary>
/// 导弹
/// </summary>
class daodanBomb :Bomb
{
  public override void baozha()
  {
    Console.WriteLine("我是一颗中国造导弹,来轰炸不老实的小邪恶国家!");
  }
}
/// <summary>
/// 核弹
/// </summary>
class hedanBomb : Bomb
{
  public override void baozha()
  {
    Console.WriteLine("我是一颗中国造核弹,来轰炸不老实的小邪恶国家!");
  }
}
#endregion
 
#region 坦克系列
abstract class Tank
{
  abstract public void go();
}
/// <summary>
/// 越野车
/// </summary>
class yueyeTank : Tank
{
  public override void go()
  {
    Console.WriteLine("我是一颗中国造越野车,来踏平不老实的小邪恶国家!");
  }
}
/// <summary>
/// 主站坦克
/// </summary>
class zhuzhanTank : Tank
{
  public override void go()
  {
    Console.WriteLine("我是一颗中国造主站坦克,来踏平不老实的小邪恶国家!");
  }
}
#endregion工厂类代码
 
 
#region 中国兵工厂
abstract class chinaFactory
{
  //装甲车制造车间
  public abstract Tank CreateTank();
  //炸弹知道车间
  public abstract Bomb CreateBomb();
}
//兵工厂前期制造
class qianqiFactory : chinaFactory
{  
  public override Bomb CreateBomb()
  {
    //导弹
    return new daodanBomb();
  }
  public override Tank CreateTank()
  {
    //越野车
    return new yueyeTank();
  }
}
//兵工厂后期制造
class houqiFactory : chinaFactory
{
  public override Bomb CreateBomb()
  {
    //核弹
    return new hedanBomb();
  }
  public override Tank CreateTank()
  {
    //主站坦克
    return new zhuzhanTank();
  }
}
#endregion客户端代码:(打仗)
 
 
// 备战
class Make
{
  //装备
  private Bomb bomb;
  private Tank tank;
  //制造加工
  public Make(chinaFactory factory)
  {
    bomb = factory.CreateBomb();
    tank = factory.CreateTank();
  }
 
  //开始打仗
  public void warStar()
  {
    //炸弹类爆炸
    bomb.baozha();
    //战车类前进
    tank.go();
  }
 
}
public class start
{
  public static void Main()
  {
    //大战前期
    chinaFactory qianqiMake = new qianqiFactory();
    Make qianqi = new Make(qianqiMake);
    qianqi.warStar();
 
    //点任意键,进行后期攻势!!
    Console.ReadKey();
 
    //大战后期
    chinaFactory houqiMake = new houqiFactory();
    Make houqi = new Make(houqiMake);
    houqi.warStar();
 
    Console.WriteLine("钓鱼岛是中国的,神圣不可侵犯!小邪恶国家,滚开!!");
    Console.ReadLine();
  }
}

 

抽象工厂模式的定义和类图

抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。下面通过抽象工模式的类图来了解各个类中之间的关系:

详解C#的设计模式编程之抽象工厂模式的应用

抽象工厂的分析
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):

抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

知道了抽象工厂的优缺点之后,也就能很好地把握什么情况下考虑使用抽象工厂模式了,下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:

一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
这个系统有多个系列产品,而系统中只消费其中某一系列产品
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。


.NET中抽象工厂模式实现
抽象工厂模式在实际中的应用也是相当频繁的,然而在我们.NET类库中也存在应用抽象工厂模式的类,这个类就是System.Data.Common.DbProviderFactory,这个类位于System.Data.dll程序集中,该类扮演抽象工厂模式中抽象工厂的角色,我们可以用reflector反编译工具查看该类的实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/// 扮演抽象工厂的角色
/// 创建连接数据库时所需要的对象集合,
/// 这个对象集合包括有 DbConnection对象(这个是抽象产品类,如绝味例子中的YaBo类)、DbCommand类、DbDataAdapter类,针对不同的具体工厂都需要实现该抽象类中方法,
public abstract class DbProviderFactory
{
  // 提供了创建具体产品的接口方法
  protected DbProviderFactory();
  public virtual DbCommand CreateCommand();
  public virtual DbCommandBuilder CreateCommandBuilder();
  public virtual DbConnection CreateConnection();
  public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();
  public virtual DbDataAdapter CreateDataAdapter();
  public virtual DbDataSourceEnumerator CreateDataSourceEnumerator();
  public virtual DbParameter CreateParameter();
  public virtual CodeAccessPermission CreatePermission(PermissionState state);
}
DbProviderFactory类是一个抽象工厂类,该类提供了创建数据库连接时所需要的对象集合的接口,实际创建的工作在其子类工厂中进行,微软使用的是SQL Server数据库,因此提供了连接SQL Server数据的具体工厂实现,具体代码可以用反编译工具查看,具体代码如下:
 
/// 扮演着具体工厂的角色,用来创建连接SQL Server数据所需要的对象
public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider
{
  // Fields
  public static readonly SqlClientFactory Instance = new SqlClientFactory();
  // 构造函数
  private SqlClientFactory()
  {
  }
      
  // 重写抽象工厂中的方法
  public override DbCommand CreateCommand()
  { // 创建具体产品
    return new SqlCommand();
  }
  public override DbCommandBuilder CreateCommandBuilder()
  {
    return new SqlCommandBuilder();
  }
  public override DbConnection CreateConnection()
  {
    return new SqlConnection();
  }
  public override DbConnectionStringBuilder CreateConnectionStringBuilder()
  {
    return new SqlConnectionStringBuilder();
  }
  public override DbDataAdapter CreateDataAdapter()
  {
    return new SqlDataAdapter();
  }
  public override DbDataSourceEnumerator CreateDataSourceEnumerator()
  {
    return SqlDataSourceEnumerator.Instance;
  }
  public override DbParameter CreateParameter()
  {
    return new SqlParameter();
  }
  public override CodeAccessPermission CreatePermission(PermissionState state)
  {
    return new SqlClientPermission(state);
  }
}

因为微软只给出了连接SQL Server的具体工厂的实现,我们也可以自定义连接Oracle、MySql的具体工厂的实现。

延伸 · 阅读

精彩推荐
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21