策略模式:定义算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
简单工厂:将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。
简单工厂严格意义上不是一种设计模式,只能是一种良好的编程习惯
简单工厂模式:
简单工厂模式,首先要有个工厂类,还要有个产品类。通过工厂类的静态接口获得用户需要的产品对象,也就是通过工厂来生产产品,这些对象的类都继承于相同的基类,拥有相同的方法,这样的封装可以实现让不同的变化通过统一的方式来调用,这也是多态的效果。对于要生成什么样的对象,这个判断是放在工厂类里面的,用户需要传给工厂类相应的参数,工厂类来做判断返回对应的产品类对象,用户再使用这个产品类对象做相应的操作。对于工厂模式,我觉得用户是希望得到产品类对象的并且希望自己操作,而且每个产品类不一定具有相同的方法,但他们都具有相似的属性。所以,工厂模式侧重于生产产品对象。
策略模式:
策略模式和简单工厂模式有很多相似的地方,他是针对不同的算法对其进行封装,更强调的是对一种方法的封装。策略模式里面没有产生策略对象的方法,他是要接收每个策略或者算法对象的,产生算法对象的任务是交给客户端来完成,在客户端里面,用户需要根据具体情况生成对应的算法对象。Context类是就是对一种算法的引用,Context类接收算法对象,并提供给用户返回算法结果的方法,算法的实际调用也是在这个方法中进行的。所以,策略模式更加强调的是对方法的封装。
至于将简单工厂模式和策略模式进行结合我觉得只是一个解耦优化的结果。每种设计模式都有他的优势和短板,可能在实际设计中不一定要做出完全和书本上那些模式一样的设计,具体的变化因人而异,因所设计东西或他的使用场景而异。
学习设计模式就是学习他的设计思想,给我们平时的设计提供一些思路,每种设计模式的应用场景也要看其更偏向于哪个功能需求,再结合一些优化才能做出好的设计。最近一直在抽时间研究设计模式,之前对设计模式也有一定的了解,但是都没有平心静气的去研究过,只是了解了一些皮毛,最近打算再深入研究一下,重新打开了设计模式的数据,对之前的疑问一个个的刨根问底,今天看了简单工厂模式和策略模式看的人有点小晕,两个的大概思路没有怎么变,都是通过多态去减少代码的耦合度,怎么看两个都是如出一辙,最后终于找到了两个的本质区别,在此和大家分享下:
先上代码:
简单工厂模式:
//抽象类
abstract class AbsClass
{
//抽象方法:提供一些列的算法操作
public abstract void acceptCash(string org);
}
//继承自抽象类
class A:AbsClass
{
//具体方法:提供一些列的算法操作
public override double acceptCash(string org)
{
Console.WriterLine("A类方法");
}
}
//继承自抽象类
class B:AbsClass
{
//具体方法:提供一些列的算法操作
public override double acceptCash(string org)
{
Console.WriterLine("B类方法");
}
}
... .... ....
简单工厂类
//现金收取工厂
class CashFactory
{
//根据条件返回相应的对象
public static AbsClass createCashAccept(string type)
{
AbsClass cs = null;
switch (type)
{
case "A":
cs = new Al();
break;
case "B":
cs = new B();
break;
case "...":
........ ....
break;
}
return cs;
}
}
客户端调用:
/利用简单工厂模式根据下拉选择框,生成相应的对象
AbsClass csuper = CashFactory.createCashAccept("A");
策略模式:
前面的类没有任何变化,只是把Factory变成了CaseContext策略类
//策略Context
class CashContext
{
//声明一个现金收费父类对象
private AbsClass cs;
//设置策略行为,参数为具体的现金收费子类(正常,打折或返利)
public CashContext(AbsClass csuper)
{
this.cs = csuper;
}
//得到现金促销计算结果(利用了多态机制,不同的策略行为导致不同的结果)
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
客户端调用:
CashContext cc = null;
switch (cbxType.SelectedItem.ToString())
{
case "A":
cc = new CashContext(new A());
break;
case "B":
cc = new CashContext(new B());
break;
case "...":
... ....
break;
}
最后概括总结一下:
策略模式和简单工厂模式看起来非常相似,都是通过多态来实现不同子类的选取,这种思想应该是从程序的整体来看得出的。如果从使用这两种模式的角度来看的话,我们会发现在简单工厂模式中我们只需要传递相应的条件就能得到想要的一个对象,然后通过这个对象实现算法的操作。而策略模式,使用时必须首先创建一个想使用的类对象,然后将该对象最为参数传递进去,通过该对象调用不同的算法。在简单工厂模式中实现了通过条件选取一个类去实例化对象,策略模式则将选取相应对象的工作交给模式的使用者,它本身不去做选取工作。
结合上面的代码和下面的释义不难看出,其实两个的差别很微妙,Factory是直接创建具体的对象并用该对象去执行相应的动作,而Context将这个操作给了Context类,没有创建具体的对象,实现的代码的进一步封装,客户端代码并不需要知道具体的实现过程。