学习设计模式已经有很长一段时间了,其实先前已经敲过一遍了,但是老觉得没有学到什么,认识也不够深刻,现在趁着重构机房,再重新来过,也不晚。
其实在敲了机房之后,看看模式,其实,以前很难理解,很难看懂的代码一眼就可以看懂了,趁着有点感觉了,早点收获吧。
简单工厂模式:
简单地说简单工厂模式:很容易变化的地方,就可以用到简单工厂模式。
实例:
举个例子:我们在逛商场时,正好商场促销,各种优惠活动:有满300返100 ,有打8折的、抽奖等等吧。
促销来讲,各种优惠活动其实就是变化。
再举个例子:我们在买早餐的时候,早餐店里琳琅满目,但无论是谁来这家商店买都系,营业员问你需要什么,他就知道给你拿什么东西。我们需要的东西就是变化。
浅谈:
简单工厂模式就是通过传入的数据返回几种可能类宏的一种类的实例。但这几种类一般会有一个共同特点就是:这几种类有一个共同的父类和共同的方法,但每个方法被容不同,而且根据不同的数据进行优化。
深入:
上述是浅谈,实质:面对这些变化,面向对象的思想就是封装这些变化,封装变化之后,则可增加它的可扩展性,不会再修改以前的类了。
简单工厂模式结构图:
实现商场促销:
父类:
<span style="background-color: rgb(204, 204, 204);"><strong> abstract class CashSuper//父类,一个抽象还是,封装
{
public abstract double acceptCash(double money);
}</strong></span>
各个子类:
class CashNormal :CashSuper//各个实例化的对象,实现了多态
{
public override double acceptCash(double money)//实现父类中的方法,并各个不同的类之间都有差异
{
return money;
}
}
class CashRebate:CashSuper
{
private double moneyRebate = 1d;
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double acceptCash(double money)
{
return money * moneyRebate;
}
}
class CashReturn:CashSuper
{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn (string moneyCondition,string moneyReturn)
{
this.moneyCondition = double.Parse(moneyCondition);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double acceptCash(double money)
{
double result = money;
if (money >= moneyCondition)
result = money - Math.Floor(money / moneyCondition) * moneyReturn;
return result;
}
}
工厂模式:
//简单工厂模式
class CashFactory//简单工厂模式实现了,将选择放在了业务层,而不是界面层
{
public static CashSuper createCashAccept(string type)
{
CashSuper cs = null;//定义了一个父类的类型
switch (type)
{
case"正常收费":
cs = new CashNormal();//实例化的是各个子类对象
break;
case"满300返100":
CashReturn cr1 = new CashReturn("300", "100");
break;
case"打8折":
CashRebate cr2 = new CashRebate("0.8");
break;
}
return cs;
}
}
界面层:
private void button1_Click(object sender, EventArgs e)
{
//简单工厂模式-------------------------------------------------------------------
CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());//简单工厂模式的写法,客户端认识两个类,CashSuper和CashFactory,再简单工厂模式中就已经实例出了各个子类对象
double totalPrices = 0d;
totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
total = total + totalPrices;
lbxList.Items.Add("单价" + txtPrice.Text + "数量:" + txtNum.Text + "" + cbxType.SelectedItem + "合计:" + totalPrices.ToString());
label4.Text = total.ToString();
}
我们都知道,商店不是一直都有促销的,也不一定今年这这种促销,明年还是这种,事物都是在随着时间变化的,如果每次更改打折额度和返利额度,每次都要维护或扩展收费方式,都要改动工厂,一直代码徐重新编译部署,这要就很糟糕了,面对算法的市场变动,就需要策略模式了。
策略模式:
例子:
商店里促销每年需要更改打折额度和返利额度。结构图:
闲谈:
其实策略模式定义了算法家族,分别封装起来,让他们之间可以相互代替,此模式让算法的变化,不会影响到使用算法的客户。所有这些算法完成的都是相同的工作,只是实现不同,他可以用相同的方法调用所有的算法,减少了算法类和使用算法类之间的耦合。
深入:
简单工厂来生成算法对象,算法是随时都可能互相替换,这就是变化点,封装变化点。
实现商店促销:
前面的父类和个促销子类不需要修改:
策略模式代码:
class CashContext//用一个CashContext来配置,维护一个对Strategy对象的引用。
{
CashSuper cs=null;
public CashContext(string type)//应用了简单工厂模式将父类实例化的对象(不同的子类)
{
switch (type)//给一个值,来选择不同的对象,传入具体的策略对象
{
case"正常收费":
CashNormal cs0=new CashNormal();
cs=cs0;
break;
case"满300返100":
CashReturn cr1=new CashReturn ("300","100");
cs=cr1;
break;
case"打8折":
CashRebate cr2=new CashRebate ("0.8");
cs=cr2;
break;
}
}
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
界面代码:
private void button1_Click(object sender, EventArgs e)
{
//策略模式和简单工厂模式结合----------------------------------------------------
CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());//客户端只认识CashContext就行了,纯如具体的策略对象
double totalprices = 0d;
totalprices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
total = total + totalprices;
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + " " + cbxType.SelectedItem + "合计:" + totalprices.ToString());
label4.Text = total.ToString();
}
以上就是策略模式和简单工厂模式的结合了,简单工厂模式其实说简单一点就是:一个类创造实例的过程。策略模式:策略随时有可能互相替换。