雪黛缘
-失业中...QQ:941187431

   ^_^...继续写了..这次到什么了呢~工厂把~
   上次刚送走了一个喜欢让人”笑“的客户,这次又来了一个了。。这个客户要你写一个程序,用来帮助他管理一间餐馆的,这个餐馆主要的提供“鱼”的餐饮的,现在他刚开张,计划提供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抽象工厂解决的是一系列相互依赖的对象的创建.
你可以在工厂中加入简单工厂从而减少工厂的膨胀,那样是不是看起来好像是一系列的对象呢?其实他一个时刻只能返回一个对象,而不是返回一系列的对象.但抽象工厂是可以给你在一个初始化中提供一系列对象的.
本来想一口气写完的...看来太多的..受不了了....=_=...

 例子

posted on 2008-01-04 14:16  zhuibobo  阅读(399)  评论(2编辑  收藏  举报