您的位置:首页 > 其它

設計模式具體應用

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

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

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

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

C#代码

public class User

{

private int _id;

public int ID

{

get { return _id; }

set { _id = value; }

}

private string _name;

public string Name

{

get { return _name; }

set { _name = value; }

}

}

public class Department

{

private int _id;

public int ID

{

get { return _id; }

set { _id = value; }

}

private string _deptName;

public string DeptName

{

get { return _deptName; }

set { _deptName = value; }

}

}

public interface IUser

{

void Insert(User user);

User GetUser(int id);

}

public class SqlserverUser : IUser

{

public void Insert(User user)

{

Console.WriteLine("在Sqlserver中给User表增加一条记录");

}

public User GetUser(int id)

{

Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");

return null;

}

}

public class AccessUser : IUser

{

public void Insert(User user)

{

Console.WriteLine("在Access中给User表增加一条记录");

}

public User GetUser(int id)

{

Console.WriteLine("在Access中根据ID得到User表一条记录");

return null;

}

}

public interface IDepartment

{

void Insert(Department department);

Department GetDepartment(int id);

}

public class SqlserverDepartment : IDepartment

{

public void Insert(Department department)

{

Console.WriteLine("在Sqlserver中给Department表增加一条记录");

}

public Department GetDepartment(int id)

{

Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");

return null;

}

}

public class AccessDepartment : IDepartment

{

public void Insert(Department department)

{

Console.WriteLine("在Access中给Department表增加一条记录");

}

public Department GetDepartment(int id)

{

Console.WriteLine("在Access中根据ID得到Department表一条记录");

return null;

}

}

public class DataAccess

{

private static readonly string AssemblyName = "抽象工厂模式";

private static readonly string db = "Sqlserver";

//private static readonly string db = "Access";

public static IUser CreateUser()

{

string className = AssemblyName + "." + db + "User";

return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);

}

public static IDepartment CreateDepartment()

{

string className = AssemblyName + "." + db + "Department";

return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);

}

}

调用代码:

C#代码

User user = new User();

Department dept = new Department();

IUser iu = DataAccess.CreateUser();

iu.Insert(user);

iu.GetUser(1);

IDepartment id = DataAccess.CreateDepartment();

id.Insert(dept);

id.GetDepartment(1);

Console.Read();

}

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

C#代码

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<appSettings>

<add key="DB" value="Sqlserver"/>

</appSettings>

</configuration>

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

C#代码

class DataAccess

{

private static readonly string AssemblyName = "抽象工厂模式";

private static readonly string db = ConfigurationManager.AppSettings["DB"];

public static IUser CreateUser()

{

string className = AssemblyName + "." + db + "User";

return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);

}

public static IDepartment CreateDepartment()

{

string className = AssemblyName + "." + db + "Department";

return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);

}

}

3.总结

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

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

采用反射技术创建的反射工厂可以使系统更灵活,使工厂和产品之间的依赖关系更小。在.NET的项目中大量的使用了反射工厂取代的传统的工厂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: