所谓工厂,肯定是和生产有关。工厂模式主要包括工厂方法模式和抽象工厂模式,有些人把简单工厂也作为一种模式,在本文我分别讨论简单工厂模式,工厂方法模式,抽象工厂模式。这些模式中同样也和生产有关。接下来,我们来看看各种工厂的特点。

简单工厂模式

上面说了只是有些人把简单工厂看做是设计模式,其实是一种编程习惯,无论是否是设计模式,本文将先看看其用法,然后简单给出其类图,最后说出其特点。

本节将面对多种比萨,先看看当顾客需要一个比萨时的过程:

1.根据类型,制作一个比萨形状。2.然后进行烘烤3.切4.打包

如果不熟悉的话,完全可以把其想想成面包的做法。

当顾客根据自己的需求要一个比萨时,用代码模拟这个过程如下:

public  class Pizza
    {
       public void bake() { }
       public void cut() { }
       public void box() { }
    }
    public class CheesePizza:Pizza
    {
        public CheesePizza()
        { }
    }
    public class GreekPizza : Pizza
    {
        public GreekPizza(){}
    }
    public class PepperoniPizza:Pizza
    {
        public PepperoniPizza() { }
    }
    public  class Store
    {
      public  Pizza OrderPizza(string type)
        {
            Pizza pizza = null;
            if (type=="Cheese")
            {
                pizza = new CheesePizza();
            }
            else if (type=="Greek")
            {
                pizza = new GreekPizza();
            }
            else if (type == "Pepperoni")
            {
                pizza = new PepperoniPizza();
            }
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
    }

以上的设计方法和我们的以前提到的过的原则(找出经常变化的部分,抽象成类),很明显在if else 的地方发生经常性变化。

接下来就把if else 放到一个类中。修改后的代码

public  class Store
{
  public  Pizza OrderPizza(string type)
    {
        Pizza pizza = null;
        //if (type=="Cheese")
        //{
        //    pizza = new CheesePizza();
        //}
        //else if (type=="Greek")
        //{
        //    pizza = new GreekPizza();
        //}
        //else if (type == "Pepperoni")
        //{
        //    pizza = new PepperoniPizza();
        //}
        SimpleFactory factory = new SimpleFactory();
        pizza =factory.CreatePizza(type);
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

public class SimpleFactory
{
    public Pizza CreatePizza(string type)
    {
        Pizza pizza = null;
        if (type == "Cheese")
        {
            pizza = new CheesePizza();
        }
        else if (type == "Greek")
        {
            pizza = new GreekPizza();
        }
        else if (type == "Pepperoni")
        {
            pizza = new PepperoniPizza();
        }
        return pizza;
    }
}

这样的话,就可以遵循了把变化的部分抽象成一个类。下次需要变化,只需要对变化的类的部分做修改即可。下面给出其UML图。

简单工厂的目的,主要负责实现生产对象的细节,根据订单来生产。每一个商店有对应着自己的工厂。在此,可以将OrderPizza是工厂的一个客户,当然还可以是其他类似的方法,比如PizzaShopMenu也可以是工厂的客户。客户就是为了获取工厂生成的对象。前者是为了卖给people,后者是为了使用Pizza类获取其描述和价格等。这样遵循了找出变化的部分,将其封装到一个类中的原则,从而到达了复用的目的。

简单工厂之所以简单是因为它只根据需要,来生产出来指定的Pizza。特点:所有的产品都由一个工厂来生产。

接下来我们来看看工厂方法的实现。

工厂方法模式

如果是有多个商店,各个商店对于相同名字的pizza都有自己的生成方法。而且,除了生成方法不一样,其他的烘烤,切,打包,都是使用一样的步骤。下面就该我们的工厂方法模式出厂了。

由于生产pizza的方法决定于各个商店,不妨假设有两个商店。其公共的基类,应该有一个抽象的生产方法,具体的生产方法决定于商店。其UML类图如下:

上面的PizzaStore是一个抽象类,该类具有一个CreatePizza的抽象方法,真正实现的是具体的商店。

除了有多种商店,每个商店有多种Pizza类,而且是Pizza名是相同的,只是地区不一样,下面Pizza类的命名方式为:地区+Pizza名,其UML类图为:

商店和pizza的大致联系如下图:

在工厂方法中,使用了一个重要的原则:

原则五:依赖倒置:依赖于抽象,不要依赖于具体类

如果没有使用上述原则,而是直接让店铺依赖于每个Pizza类。

如果Pizza的实现变化了,就必须改变PizzaStore。每增加一个Pizza都会增加一个依赖。如果使用工厂方法设计模式的话,其依赖于抽象,不依赖与具体类。我们可以抽象出一个Pizza类,让所有商店以及所有的Pizza类来依赖它。这里涉及到一个依赖倒置的另一种解释,高层组件和底层组件都依赖于抽象。而不依赖与具体的实现,高层组件是有底层组件的方法构建 而成的。PizzaStore是由Pizza的Bake,Cut,Box方法构建。那么根据这个原则其大致图为:

这样的设计方法,对于任何添加新的Pizza种类,不会影响到PizzaStore。从而实现了松耦合的效果。

工厂方法和简单工厂设计模式的区别:简单工厂设计模式,只有一个工厂,每次增加新类,都需要修改SimpleFactory的代码,不能对工厂的创建方式进行分类管理,全部都由一个工厂制作。工厂方法,可以对工厂进行扩展,也就是可以对Pizza类分类管理,可以由不同的工厂去创建,更加灵活。

这个好比,简单工厂只有可以看成商店只有一家供应商,需要什么样子的产品,直接给工厂说,工厂如果没有的话要不然制造出来对象,要不然告诉供应商,我不能创建。工厂方法可以看成商店有多个供应商,需要的产品,可以有多重选择。

下面给出工厂方法的测试代码:

PizzaStore store = new NYPizzaStore();
store.OrderPizza("Greek");
store.OrderPizza("Cheese");

store = new ChicagoPizzaStore();
store.OrderPizza("Greek");
store.OrderPizza("Cheese");

抽象工厂模式

抽象工厂模式的定义:抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。

定义感觉还真有些抽象,下面就把他易于理解化。

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际的具体产品是什么。这样客户就从具体的产品中被解耦了。

下面就来看个关于南北方饮食的差异:

主食分别是北方风味和南方风味。无论是南方味道还是北方味道,其都包括主食和调料:北方主要是以面食和辣椒为主,南方主要是以大米和糖为主。

下面就使用抽象工厂来抽象两个接口,分别是主食和调料,对应还有两种风味。

接下来是调料和事务的对应实现:

接下来看看其联系

在上图中,AbstractFactory接口定义了两个方法来分别获得调料和主食。下面的南北风味是可以看出其具体实现。

这样就可以在前台查看风味的主食和调料就不用关心具体的实现。直接调用其Create方法就行了。

测试代码:

class Program
   {
       static void Main(string[] args)
       {
           Console.WriteLine("南方风味:");
           AbstractFactory factory = new SouthFood();
           Food food = factory.CreateFood();
           Console.WriteLine(food.Name);
           Condiment condiment = factory.CreateCondiment();
           Console.WriteLine(condiment.Name);

Console.WriteLine("北方风味:");
           AbstractFactory factory2 = new NouthFood();
           Food food2 = factory2.CreateFood();
           Console.WriteLine(food2.Name);
           Condiment condiment2 = factory2.CreateCondiment();
           Console.WriteLine(condiment2.Name);
           Console.ReadKey();
       }
   }

从该实例,可以看出抽象工厂是定义了多类产品。工厂方法是一个对象有多种做法,所以在抽象工厂中可以使用多个工厂方法。如果理解了工厂方法,那么抽象工厂应该更好理解些。

抽象工厂是单个接口定义了多个方法,所以具体的工厂肯定都要实现创建方法。

源码

FactoryPattern.zip

工厂模式——(Head first设计模式4)的更多相关文章

  1. java 之 简单工厂模式(大话设计模式)

    以前只是看设计模式,每次看完都去理解一次,并没有手动去写代码,所以理解的还不是很深刻,最近查看框架源码,发现很多地方用到的都是设计模式,因为对设计模式理解的不够深刻,所以源码查看进度很慢!现在决定来温 ...

  2. java 之 工厂模式(大话设计模式)

    在以前的文章里面讲述过简单工厂模式,见链接:http://www.cnblogs.com/zhuxiansheng/p/7873161.html 简单工厂模式解耦了客户端和实现的依赖,不过如果有再次扩 ...

  3. java 之 抽象工厂模式(大话设计模式)

    看了几次抽象工厂模式,每次查看都需要重新理解一次,可能是涉及的类和接口比较多,所以比较难缕清的关系吧!在笔者看来,我们还是要吸取其思想而不是生搬硬套. 来看下类图: 大话设计模式-类图 看类图已经很乱 ...

  4. C#简单工厂模式和单列设计模式潜要解析

    简单工厂设计模式,又叫做静态工厂方法(Static Factory Method)模式,就是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例. 简单工厂模式是工厂模式家族中最简单实用的模式.简单 ...

  5. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  6. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

  7. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  8. java设计模式之一工厂模式

    简单工厂模式是java设计模式中最简单的设计模式之一: 工厂模式是最常用的设计模式之一. 工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模 ...

  9. 桥接模式及C++实现 C++设计模式-AbstractFactory抽象工厂模式

    桥接模式及C++实现 桥接模式 先说说桥接模式的定义:将抽象化(Abstraction)与实现化(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式之一 ...

  10. [JS设计模式]:工厂模式(3)

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

随机推荐

  1. C++ 智能指针Auto_PTR 分析

    C++的动态内存的分配与释放是个挺折磨人的事情,尤其异常分支复杂时(比如一堆try catch中,各catch里需要做delete 掉相关的堆上分配的内存),极有可能产生内存泄露的情况.C++中提供了 ...

  2. vim设置配色主题

    默认主题注释为蓝色,完全看不清.可以在~/.vimrc当中设置colorscheme参数.我在zsh设置中设置了快捷键,直接编辑. colorscheme参数的值可以在 /usr/share/vim/ ...

  3. PHP-学习大规模高并发Web系统架构及开发推荐书籍

    以下书籍内容涵盖大型网站开发中几个关键点:高可用.高性能.分布式.易扩展.如果想对大规模高并发Web系统架构及开发有很系统的学习,可以阅读以下书籍,欢迎补充! 一.<Linux企业集群—用商用硬 ...

  4. HDUOJ-----3591The trouble of Xiaoqian

    The trouble of Xiaoqian Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  5. HDUOJ------1058 Humble Numbers

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. HDUOJ---1171

    http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Java/Othe ...

  7. IT常用设备及服务器安全公告或漏洞地址pa安全预警微软安全公告 HP 安全公告AIX 安全公告REDHAT安全公告ORACLE 安全公告F5 安全公告 Cisco 安全公告Juniper 安全公告 VMware 安全公告IOS 安全公告

    IT常用设备及服务器安全公告或漏洞地址: 微软安全公告 https://technet.microsoft.com/en-us/library/security/MS14-085 HP 安全公告 ht ...

  8. Java虚拟机学习 - 垃圾收集器 (4)

    HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器.如果两个收集器之间存在连线,就说明它们可以搭配使用. Serial(串行GC)收集器 Serial收集 ...

  9. 转 虫师的selenium借助AutoIt识别上传(下载)详解

    selenium借助AutoIt识别上传(下载)详解 2014-12-27 11:26 by 虫师, 755 阅读, 1 评论, 收藏,  编辑 AutoIt目前最新是v3版本,这是一个使用类似BAS ...

  10. Android 加新的页面

    工程右键->New->Other->Android Activity