大话设计模式之工厂模式

       千百年来,关于“空中花园”有一个美丽动人的传说。新巴比伦国王尼布甲尼撒二世娶了米底的公主安美依迪丝为王后。公主美丽可人,深得国王的宠爱。可是时间一长,公主愁容渐生。尼布甲尼撒不知何故。公主说:“我的家乡山峦叠翠,花草丛生。而这里是一望无际的巴比伦平原,连个小山丘都找不到,我多么渴望能再见到我们家乡的山岭和盘山小道啊!”原来公主得了思乡病。于是,尼布甲尼撒二世令工匠按照米底山区的景色,在他的宫殿里,建造了层层叠叠的阶梯型花园,上面栽满了奇花异草,并在园中开辟了幽静的山间小道,小道旁是潺潺流水。工匠们还在花园中央修建了一座城楼,矗立在空中,巧夺天工的园林景色终于博得公主的欢心。故事讲到这里,在我们的故事中蕴藏着怎样的设计模式呢?今天这篇博文的内容就从我们美丽动人的传说空中花园开始!

        如果空中花园中只种花,那么就用简单工厂就可以了,如果公主喜欢各种各样的花,种类比较繁多,我们就需要用工厂方法,把公共有的东西抽象出来,再者如果公主想要扩大花园的规模,一个在安徽一个在河北,这样工厂方法也就无法实现了,这个时候,就需要用到抽象工厂,把各种各样的植物,又组成一个空中花园。我们先来看一下工厂方法模式模式的结构图:

        

        在前面的博文中,我们学习过简单工厂模式,简单工厂是一个工厂只生产一类的产品,面对的是具体的类,工厂方法是可以生产不同的产品,把公共的方法抽象出来,然后进行创建各种各样的产品.抽象工厂把几种产品划出共同的东西,把相互依赖的对象抽象出来,只要实现这些接口就可以得到不同的产品,简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,下面就具体看看工厂模式是如何解决该问题的。 工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点。下面看下工厂模式的具体实现代码(这里还是以简单工厂模式中点菜的例子来实现:

        

<span style="font-size:18px;">namespace 设计模式之工厂方法模式
{
    /// <summary>
    /// 菜抽象类
    /// <summary>
    public abstract class Food
    {
        // 输出顾客点了什么菜
        public abstract void Print();
    }

    /// 酸辣土豆丝这道菜

    public class ChiliSourPotatod: Food
    {
        public override void Print()
        {
            Console.WriteLine("酸辣土豆丝出锅!");
        }
    }
    /// <summary>
    /// 姜汁皮蛋这道菜
    /// </summary>
    public class PreservedEggSinGingerSauce : Food
    {
        public override void Print()
        {
            Console.WriteLine("姜汁皮蛋");
        }
    }
    /// <summary>
    /// 抽象工厂类
    /// </summary>
    public abstract class Creator
    {
        // 工厂方法
        public abstract Food CreateFoddFactory();
    }
    /// <summary>
    /// 酸辣土豆丝工厂类
    /// </summary>
    public class  ChiliSourPotatod:Creator
    {
        /// <summary>
        /// 负责创建酸辣土豆丝这道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return new  ChiliSourPotatod();
        }
    }
    /// <summary>
    /// 姜汁皮蛋工厂类
    /// </summary>
    public class PreservedEggSinGingerSauceFactory:Creator
    {
        /// <summary>
        /// 负责创建姜汁皮蛋这道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return newPreservedEggSinGingerSauce();
        }
    }
    /// <summary>
    /// 客户端调用
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            // 初始化做菜的两个工厂()
            Creator ChiliSourPotatodFactory = new ChiliSourPotatodFactory();
            Creator PreservedEggSinGingerSauceFactory = new  PreservedEggSinGingerSauceFactory();
            // 开始做酸辣土豆丝
            Food ChiliSourPotatod = tomatoScrambledEggsFactory.CreateFoddFactory();
            ChiliSourPotatod.Print();
            //开始做姜汁皮蛋
            FoodPreservedEggSinGingerSauce =PreservedEggSinGingerSauceFactory.CreateFoddFactory();
            PreservedEggSinGingerSauce.Print();
            Console.Read();
        }
    }
}
</span>

       使用工厂方法实现的系统,如果系统需要添加新产品时,我们可以利用多态性来完成系统的扩展,对于抽象工厂类和具体工厂中的代码都不需要做任何改动。例如,我们我们还想点一个“黄瓜炒鸡蛋”,此时我们只需要定义一个黄瓜炒鸡蛋具体工厂类和黄瓜炒鸡蛋类就可以。而不用像简单工厂模式中那样去修改工厂类中的实现,具体代码如下所示:

           

<span style="font-size:18px;">/// <summary>
    /// 黄瓜炒鸡蛋这道菜
    /// </summary>
    public class ScrambleEggWithCucumber : Food
    {
        /// <summary>
        /// 重写抽象类中的方法
        /// </summary>
        public override void Print()
        {
            Console.WriteLine("黄瓜炒鸡蛋好了");
        }
    }
 /// <summary>
    /// 黄瓜炒鸡蛋工厂类,负责创建黄瓜炒鸡蛋这道菜
    /// </summary>
    public classScrambleEggWithCucumberFactory : Creator
    {
        /// <summary>
        /// 负责创建黄瓜炒鸡蛋这道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return new ScrambleEggWithCucumber();
        }
    }
    /// <summary>
    /// 客户端调用
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {

            // 如果客户又想点黄瓜炒鸡蛋了
            // 再另外初始化一个黄瓜炒鸡蛋工厂
            Creator ScrambleEggWithCucumberFactor = new ScrambleEggWithCucumberFactory();
            // 利用黄瓜炒鸡蛋工厂来创建黄瓜炒鸡蛋这道菜
            Food ScrambleEggWithCucumber = ScrambleEggWithCucumberFactor.CreateFoddFactory();
            ScrambleEggWithCucumber.Print();
            Console.Read();
        }
    }
