C#抽象工厂(AbstractFactory)-鸡腿和汉堡

最近学习设计模式,对于抽象工厂很是难以理解,就到网上查看一番,碰到一哥们写的文章,比喻很贴切,也算是让我明白了大概。下面是转载他写的文章。

他的地址我忘了,很久了。最近整理了一下发到博客上来。

一直觉得设计模式是非常抽象的(事实上MS也是。。。),所以就想把它说的白话点儿,让人更容易理解。

           关于抽象工厂(Abstract Factory)模式,网上一个非常流行的例子,麦当劳和肯德基的故事。具体怎么说的我已经忘了,但是我想自己描述一遍,希望能让自己加深对设计模式思想的理解,也希望对大家有所帮助。

           既然叫抽象工厂,那一定有工厂(废话)。那么我们可以认为麦当劳和肯德基就是生产食物的工厂,那么理所当然,汉堡和鸡腿是他们共同生产的两种食物,不管你去MDL还是KDJ,说:我要鸡腿,那肯定不会给你拿来烤羊腿。嘿嘿 。这里,我们假定麦当劳和肯德基只生产这两种产品(这很重要,因为抽象工厂模式的一个很重要的场景就是产品相对稳定,如果要经常新增新产品,那么需要和另外的设计模式混合使用或寻求其它解决方案,这里不赘述)。

            情况已经很明显了,我们是消费者,我们就是客户,就是产品的消费者,就是程序中对象的调用者。而麦当劳和肯德基,理所当然的,他们就是工厂,一个叫做麦当劳工厂,一个叫做肯德基工厂,他们是真正的生产者,而对于我们这些客户消费者(程序中对象的调用者)来说,不管是去麦当劳还是肯德基,我们都说一样的话(我们的要求是稳定的):我要鸡腿。只要我们提出这个请求,那么肯定会得到我们想要的。而作为工厂(生产者),麦当劳和肯德基都生产鸡腿和汉堡,所以抽象出来的抽象工厂都具有生产鸡腿和生产汉堡的功能,这是接口中的两个方法。因为在这个接口中,还不知道到底要生产谁家的产品,所以只能返回个抽象的鸡腿或汉堡,等到麦当劳或者肯德基工厂生产出来,就知道是谁家的了。(有标志嘛,哈哈,这就是动态创建对象)

            不管是麦当劳还是肯德基的鸡腿或汉堡,它的本质都是鸡腿或汉堡,所以可以抽象出来。那么鸡腿就派生出麦当劳的鸡腿和肯德基的鸡腿,而汉堡就派生出麦当劳的汉堡和肯德基的汉堡。而对于我们这些客户消费者(程序中对象的调用者)来说,不管是去麦当劳还使肯德基,我们都说一样的话(我们的要求是稳定的):我要鸡腿。只要我们提出这个要求,那么肯定会得到我们想要的。不管是谁家的鸡腿,肯定是鸡腿不会是羊腿。所以,我们只要规定好是鸡腿(接口)就行了,而让工厂去绝对具体的制作过程。我们只伸手接过来一个鸡腿,狠狠的咬一口,恩,真香~:)

            到现在为止,我们只和鸡腿(抽象的接口)还有抽象工厂(因为我们不管是麦当劳还是肯德基,我们只要鸡腿)打交道。

            当我们走向一个快餐店,这个过程就决定了我们到底要哪个工厂来生产鸡腿和汉堡。我们可以把我们消费的习惯存入大脑,每次出门直接取出来,就只管走就行了。也不用看到底是走向了哪里,反正最后吃了好多鸡腿和汉堡,饱饱的走了。:)哈哈   理论讲解完毕,那么现在看看UML图。

那么,现在,大家应该已经看清楚。这张图是我自己随手画的,画完之后发现,哇,这不就是经典的AbstractFactory模式的那张图吗?现在,你了解吗?

        必胜客来了,也做汉堡和鸡腿。那么怎么办呢?非常容易,我们消费者根本不管这些,只管把必胜客加入我们的大脑(配置文件),需要的时候,直接走进去就行了。仅仅需要添加一个必胜客工厂,必胜客汉堡,必胜客鸡腿,OK,一切搞定。那么又有人问了,我要喝汽水怎么办呢?我偷偷告诉你,这里不卖~:)哈哈,希望大家学习愉快,工作愉快!!


以上是我在网上看到一篇仁兄写的文章,对我思想上的触发很大。自己琢磨了一会写出了下面的代码。

 

public abstract class KuaiCanFactory    //快餐工厂
    {

        
//两个抽象方法,您吃鸡腿呢,还是汉堡呀?因为是抽象出来的,所以不分商家哦!
        public abstract JiTui eatJiTui();
        
public abstract HanBao eatHanBao();
    }

//继续写类

    
public class MDLFactory:KuaiCanFactory   //麦当劳工厂
    {
        
public override JiTui eatJiTui()    
        {
            
return new MDLJiTui();
        }

        
public override HanBao eatHanBao()
        {
            
return new MDLHanBao();
        }
    }

//有了麦当劳当然少不了KFC啦。

//肯德基工厂及麦当劳工厂都实现了eatJiTui(),eatHanBao()方法。

    
public class KDJFactory:KuaiCanFactory

   {
        
public override JiTui eatJiTui()
        {
            
return new KDJJiTui();
        }

        
public override HanBao eatHanBao()
        {
            
return new KDJHanBao();
        }
    }

//下面就到食物了。。

    
public abstract class HanBao   //汉堡抽象类
    {
        
public abstract void getHanBao();
    }

    
public class MDLHanBao:HanBao //具体的麦当劳汉堡
    {
        
public override void getHanBao()
        {
            Console.WriteLine( 
"麦当劳汉堡");
        }
    }

    
public class KDJHanBao:HanBao   //具体的肯德基汉堡
    {
        
public override void getHanBao()
        {
            Console.WriteLine( 
"肯德基汉堡");
        }
    }

    
public abstract class JiTui    //鸡腿抽象类
    {
        
public abstract void getJiTui();
    }

    
public class KDJJiTui:JiTui  //具体的肯德基鸡腿
    {
        
public override void getJiTui()
        {
            Console.WriteLine( 
"肯德基鸡腿");
        }
    }

    
class MDLJiTui:JiTui      //具体的麦当劳鸡腿
    {
        
public override void getJiTui()
        {
            Console.WriteLine( 
"麦当劳鸡腿");
        }
    }

//这样就大功告成,客户去快餐店吃鸡腿,并不关心他们怎么拿出来的,只需要大吼一声“我吃鸡腿”,就OK了。

        
static void Main(string[] args)
        {
            
//这里或许使用简单工厂来处理选择商店更好
            KuaiCanFactory KC = new KDJFactory(); //想吃KFC的鸡腿,那么就去KFC。
            JiTui jt = KC.eatJiTui(); //想吃鸡腿了,那么就告诉KC(快餐店)
            jt.getJiTui(); //鸡腿拿来咯~~……

            HanBao hb 
= KC.eatHanBao(); //想吃汉堡
            hb.getHanBao();

            KC 
= new MDLFactory();
            jt 
= KC.eatJiTui();
            jt.getJiTui();

            hb 
= KC.eatHanBao();
            hb.getHanBao();
        }

 

输出结果:

肯德基鸡腿

肯德基汉堡

麦当劳鸡腿

麦当劳汉堡

饱了~~~~希望别吃坏了肚子。。要是哪不对,就给我留言,谢谢!!!
posted @ 2009-01-14 09:28  大尾巴狼啊  阅读(1088)  评论(7编辑  收藏  举报