zoukankan      html  css  js  c++  java
  • 設計模式具體應用

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

    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的项目中大量的使用了反射工厂取代的传统的工厂。

  • 相关阅读:
    设计模式之设计原则
    浅谈简单工厂模式和策略模式
    Flask-SQLAlchemy插件
    SQLAlchemy的ORM
    Flask 微博三方登录
    SQLAlchemy介绍和基本使用
    Flask常用的钩子函数
    Flask-Restful详解
    flask信号使用
    多线程爬取斗图图片
  • 原文地址:https://www.cnblogs.com/sdya/p/5261642.html
Copyright © 2011-2022 走看看