【设计模式】抽象工厂(Abstract Factory)模式

谁借莪1个温暖的怀抱¢ 2023-03-13 03:27 129阅读 0赞
  • 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
  • 定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
  • 为了方便引进抽象工厂模式引进一个新概念:产品族(Product Family)。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。
    在这里插入图片描述
    图中一共有四个产品族,分布于三个不同的等级结构中。只要指明一个产品所处的产品族一集它所属的等级结构中就可以为以确定这个产品。

引进抽象工厂格式

所谓的抽象工厂是指一个工厂等级结构可以常见出分属于不同产品等级结构的一个产品族中的所有对象。如下图:
在这里插入图片描述

抽象工厂产品结构图

在这里插入图片描述

  • 抽象工厂(Abstract Factory)角色担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
  • 具体工厂(Concrete Factory)角色这个角色直接在客户端调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,二这个逻辑是与应用系统的商业逻辑紧密相关的。
  • 抽象产品(Abstract Product)角色担任这个角色的类是工厂方法模式所创建的对象的父类,或他们共同拥有的接口。
  • 具体产品(Concrete Product)角色抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

使用抽象工厂模式的情形

  • 希望一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节时。
  • 一个系统有多于一个的产品族,而系统只消费其中某一个产品族。

AbstractFactory模式和Factory模式的区别

  • AbstractFactory模式是为了常见一组(有多类)相关或依赖的对象提供创建接口。
  • Factory模式是为一类对象提供创建接口。

优缺点

  • “开放——封闭”原则要求系统对扩展开放,对修改封闭。通过扩展达到增强功能的目的。对于涉及到多个产品族与多个产品等级结构的系统其功能增加包括两个方面:
    增加产品族:Abstract Factory很好的支持了“开放——封闭”原则。
    增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持“开放——封闭”原则。
  • 抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品组的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。

本质

选择产品族的实现。

用反射+抽象工厂的数据访问程序

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。聚义含义:

  • 当某个角色需要另一个角色的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。
  • 在“依赖注入”里,创建被调用者的工作不再由调用者来完成,因此成为控制反转;创建被调用者实例的工作通常由loc容器来完成,然后注入调用者,因此也称为依赖注入。

Java中的反射

  • Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class内部信息。
  • Java反射相关的API在包java.lang.reflect中。

常用类和接口

  • Member接口:可以获取有关类成员(域或者方法)后者构造函数的信息。
  • Array类:提供动态地生成和访问Java数组方法。
  • Constructor类:提供一个类的构造函数的信息以及访问类的构造函数的接口。
  • Field类:提供一个类的域的信息以及访问类的域的接口。
  • Method类:提供一个类的方法的信息以及访问类的方法的接口。

举个例子

访问数据库。通过不同的数据库格式访问数据库。
【代码】

  1. using System;
  2. using System.Configuration;
  3. using System.Reflection;
  4. namespace DataBase_AbstractFactory
  5. {
  6. //User表
  7. class User
  8. {
  9. private int id;
  10. public int ID
  11. {
  12. get { return id;}
  13. set { id = value; }
  14. }
  15. private string name;
  16. public string Name
  17. {
  18. get { return name; }
  19. set { name = value; }
  20. }
  21. }
  22. //User表类型接口
  23. interface IUser
  24. {
  25. public void Insert(User user);
  26. public User GetUser(int id);
  27. }
  28. //SqlServer实现user表
  29. class SqlServerUser : IUser
  30. {
  31. public User GetUser(int id)
  32. {
  33. Console.WriteLine("在SqlServer中根据ID得到User表的一条记录。");
  34. return null;
  35. }
  36. public void Insert(User user)
  37. {
  38. Console.WriteLine("在SqlServer中给User表增加一条记录。");
  39. }
  40. }
  41. //Access实现User表
  42. class AccessUser : IUser
  43. {
  44. public User GetUser(int id)
  45. {
  46. Console.WriteLine("在Access中根据ID得到User表的一条记录。");
  47. return null;
  48. }
  49. public void Insert(User user)
  50. {
  51. Console.WriteLine("在Access中给User表增加一条记录。");
  52. }
  53. }
  54. //Department表
  55. class Department
  56. {
  57. private int id;
  58. public int ID
  59. {
  60. get { return id; }
  61. set { id = value; }
  62. }
  63. private string deptname;
  64. public string DeptName
  65. {
  66. get { return deptname; }
  67. set { deptname = value; }
  68. }
  69. }
  70. //Department表类型接口
  71. interface IDepartment
  72. {
  73. void Insert(Department department);
  74. Department GetDepartment(int id);
  75. }
  76. //SqlServer实现Department
  77. class SqlServerDepartment : IDepartment
  78. {
  79. public Department GetDepartment(int id)
  80. {
  81. Console.WriteLine("在SqlServer中根据ID得到Department表的一条记录。");
  82. return null;
  83. }
  84. public void Insert(Department department)
  85. {
  86. Console.WriteLine("在SqlServer中给Department表增加一条记录。");
  87. }
  88. }
  89. class AccessDepartment : IDepartment
  90. {
  91. public Department GetDepartment(int id)
  92. {
  93. Console.WriteLine("在Access中根据ID得到Department表的一条记录。");
  94. return null;
  95. }
  96. public void Insert(Department department)
  97. {
  98. Console.WriteLine("在Access中给User表增加一条记录。");
  99. }
  100. }
  101. //数据库工厂
  102. class DataAccess
  103. {
  104. private static string AssemblyName = "DataBase_AbstractFactory";
  105. private static string db = ConfigurationManager.AppSettings["DB"];
  106. public static IUser CreateUser()
  107. {
  108. string classname = AssemblyName + "." + db + "User";
  109. return (IUser)Assembly.Load(AssemblyName).CreateInstance(classname);
  110. }
  111. public static IDepartment CreateDepartment()
  112. {
  113. string classname = AssemblyName + "." + db + "Department";
  114. return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(classname);
  115. }
  116. }
  117. class Program
  118. {
  119. static void Main(string[] args)
  120. {
  121. User user = new User();
  122. Department dept = new Department();
  123. IUser iu = DataAccess.CreateUser();
  124. iu.Insert(user);
  125. iu.GetUser(1);
  126. IDepartment idept = DataAccess.CreateDepartment();
  127. idept.Insert(dept);
  128. idept.GetDepartment(1);
  129. Console.Read();
  130. }
  131. }
  132. }

【UML图】
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,129人围观)

还没有评论,来说两句吧...

相关阅读

    相关 抽象工厂模式(Abstract Factory)

    在上一篇的工厂方法模式中,通过一个公用的类对其他具有相同特性(实现相同接口或继承同一父类)的类的对象进行创建。随之带来的问题在于:当新定义了一个具有相同特性的类时,需要修改工厂