設計模式具體應用

大话设计模式中的利用反射加抽象工厂的数据访问程序。先来看看反射技术的基本格式:--反射工廠

Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”);

只要在程序顶端写上using System.Reflection来引用Reflection,就可以采用反射工厂来克服抽象工厂模式的先天不足。下面我们来看通过反射技术实现不同数据库的访问程序.

DataAccess类,用反射技术,取代了抽象工厂中的IFactory,SqlServerFactory和AccessFactory。
    具体代码:

C#代码

  1. public class User
  2. {
  3. private int _id;
  4. public int ID
  5. {
  6. get { return _id; }
  7. set { _id = value; }
  8. }
  9. private string _name;
  10. public string Name
  11. {
  12. get { return _name; }
  13. set { _name = value; }
  14. }
  15. }
  16. public class Department
  17. {
  18. private int _id;
  19. public int ID
  20. {
  21. get { return _id; }
  22. set { _id = value; }
  23. }
  24. private string _deptName;
  25. public string DeptName
  26. {
  27. get { return _deptName; }
  28. set { _deptName = value; }
  29. }
  30. }
  31. public interface IUser
  32. {
  33. void Insert(User user);
  34. User GetUser(int id);
  35. }
  36. public class SqlserverUser : IUser
  37. {
  38. public void Insert(User user)
  39. {
  40. Console.WriteLine("在Sqlserver中给User表增加一条记录");
  41. }
  42. public User GetUser(int id)
  43. {
  44. Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
  45. return null;
  46. }
  47. }
  48. public class AccessUser : IUser
  49. {
  50. public void Insert(User user)
  51. {
  52. Console.WriteLine("在Access中给User表增加一条记录");
  53. }
  54. public User GetUser(int id)
  55. {
  56. Console.WriteLine("在Access中根据ID得到User表一条记录");
  57. return null;
  58. }
  59. }
  60. public interface IDepartment
  61. {
  62. void Insert(Department department);
  63. Department GetDepartment(int id);
  64. }
  65. public class SqlserverDepartment : IDepartment
  66. {
  67. public void Insert(Department department)
  68. {
  69. Console.WriteLine("在Sqlserver中给Department表增加一条记录");
  70. }
  71. public Department GetDepartment(int id)
  72. {
  73. Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
  74. return null;
  75. }
  76. }
  77. public class AccessDepartment : IDepartment
  78. {
  79. public void Insert(Department department)
  80. {
  81. Console.WriteLine("在Access中给Department表增加一条记录");
  82. }
  83. public Department GetDepartment(int id)
  84. {
  85. Console.WriteLine("在Access中根据ID得到Department表一条记录");
  86. return null;
  87. }
  88. }
  89. public class DataAccess
  90. {
  91. private static readonly string AssemblyName = "抽象工厂模式";
  92. private static readonly string db = "Sqlserver";
  93. //private static readonly string db = "Access";
  94. public static IUser CreateUser()
  95. {
  96. string className = AssemblyName + "." + db + "User";
  97. return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
  98. }
  99. public static IDepartment CreateDepartment()
  100. {
  101. string className = AssemblyName + "." + db + "Department";
  102. return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
  103. }
  104. }

调用代码:

C#代码

  1. User user = new User();
  2. Department dept = new Department();
  3. IUser iu = DataAccess.CreateUser();
  4. iu.Insert(user);
  5. iu.GetUser(1);
  6. IDepartment id = DataAccess.CreateDepartment();
  7. id.Insert(dept);
  8. id.GetDepartment(1);
  9. Console.Read();
  10. }

现在我们要增加Oracle数据访问,相关类的增加是不可避免的,这点是无论我们用什么方法都解决不了的,这是扩展,依照开发-封闭原则,对于扩展,我们开放,但对与修改我们关闭。就现在的代码中,我们要换Oracle很容易,只需将db=”Sqlserver”换成db=”Oracle”。
    现在我们需要增加Product,只需增加三个与Product相关的类,再修改一下DataAccess,在其中增加一个创建Product的方法就可以了。
    现在我们要更换数据访问程序是,我们还需要修改程序,重新编译,我们可以利用配置文件来解决这个问题,首先要在我们的项目中添加config文件,内容如下:

C#代码

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <appSettings>
  4. <add key="DB" value="Sqlserver"/>
  5. </appSettings>
  6. </configuration>

再在项目中引用System.configuration,并在程序头增加using System.configuration;, 然后修改DataAccess类的字段db的赋值代码:

C#代码

  1. class DataAccess
  2. {
  3. private static readonly string AssemblyName = "抽象工厂模式";
  4. private static readonly string db = ConfigurationManager.AppSettings["DB"];
  5. public static IUser CreateUser()
  6. {
  7. string className = AssemblyName + "." + db + "User";
  8. return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
  9. }
  10. public static IDepartment CreateDepartment()
  11. {
  12. string className = AssemblyName + "." + db + "Department";
  13. return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
  14. }
  15. }

3.总结

使用反射工厂的优点是极大的减少了工厂类的数量,降低了代码的冗余,并且系统更容易扩展,增加新类型后,不需要修改工厂类。

