设计模式 学习笔记(4)工厂方法模式、原型模式、模板方法模式
(8)工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
简单工厂模式与工厂方法模式的区别。简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。但是我们在增加一个功能时,需要给运算的工厂类方法里加“case”的分之条件,修改原有的类就违背了开发-封闭原则。这时就由工厂方法模式来解决,但工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,也就是原来是要修改工厂类的,而现在是修改客户端。
工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
//工厂接口 interface Ifactory { Operation CreateOperation(); } //加减乘除各建一个具体工厂去实现这个接口。 class AddFactory:IFactory //加法类工厂 { public Operation CreateOperation() { return new OperationAdd(); } } class SubFactory:IFactory //减法类工厂 { public Operation CreateFactory() { return new OperatioSub(); } } 。。
客户端的实现。
1 IFactory operFactory=new AddFactory(); 2 Operation oper=operFactory.CreateOperation(); 3 oper.NumberA=1; 4 oper.NumberB=2; 5 double result=oper.GetResult();
(9)原型模式
原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式实际就是从一个对象再创建另一个可定制的对象,而且不需知道任何创建的细节。
原型类
1 abstract class Prototype 2 { 3 private string id; 4 public Prototype(string id) 5 { 6 this.id=id; 7 } 8 public string Id; 9 { 10 get {return id;} 11 } 12 public abstract Prototype Clone(); 13 }
具体原型类
1 class ConcretePrototype1:Prototype 2 { 3 public ConcretePrototype1(string id):base(id) 4 {} 5 public override Prototype Clone() 6 { 7 return (Prototype)this.MemberwiseClone(); 8 } 9 }
客户端代码
1 static void Main(string[] args) 2 { 3 ConcretePrototype p1=new ConcretePrototype1("I"); 4 ConcretePrototype c1=(ConcretePrototype)p1.Clone(); 5 Console.WriteLine("Cloned:{0}",c1。Id); 6 Console.Read(); 7 }
在.net中Systwm命名空间中提供了ICloneable接口,其中就是唯一的一个方法Clone(),这样你就只需要实现这个接口就可以完成原型模式了。MemberwiseClone()方法是这样,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制,把引用对象的变量指向父之过的新对象,而不是原有的被引用的对象。深复制要注意循环引用问题。深复制则需要手动复制对象的所有字段值。
数据集对象DataSet,它有Clone()方法和Copy()方法。前者复制结构,不复制数据,实现原型模式的浅复制;后者不但复制结构还复制数据实现了原型模式的深复制。
(10)模板方法模式
模板方法模式,定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的机构即可重定义该算法的某些特定步骤。
AbstractClass是抽象类,其实也就是一抽象模板,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
1 abstract class AbstractClass 2 { 3 public abstract void PrimitiveOperation1(); 4 public abstract void PrimitiveOperation2(); 5 public void TemplateMethod() 6 { 7 PimitiveOperation1(); 8 PimitiveOperation2(); 9 Console.WriteLine(""); 10 } 11 }
ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
1 class ConcreteA:AbstractClass 2 { 3 public override void PrimitiveOperation1() 4 { 5 Console.WriteLine("具体类A方法1实现"); 6 } 7 public override void PrimitiveOperation2() 8 { 9 Console.WriteLine("具体类A方法2实现"); 10 } 11 } 12 13 class ConcreteClassB:AbstractClass 14 { 15 public override void PrimitiveOperation1() 16 { 17 Console.WriteLine("具体类B方法1实现"); 18 } 19 public override void PrimitiveOperation2() 20 { 21 Console.WriteLine("具体类B方法2实现"); 22 } 23 }
客户端调用
1 static void Main(stringp[] args) 2 { 3 AbstractClass c; 4 c=new ConcreteClassA(); 5 c.TemplateMethod(); 6 c=new ConcreteClassB(); 7 c.TemplateMedthod(); 8 Console.Read(); 9 }
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。