- 浏览: 127380 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
hulibo:
太简单了 没参考价值
网上商城的数据库设计 -
lfc:
[img][/img][url][/url][flash= ...
Petshop 4.0 详细解释 -
早上好朋友:
引用
自学MVC(十):自己写的通用的JS分页控件-2009年05月27日 -
早上好朋友:
[flash=200,200][/flash][url][/u ...
自学MVC(十):自己写的通用的JS分页控件-2009年05月27日 -
银杏树:
参考一下。
网上商城的数据库设计
1. 简述
通过前面的学习,我们以传统的方式实现了简单工厂,工厂方法和抽象工厂,但是有些场合下如此处理,代码会变得冗余并且难以维护。假设我们要创建交通工具。可以是汽车,火车,轮船等,其结构如下:
我们可以采用简单工厂,通过参数指示创建所需要的对象类型。如果要增加子类,例如卡车和轿车,则必须增加参数和相应的代码。如果子类层次过多,则会是程序变得很难维护。
但我们可以采用工厂方法模式来实现,即定义一个产生交通工具的接口,然后在子类中实现创建具体子类。代码如下:
public interface ICreateVehicle { Vehicle CreateCehicle(); } public abstract class Vehicle { } public class Car:Vehicle { public Car() { Console.WriteLine("创建了一个Car"); } } public class Boat:Vehicle { public Boat() { Console.WriteLine("创建了一个Boat"); } } public class CreateCar:ICreateVehicle { ICreateVehicle 成员#region ICreateVehicle 成员 public Vehicle CreateCehicle() { Vehicle vehicle=new Car(); return vehicle; } #endregion } public class CreateBoat:ICreateVehicle { ICreateVehicle 成员#region ICreateVehicle 成员 public Vehicle CreateCehicle() { Vehicle vehicle = new Boat(); Console.WriteLine("Car"); return vehicle; } #endregion }
这就是工厂方法。如果希望增加新的交通工具,不仅需要实现交通工具接口,还需要实现生产交通工具的工厂方法。
显然我们需要几十种交通工具,则需要几十个具体的工厂。而这些类的区别仅仅是返回相对应的类的实例,所以位维护带来了很大的麻烦。如果需要在接口中增加一个带参数的方法,则所有的子类都需要修改。
在这种场合下,采用抽象工厂与工厂方法没有区别,因为这里并不涉及产品线,抽象工厂并不能解决其中的问题,如果每种交通工具都要有对应的车站,则要使用抽象工厂,但是将会跟复杂。
有没有可能将需要创建类的类型传递到工厂方法中,由工厂方法根据类型返回相应的实例?解决这个问题的关键是需要动态的决定需要创建的类,这不是设计模式能解决的问题,属于软件平台的功能范畴。.NET可以提供反射技术。
我们先看通过反射技术实现的简化的工厂,代码如下:
public class CreateVehicleByType:ICreateVehicle
{
ICreateVehicle 成员#region ICreateVehicle 成员
private Type VehicleTYpe;
public CreateVehicleByType(string strType)
{
Type t = Type.GetType(strType);
VehicleTYpe = t;
}
public Vehicle CreateCehicle()
{
ConstructorInfo objConstrutor = VehicleTYpe.GetConstructor(System.Type.EmptyTypes);
Vehicle c = (Vehicle)objConstrutor.Invoke(null);
return c;
}
#endregion
}
在使用是,只要在创建时带入需要创建的类的类型:
static void Main(string[] args)
{
string strType = "Car";
Vehicle v;
ICreateVehicle f = null;
if (strType == "Car")
{
f = new CreateVehicleByType("FactoryVehicle.Car");
}
else if (strType == "Boat")
{
f = new CreateVehicleByType("Boat");
}
v = f.CreateCehicle();
Console.ReadLine();
}
通过反射技术,我们将很多的具体的工厂类简化为一个类,并且新增加类型时不需要新的工厂类,这样我们得到简化的工厂,可以称其为“反射工厂”。
2.实例
先来看看,大话设计模式中的利用反射加抽象工厂的数据访问程序。先来看看反射技术的基本格式:
Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”);
只要在程序顶端写上using System.Reflection来引用Reflection,就可以采用反射工厂来克服抽象工厂模式的先天不足。下面我们来看通过反射技术实现不同数据库的访问程序.
先来看结构图:
DataAccess类,用反射技术,取代了抽象工厂中的IFactory,SqlServerFactory和AccessFactory。
具体代码:
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); } }
调用代码:
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文件,内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DB" value="Sqlserver"/>
</appSettings>
</configuration>
再在项目中引用System.configuration,并在程序头增加using System.configuration;, 然后修改DataAccess类的字段db的赋值代码:
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的项目中大量的使用了反射工厂取代的传统的工厂。
发表评论
-
webservice的几种调用方法
2009-10-10 17:35 1246一、WebService在cs后台程序中的调用 ... -
我是如何学习设计模式的十:工厂模式-这个是我花的心思最多的
2009-10-09 10:39 1070工厂模式 为什么会出 ... -
Asp.net ViewState
2009-08-27 14:20 1350ASP.NET中的ViewState ViewSta ... -
Stack,Queue,SortedList
2009-08-04 15:23 896using System; using System.Dat ... -
匿名方法
2009-08-04 09:21 832匿名方法优点:减少系统开销,在真正委托调用时才定义。 usi ... -
.NET WebService的创建、部署、运用
2009-07-24 13:41 1423项目要求:(简单点讲) ... -
C#生成缩略图
2009-07-13 10:01 1656using System; using System.Dat ... -
.net MD5
2009-06-17 10:19 893using System; using System.Dat ... -
给RadionButtonList控件加onclick属性
2009-05-13 16:25 1062RadionButtonList _Specialclassi ... -
设计模式学习笔记七:常用设计模式原则总结
2009-05-12 15:43 1015前面学习了一部分创建 ... -
设计模式学习笔记六——Adapter模式
2009-05-12 15:42 711动机:将一个类的接口转换成客户希望的另外一个接口,使得原本由于 ... -
设计模式学习笔记五——Prototype模式
2009-05-12 15:01 1046动机:使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创 ... -
设计模式学习笔记五:抽象工厂(Abstract Factory)
2009-05-12 14:58 14301.概述 意图: 提供一个创建一系列相关 ... -
设计模式学习笔记四——Builder模式
2009-05-12 14:52 1111动机:一个复杂对象由多个子对象构成,该对象创建的算法相对不变, ... -
设计模式学习笔记四:工厂方法(Factory Method)
2009-05-12 14:51 8711.概述 在软件系统中,经常面临着“某个对象”的创建工作 ... -
设计模式学习笔记三——Abstract Factory模式
2009-05-12 14:51 972动机:实现一系列相互依赖对象的创建,通过封装系列对象创建来隔离 ... -
设计模式学习笔记三:简单工厂(Simple Factory)
2009-05-12 14:50 879开始学习创建型模式,这些模式的使用是面向接口编程的必然结果,面 ... -
设计模式学习笔记二——Singleton模式
2009-05-12 14:49 843意图:出于某种目的(如性能考虑、逻辑性要求)要求一个类的实例只 ... -
设计模式学习笔记二:面向对象基础六之委托与事件
2009-05-12 14:48 1187委托 委托作为函 ... -
设计模式学习笔记二:面向对象基础五之集合和泛型
2009-05-12 14:47 957数组 数组的优点:数组在内存中连续存储,可以快速而容易的 ...
相关推荐
Spring.NET学习笔记 - 刘冬.NET - 博客园
Activiti 学习笔记六:流程执行历史记录
.net学习笔记,.net学习的好资料。
本人几年的学习摘要。对想学习ASP.NET的朋友很有帮助。 里面知识面广,内容都是我在实践中遇到的困难的解决方法,和我自己的实现片段代码。现在与大家分享。
我的asp.net学习笔记 学习asp.net过程的学习笔记,大家可以来看下
设计模式学习笔记,分析了GOF的23种模式和类设计的原则
Java设计模式学习笔记
ASP.NET 学习笔记 内包括很多实用的代码
我收集的设计模式的学习笔记,采用pdf格式,便于收藏和查看
本人几年的学习摘要。对想学习ASP.NET的朋友很有帮助。 里面知识面广,内容都是我在实践中遇到的困难的解决方法,和我自己的实现片段代码。现在与大家分享。
VC学习笔记1:按钮的使能与禁止 VC学习笔记2:控件的隐藏与显示 VC学习笔记3:改变控件的大小和位置 VC学习笔记4:什么时候设定视中控件的初始尺寸? ......
各个模式都有详细的例子C#学习笔记,打开就知道了
ASP.NET编程技术与交互式网页设计 asp.net亲密接触_带源码 C#学习 01_类.htm.txt 02_构造函数的执行序列.htm.txt 03_抽象类和接口.htm.txt 04_结构类型.htm.txt 05_类成员的定义.htm.txt 06_类成员的其他...
设计模式学习笔记(一)--简单工厂模式源码和类图
*ASP.NET_2.0中的数据操作/*ASP.NET学习笔记/*ASP.NET中文手册
HeadFirst设计模式学习笔记比较全面详细地讲解了13个设计模式,有利于大家更好的学习HeadFirst设计模式,希望亲们会喜欢~~~
本人几年的学习摘要。对想学习ASP.NET的朋友很有帮助。 里面知识面广,内容都是我在实践中遇到的困难的解决方法,和我自己的实现片段代码。现在与大家分享。
设计模式学习笔记.ppt 自己写的一点学习笔记。
总结了java开发中的21种设计模式,详解和例子,带书签的pdf格式,方便阅读!