設計模式具體應用

Posted 学如逆水行舟,不进则退

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了設計模式具體應用相关的知识,希望对你有一定的参考价值。

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

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

  

调用代码: 

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

 

 现在我们要增加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.           
  6.         public static IUser CreateUser()  
  7.         {  
  8.             string className = AssemblyName + "." + db + "User";  
  9.             return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);  
  10.         }  
  11.   
  12.         public static IDepartment CreateDepartment()  
  13.         {  
  14.             string className = AssemblyName + "." + db + "Department";  
  15.             return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);  
  16.         }  
  17.     }  

 3.总结

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

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

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

以上是关于設計模式具體應用的主要内容,如果未能解决你的问题,请参考以下文章

常用的設計模式

藏書閣

問題排查:行動裝置網頁前端 UI 設計

java之策略模式

面向對象設計原則

Linux 的歷史