策略模式VS简单工厂模式
策略模式(Strategy)它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
1.组成
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
2.应用场景
— 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
—需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
—对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
所有设计模式总结请参考:http://blog.csdn.net/chr23899/article/details/46999267
所有设计原则总结请参考:http://blog.csdn.net/chr23899/article/details/46999401
首先来看下具体的效果图
简单工厂模式的实现过程请参考:http://blog.csdn.net/chr23899/article/details/47000609
主要包括两个数 Number_X 和Number_Y 下面是四个操作
Add(+)、 Sub(-) 、 Mul(*)、 Div(/); 当用户选择一种模式后 点击其中一个操作时会安装具体的设计模式进行实例化具体的操作类型。
策略模式的类图如下:
具体实现代码如下:
//策略基类 public abstract class Strategy { //定义虚函数 public abstract double Result(double Number_x, double Number_y); } //加法运算 public class Strategy_Add : Strategy { public override double Result(double Number_x, double Number_y) { double number = 0; number = Number_x + Number_y; return number; } } //减法运算 public class Strategy_Sub : Strategy { public override double Result(double Number_x, double Number_y) { double number = 0; number = Number_x - Number_y; return number; } } //乘法运算 public class Strategy_Mul : Strategy { public override double Result(double Number_x, double Number_y) { double number = 0; number = Number_x * Number_y; return number; } } //除法运算 public class Strategy_Div : Strategy { public override double Result(double Number_x, double Number_y) { double number = 0; if (Number_y == 0) return 0; number = Number_x / Number_y; return number; } } //具体执行的对象 public class Context { private Strategy strate; public Context(Strategy str) { this.strate = str; } public double GetResult(double Number_x, double Number_y) { return strate.Result(Number_x, Number_y); } }</span>
首先提一下: 在简单工厂模式中使用了Virtual(虚函数) , 在策略模式中使用Abstract(抽象函数),让我们先来认识下他们之间的区别:
virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义。
它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的。毕竟加上virtual或 abstract就是让子类重新定义的,而private成员是不能被子类访问的。但是它们的区别很大。
(1)virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现。
(2)virtual可以被子类重写,而abstract必须被子类重写
(3)如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法。
(4)无法创建abstract类的实例,只能被继承无法实例化,比如: BaseTest2 base2 = new BaseTest2();将出现编译错误:抽象类或接口不能创建实例。
(5)C#中如果要在子类中重写方法,必须在父类方法前加virtual,在子类方法前添加override,这样就避免了程序员在子类中不小心重写了父类方法。
(6)abstract方法必须重写,virtual方法必须有实现(即便它是在abstract类中定义的方法).
在认识策略模式和简单工厂模式两者的区别时我们先来看下两者在客户端的调用方式
Operation oper; //简单工厂获取计算结果 private void GetResult_factory(string str) { oper = null; oper = FactoryOfOperation.GetTheOperation(str); oper.Number_x = Convert.ToDouble(txt_x.Text.Trim()); oper.Number_y = Convert.ToDouble(txt_y.Text.Trim()); txt_result.Text = oper.Result().ToString(); } Context cont; Strategy strate; //策略模式获取计算结果 private void GetResult_strategy(string str) { strate = null; switch (str) { case "add": strate = new Strategy_Add(); break; case "sub": strate = new Strategy_Sub(); break; case "mul": strate = new Strategy_Mul(); break; case "div": strate = new Strategy_Div(); break; default: break; } cont = new Context(strate); txt_result.Text = cont.GetResult(Convert.ToDouble(txt_x.Text.Trim()), Convert.ToDouble(txt_y.Text.Trim())).ToString(); }
从客户端来看,简单工厂需要至少需要两个类,一个是工厂类Factory,用来产生具体的功能类Operation,一个是这个Operation类,在这个Operation类中定义可以被要被重写的方法。客户端使用的时候首先要使用Factory类根据客户端条件,产生具体的Operation类,然后再使用Operation类中的方法实现具体的功能;策略类,在客户端也要接触两个类,一个是想要的具体算法类Category,一个是上下文类Context,Context类的构造方法接受一个Category类型对象,然后调用这个对象的具体算法实现具体的功能,Context类和Factory有点类似,和简单工厂模式不同的是Context接受一个对象,用这个对象来实例化自己,然后来调用自己的方法,当然这个方法是用这个对象中的方法。而Factory类接受条件产生一个对象,具体使用这个对象的方法还是要调用这个对象中的方法,而不是Factory中的方法。就是说Factory只负责获得对象,Context要依靠一个具体的对象来实例化自己,并调用具体的功能方法。
个人总结并整理 有不妥之处请大家指出并纠正。
原文出处: http://blog.csdn.net/chr23899 转发请说明
源程序下载地址:http://download.csdn.net/detail/chr23899/8924105
版权声明:本文为博主原创文章,未经博主允许不得转载。 博客列表: http://blog.csdn.net/chr23899