</span>

         
         简单工厂:严格说并不是一个设计模式。简单工厂没有抽象类,只有一个具体工厂类如MyFactory,然后MyFactory里面有个工厂方法CreateProduct返回一个基类产品,具体返回什么具体实例通过传入参数然后用case判断。用手机生产做个例子:比如魅族简单工厂就是只有MeizuFactory工厂类,工厂方法就是CreateMeizuPhone,参数是Meizu手机型号,根据不同型号创建不同的Meizu手机(使用case)。很明显的缺点就是Meizu每发明一个新型号的手机都需要修改简单工厂类(增加case判断),违反了封闭修改,开放扩展原则。
         工厂方法:该模式有一个抽象基类和若干个派生的具体工厂类,基类定义了一个虚工厂方法返回指定产品类的基类,派生类需要实现该虚方法并创建具体产品类返回。注意工厂方法的每个具体工厂只负责返回一种产品类。同样以手机生产做例子:Meizu工厂方法模式有一个工厂基类MeizuFactory,注意此工厂和上面不一样,是抽象的。该类定义一个虚工厂方法CreateMeizuPhone,该方法返回MeizuPhone基类。然后不同型号的手机对应一个该型号的手机工厂,这样的优点就是,新出一个Meizu手机型号,只需派生一个该型号的工厂而无需修改原来的代码。符合封闭修改,开放扩展原则。设计之旅,未完待续......

         

    

时间: 2024-10-12 15:01:38

大话设计模式之工厂模式的相关文章

深入理解JavaScript系列(28):设计模式之工厂模式详解

 这篇文章主要介绍了深入理解JavaScript系列(28):设计模式之工厂模式详解,工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类,需要的朋友可以参考下     介绍 与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口方法以便创建的时候指定自己的对象类型. 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于

PHP设计模式之工厂模式与单例模式_php技巧

本文实例讲述了PHP设计模式之工厂模式与单例模式实现方法.分享给大家供大家参考,具体如下: 设计模式简单说应对某类问题而设计的解决方式 工厂模式:应对需求创建相应的对象 class factory{ function __construct($name){ if(file_exists('./'.$name.'.class.php')){ return new $name; }else{ die('not exist'); } } } 单例模式:只创建一个对象的实例,不允许再创建实例,节约资源(

大话设计模式之原型模式

       外国人把那京戏叫做"Beijing Opera " 没见过那五色的油彩楞往脸上画,四击头一亮相,(哇--)美极了妙极了,简直"ok"顶呱呱 ,蓝脸的多尔敦盗御马,红脸的关公战长沙 ,黄脸的典韦白脸的曹操 ,黑脸的张飞叫喳喳-- ,细心的小朋友,仔细区分就会发现,虽然每个京剧演员都不同,但基本上只具有几种脸型,长方形,圆形,细长,然后配上不同的妆容,胡子,眉毛,头饰,服装,有的再加点儿装饰物,就成了我们所看到的不同的演员角色,国粹和我们的编程有着什么样的

C# 设计模式----抽象工厂模式

原文地址:C#设计模式(4)--抽象工厂模式 一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性.但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是

PHP设计模式之工厂模式

工厂设计模式: 提供获取某个对象的新实例的一个接口, 同时使调用代码避免确定实际实例化基类的步骤. <?php    //基础标准CD类    class CD {                public $tracks = array();        public $band   = '';        public $title  = '';                public function __construct() {}                public 

解读设计模式----抽象工厂模式(AbstractFactory Pattern)

一.模式描述 我的程序中有需要一系列的对象,比如我们要吃一碗米饭(Rice),要喝一杯咖啡(Coffee)......,要想利用他们,我们就必须在程序中根据用户要求,然后一个个调用 new 操作符来生成他们,这样客户程序就要知道相应的类的信息,生成的代码显然不够灵活.那么我们可以在代码中不利用具体的类,而只是说明我们需要什么,然后就能够得到我们想要的对象呢? 这当然是可以的,根据GOF在<设计模式>一书里介绍,要创建对象这样的工作应该是属于创建型模式完成的.熟悉各种设计模式意图的朋友就会很快得

解读设计模式----简单工厂模式(SimpleFactory Pattern)

一.模式概述 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现,学习了此模式可以为后面的很多中模式打下基础.那好,我们就来了解下什么是简单工厂模式? 我们来分析一个现实生活中的案例,每天早晨起床洗唰后是干什么呢?吃早餐(这里只针对在外吃早餐的上班族

面向对象编程设计模式--简单工厂模式讲解

工作之余,在看资料过程中发现一个极易理解的简单工厂模式的例子,自己亲自试练一番,感觉对这个设计模式不熟悉的朋友, 一看马上就知道是什么回事了. 简单工厂模式根据提供给它的数据,返回几个可能类中的一个类的实例.通常它返的类都有一个共同的你类和共同的方法, 但每个方法执行的任务不同,而且根据不同的数据进行了优化. 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一. 下面进行一个代码示例: public class g

JavaScript设计模式之工厂模式和构造器模式_javascript技巧

什么是模式 前阵子准备期末考试,劳神又伤身的,实在闲不得空来更新文章,今天和大家说说javascript中的设计模式. 首先呢,我们需要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案. js反模式常见例子 1.向setTimeout和setInterval传递字符串,而不是函数,这会触发eval()的内部使用. 2.在全局上下文中定义大量的变量污染全局命名空间 3.修改Object类的原型 4.以内联形式使用js,嵌入在HTML文件中的js代码是无法包含在外部单元