^_^...继续写了..这次到什么了呢~工厂把~
上次刚送走了一个喜欢让人”笑“的客户,这次又来了一个了。。这个客户要你写一个程序,用来帮助他管理一间餐馆的,这个餐馆主要的提供“鱼”的餐饮的,现在他刚开张,计划提供3种不同的“鱼”,1:水煮鱼,2:烤鱼,3:清蒸鱼,^_^,说起鱼嘛,我家那边是有很多的,潮州~呵呵,饮食挺出名的把,鱼和海鲜也是很好吃的,有机会的话去玩玩把,我想你肯定会喜欢的。。。呵呵。没说你呢。。=_=。。。好了继续我们的程序,既然有不同菜名,那加工肯定也是不同的了,费用也是不同的了。。那我们开始定义不同的菜把。。
制作工序都是:请洗,加工,上菜,恩定义一个接口
public interface IFish
{
string wash();
string machining();
string serving();
string price();
}
烤鱼:
public class BakeFish:IFish
{
private string fishType = "鲢鱼";//默认处理的,这部分以后会扩展[扩展什么?如果客人指定鱼呢?那价格不同把,呵呵,恩if判断,那在加一种鱼呢?恩,加if...天那,我又想去揍那个客户了,简直哭笑不得,"笑",噢,对了,笑,上一个客户你怎么解决的,策略模式,我们把价格计算独立出来,再根据实际需要组合.到这里你是不是想感想前一个客户了,对,带给你经验的往往就是客户,他们给公司带来钱,给你带来经验,无论你多么想揍他,还是先忍忍把..突然想起来,你看猎人吗?呵呵,可能你会想会长一样,发现充满的竟是感想.好了先跳过把],现在客户认为烤鲢鱼最好.
public BakeFish()
{
}
public string FishType
{
set { fishType = value; }
get { return fishType; }
}
public string wash()
{
return "washing BakeFish";
}
public string machining()
{
return "machining BakeFish";
}
public string serving()
{
return "serving BakeFish";
}
public string price()
{
return "$30";
}
}
水煮鱼:
public class WaterFish:IFish
{
private string fishType = "草鱼";//默认
public WaterFish()
{
}
public string FishType
{
set { fishType = value; }
get { return fishType; }
}
public string wash()
{
return "washing WaterFish";
}
public string machining()
{
return "machining WaterFish";
}
public string serving()
{
return "serving WaterFish";
}
public string price()
{
return "$35";
}
}
清蒸鱼:
public class BraiseFish:IFish
{
private string fishType = "鲫鱼";//默认
public BraiseFish()
{
}
public string FishType
{
set { fishType = value; }
get { return fishType; }
}
public string wash()
{
return "washing BraiseFish";
}
public string machining()
{
return "machining BraiseFish";
}
public string serving()
{
return "serving BraiseFish";
}
public string price()
{
return "$40";
}
}
恩,都定义好了,那接着就到客人点菜了..那我们想来直接new一下试试吧,看看怎么用的:
IFish fish=null;
if (this.DropDownList1.SelectedValue == "BakeFish")
{
fish = new BakeFish();
}
else if (this.DropDownList1.SelectedValue == "BraiseFish")
{
fish = new BraiseFish();
}
else if (this.DropDownList1.SelectedValue == "WaterFish")
{
fish = new WaterFish();
}
Response.Write(fish.wash() + "<br>");
Response.Write(fish.machining() + "<br>");
Response.Write(fish.serving() + "<br>");
Response.Write(fish.price() + "<br>");
恩...这样就行了..可以如果以后这间餐厅发展了,想多加一种菜你就不得不修改这里了...如果只有这里那还好,假如订餐的时候需要判断一次,把订单拿到柜台正式下单的时候又要判断一下,送进厨房的时候又要判断一下...恩..那就要在3处加入新菜了[修改代码]...好了,看到这里是变化的,那我们就把他那出来单独处理把..我们建一个类来处理对象的创建
public class SimpleFishFactory
{
public SimpleFishFactory()
{
}
public IFish CreateInstance(string type)
{
if (type == "BakeFish")
{
return new BakeFish();
}
else if (type == "BraiseFish")
{
return new BraiseFish();
}
else if (type == "WaterFish")
{
return new WaterFish();
}
else
{
return null;
}
}
}
好了..我们建立了一个简单工厂,用他来负责对象的创建,看看客户程序变成什么样拉
SimpleFishFactory factory = new SimpleFishFactory();
IFish fish = factory.CreateInstance(this.DropDownList1.SelectedValue);
Response.Write(fish.wash() + "<br>");
Response.Write(fish.machining() + "<br>");
Response.Write(fish.serving() + "<br>");
Response.Write(fish.price() + "<br>");
ok,这就是简单工厂了,虽然这并还不是一种设计模式,不过已经可以帮你封装一部分的变换了.如果要加入鱼的新做法,那我们修改一些SimpleFishFactory 就行了,客户端的多处调用不用动了,为什么?因为客户端我们依赖于接口了,而不是依赖与具体的实现类了.设计原则之一:依赖于接口而不要依赖于具体的实现,这里的接口包括[接口和抽象类,呵呵,我只知道这两种了]
好了..继续把..很偶然的...这里的人很喜欢吃鱼,这家餐厅继续扩大了..现在客户要我们为菜提供不同的地方口味[其实这里加入装饰模式可能更好点,不过我们继续我们的工厂把,以后我们再会到这里改把],区别是machining的不同了..好了,客户的要求是他们要加入四川和广东的口味,ok,那我们扩展"鱼"把.
public class GDWaterFish//广东风味的.
{
private string fishType = "草鱼";
public GDWaterFish()
{
}
public string FishType
{
set { fishType = value; }
get { return fishType; }
}
public string wash()
{
return "washing WaterFish";
}
public string machining()
{
return "machining WaterFish";
}
public string serving()
{
return "serving WaterFish";
}
public string price()
{
return "$35";
}
}
public class SCWaterFish:IFish//四川风味的.
{
private string fishType = "草鱼";
public SCWaterFish()
{
}
public string FishType
{
set { fishType = value; }
get { return fishType; }
}
public string wash()
{
return "washing WaterFish";
}
public string machining()
{
return "machining WaterFish";
}
public string serving()
{
return "serving WaterFish";
}
public string price()
{
return "$35";
}
}
到这里,如果我们还是用简单工厂的话,每次加入新的风味的话,那每次都要修改简单工厂了.虽然我们只需要修改一个地方,不过呢,记住对修改封闭,对扩展开放的原则,能不修改的我们就不修改.那好吧,你只能去百度,google了...呵呵,然后你可能会发现工厂模式,哦~它可以帮我解决这个难题.好,都是工厂嘛,我们就从简单工厂转换成工厂把.
首先,习惯是依赖于抽象,所以我们先建立一个抽像类把
public abstract class AFactory
{
private IFish fish=null;
public AFactory()
{
}
public string display()
{
fish = CreateFish();
return fish.wash() + "<br>" + fish.machining() + "<br>" + fish.serving() +"<br>" + fish.price();
}
public abstract IFish CreateFish();
}
然后还要一系列的子工厂负责具体对象的创建:就只列出几个把...
public class GDBakeFishFactory : AFactory
{
public GDBakeFishFactory()
{
}
public override IFish CreateFish()
{
return new GDBakeFish();
}
}
public class GDBraiseFishFactory:AFactory
{
public GDBraiseFishFactory()
{
}
public override IFish CreateFish()
{
return new GDBraiseFish();
}
}
public class GDWaterFishFactory:AFactory
{
public GDWaterFishFactory()
{
}
public override IFish CreateFish()
{
return new GDWaterFish();
}
}
....等等..等等..为每一个对象建一个工厂?那不是让程序更复杂了,对的,这里你或许可以用简单工厂加工一下,或许我们就不用建那么多工厂了.不过工厂模式负责的是单个对象的创建,并将创建延迟到之类,同时他会带来和类平行的结构图.现在你想想加入一个做法,就加入一个工厂那是不是不会影响到其他的东西呢?所以我们做到封装了,可以扩展,而不用去修改.恩看看客户程序的调用把.
哦,对了,虽然客户程序只知道需要取得"鱼",并别需要取得什么鱼到什么工厂里取就可以了,不过还是有逻辑上的判断的,例如客户程序说要广东的清蒸鱼,那你还是要去广东清蒸鱼的工厂里取的,那不是只不过将鱼到具体鱼的依赖转变成鱼和具体工厂的依赖了吗?
我们先看看客户程序把:我们的客人要指定广东清蒸鱼
AFactory factory = new GDBraiseFishFactory();//可是客户程序和具体工厂耦合了.
IFish fish = factory.CreateFish();//我们把鱼和具体鱼的耦合在客户程序解开了
Response.Write(fish.wash() + "<br>");
Response.Write(fish.machining() + "<br>");
Response.Write(fish.serving() + "<br>");
Response.Write(fish.price() + "<br>");
这样能带来什么好处呢?
1.假如需要对鱼再加工把,在这里GDBraiseFishFactory加工,鱼基本做法不变,客户程序不变.//假如这是逻辑层的话,那数据层不变,表现层[客户程序]不变.如果我们依赖于具体的鱼的话,那如果需要再加工的话,那我们需要在客户程序进行,并且不只一处.简单工厂?那每次加入新的变化都需要修改,说明没有对修改封闭,那可能会对以前的逻辑造成错误,产生bug..
2.需要加入其他烹调法,加入新的factory,新的类,以前的鱼和工厂不变,不用修改就是减少修改带来的bug,上一点应该是比较主要的..
好了,我也是半理解半不理解之间把,只能说到这里了..接着,到抽象工厂了,我们的餐厅继续扩大.它要杀出中国了,又会带来变化.先说一下工厂和抽像工厂把.
1工厂解决的是单个对象的创建.
2抽象工厂解决的是一系列相互依赖的对象的创建.
你可以在工厂中加入简单工厂从而减少工厂的膨胀,那样是不是看起来好像是一系列的对象呢?其实他一个时刻只能返回一个对象,而不是返回一系列的对象.但抽象工厂是可以给你在一个初始化中提供一系列对象的.
本来想一口气写完的...看来太多的..受不了了....=_=...