使用反射工厂的代价是工厂与产品之间的依赖关系不明显,由于动态绑定,因此理论上可以用一个工厂完成很多类型的实例化,从而使得代码不容易理解。另外就是增加了测试难度,因为创建是动态完成的。

采用反射技术创建的反射工厂可以使系统更灵活,使工厂和产品之间的依赖关系更小。在.NET的项目中大量的使用了反射工厂取代的传统的工厂。

时间: 2024-08-14 15:11:38

設計模式具體應用的相关文章

實戰設計模式之工厂方法模式

對於http請求原理的朋友應該了解IIS上後綴映射 /*当我们请求一个*.aspx的文件时,此时会映射到System.Web.UI.PageHandlerFactory类上进行处理,而对*.ashx的请求将映射到System.Web.UI.SimpleHandlerFactory类中(这两个类都是继承于IHttpHandlerFactory接口的)*/ 下面用一線圖來直觀的看一下 圖引用:http://www.cnblogs.com/zhili/p/FactoryMethod.html 為了更直

[設計模式].01.簡單工廠模式

用戶接口 1 //定義一個用戶該有的操作 2 public interface IUser 3 { 4 bool Login(string userName, string psw); 5 bool Login(); 6 bool Exsit(); 7 } 用戶抽象類 1 //定義一個抽象類,讓它去實現IUser接口 2 //編寫每個要User類需要執行的操作,如登錄信息記錄到日志,修飾符定義為可重寫virtual 3 public abstract class User : IUser 4 {

設計模式--抽象工廠模式

抽象工廠用例圖 代碼 class Program { static void Main(string[] args) { User user = new User(); Department dept = new Department(); IUser iu = DataAccess.CreateUser(); iu.Insert(user); iu.GetUser(1); IDepartment id = DataAccess.CreateDepartment(); id.Insert(dep

常用的設計模式

设计模式是软件开发讨论中,亘古不变的话题,今天又拿出来说道两句,也是对设计模式的一个复习吧. 工厂方法模式 工厂方法模型定义了一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到了其子类中.工厂方法模式是优化的简单工厂模式,它很好的支持了“开闭原则”.每一个具体的工厂只能构建一个类的对象.具体工厂类与产品类是一对一的关系. [csharp] view plain copy print? /// <summary> /// 抽象产品类 /// </summary

設計模式觀察者模式

觀察者用例圖 代碼 class Program { static void Main(string[] args) { ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, "X")); s.Attach(new ConcreteObserver(s, "Y")); s.Attach(new ConcreteObserver(s, "Z")); s.

VR廣告設計與商業

<VR廣告設計與商業>培訓營 課程 By 高煥堂/台灣VR產業聯盟 主席  2016.11月 在Buy+購物的浪潮下,<VR廣告製作>也水漲船高,歡迎您一起來學習VR廣告製作技術. 進入無框世界 我們知道,傳統多媒體大多給觀眾圈定了一個"框",例如TV建構了一個有框世界,讓人們從框外觀看框裡的節目.而VR技術則打破了傳統螢幕的"框",引導人們進入螢幕的框內,給予一個完整的世界.在廣告方面,從"有框"到"無框&qu

通過數據了解用戶——數據在新品設計中的應用

通常情況下,我們可以通過用戶訪談的方法了解用戶需求,其實設計師還可以通過分析用戶問卷調查數據以及網站頁面數據等方式,了解用戶需求以及用戶在使用產品時遇到的問題. 而且,直接通過接觸用戶了解到的需求有可能只是個案,為了增強客觀性,通常都會通過大樣本調查,從數據實證的角度,進一步更準確和客觀地找到用戶的普遍需求. 此外,通過對數據分析結果與用戶訪談所得到的定性分析結論,進行比較和綜合分析,設計師也能夠從不同的角度了解用戶的真實需求. 從用研的角度來看,交互設計包括新產品設計以及已有產品的改版設計兩大

這個日曆戳一下,一天就往時了|這個設計了不得

俺們每日都為你舉薦幾個最近察覺的好設計.「這個設計了不得」的微信市民號上線啦,直爽搜new balance 580查「BestDesign」或者「Qthings」就能夠訂閱,留意俺們每天發覺的新奇好設計.Buzzifloat by Alain Gilles更少的原料體現著未有足夠的安閒度?在吉布提科隆國外工作家倶及裝備展( ORGATEC )上,盧旺達設計師 Alain Gilles 用為家私企業 BuzziSpace 所設計的極簡風座椅 Buzzifloat 給出了否認的解答.座椅的設計靈性出

UDP 網路程式設計 (1) --- Getting Started

在大部份的網路應用裡,TCP 似乎比 UDP 來的多許多,程式人員通常也是對撰寫 TCP 程式比較熟悉,這裡將整理一些 UDP 程式設計的說明,希望對大家有幫助. 一開始先介紹三個最重要的類別,如下: DatagramPacket: UDP 的封包. DatagramSocket: 用來建立 UDP socket 的類別,包含 client 及 server. MulticastSocket: 用來建立群播 UDP socket 的類別,包含 client 和 server. 第一個程式,先寫個