zoukankan      html  css  js  c++  java
  • 简单工厂模式(Simple Factory Pattern)

    最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足。园子里其实关于此类文章已经很多了,如果dudu感觉放在首页欠妥的话,可以调一下。

    简单工厂模式(Simple Factory Pattern)

    介绍:简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些。因为它至少不是Gof23种设计模式之一。但它在实际的编程中经常被用到,而且思想也非常简单,可以说是工厂方法模式的一个引导,所以我想有必要把它作为第一个讲一下。

    引入:
    我们在编程的时候,每当"new"一个对象之后,这个对象就依赖于这个类了。如果在后期的维护过程中由于某些原因需要修改一下这个类,则唯一的做法就是打开源代码,进行修改,修改所有与这个对象有关的操作。这对我们是非常不利的。
    问题出来了:对象不能应对“具体实例化类型”的变化
    解决思路:套用一下李建忠李老师的话,封装变化点,哪里变化,封装哪里。在这个例子中,要实例化的类变了,就将实例化这个操作封装起来,我们可以把"new"这个操作移交一个具体的类,由它去负责根据我们的条件创建具体类的实例,也就是下面要说的“简单工厂模式”。

    定义:
    专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类或接口。简单工厂模式又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通常根据一个条件(参数)来返回不同的类的实例。

    意图:
    提供一个类,由它负责根据一定的条件创建某一具体类的实例

    参与者:

    • 工厂角色(Creator)
      是简单工厂模式的核心,它负责实现创建所有具体产品类的实例。工厂类可以被外界直接调用,创建所需的产品对象。
    • 抽象产品角色(Product)
      是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口。
    • 具体产品角色(Concrete Product)
      继承自抽象产品角色,一般为多个,是简单工厂模式的创建目标。工厂类返回的都是该角色的某一具体产品。

    UML图:
    简单工厂模式UML图

    现实生活中例子:
    每次参加不同的聚会或者与不同的人见面,可能穿的衣服是不一样的,比如,你今天上午要与你的一个新客户见面,你可能会对你的老婆说:老婆,给拿件商务装(参数),我要去见我的一个客户,你老婆(工厂类)接到你的请求(商务装参数)后,从衣柜中取出一件商务装(具体产品),交给你。整个过程就完成了。

    分析:
    你可能根据不同的条件,要的衣服是不一样的,但要的衣服都是已经在你的衣柜中存在的。并且,每件上衣它们都属于同一种抽象,即它们可以从一个抽象类或接口中继承,这此衣服各自都有一定特征,这些都是条件。然后你要的时候,就可以向你老婆说一种特征,她就会根据这个特征为你服务了。这就是典型的简单工厂模式的应用。
     抽象产品类代码

    1    /// <summary>
    2    /// 抽象产品类:上衣
    3    /// </summary>

    4    public interface ICoat
    5    {
    6        void GetYourCoat();
    7    }


    非常简单,是吧?这里我只是举一个仅仅能说明问题的例子,在具体的项目中,可能是很复杂的哦。。

    具体产品类代码

     1namespace SimpleFactory
     2{
     3    /// <summary>
     4    /// 具体产品类:商务上衣
     5    /// </summary>

     6    public class BusinessCoat:ICoat
     7    {
     8        public void GetYourCoat()
     9        {
    10            Console.WriteLine("商务上衣");
    11        }

    12    }

    13
    14    /// <summary>
    15    /// 具体产品类:时尚上衣
    16    /// </summary>

    17    public class FashionCoat : ICoat
    18    {
    19        /// <summary>
    20        /// 实现ICoat中定义的方法
    21        /// </summary>
    22        /// <returns></returns>

    23        public void GetYourCoat()
    24        {
    25            Console.WriteLine("时尚上衣");
    26        }

    27    }

    28}


    简单工厂模式中最核心的部分:工厂类

     1namespace SimpleFactory
     2{
     3    /// <summary>
     4    /// 简单工厂模式中的核心部分:工厂类
     5    /// </summary>

     6    public class Factory
     7    {
     8        public ICoat CreateCoat(string styleName)
     9        {
    10            switch (styleName.Trim().ToLower())
    11            {
    12                case "business":
    13                    return new BusinessCoat();
    14                case "fashion":
    15                    return new FashionCoat();
    16                default :
    17                    throw new Exception("还没有你要的那种衣服");
    18            }

    19        }

    20    }

    21}


    再看一下客户在调用的时候的代码

     1 /// <summary>
     2    /// 客户类
     3    /// </summary>

     4    class Client
     5    {
     6        static void Main(string[] args)
     7        {
     8            ICoat food;
     9            try
    10            {
    11                Factory factory = new Factory();
    12
    13                Console.Write("我要的是时尚上衣\t");
    14                food = factory.CreateCoat("fashion");
    15                food.GetYourCoat();
    16
    17            }

    18            catch (Exception ex)
    19            {
    20                Console.WriteLine(ex.Message);
    21            }

    22        }

    23    }


    到这里,代码就完成了。
    在客户端的代码中有我们就可以根据具体的参数,返回我们希望返回的对象,将"new"操作推迟到工厂类中实现。
    这里,参数我直接写上了,我们其实可以将这个参数写到一个xml文件中,如app.config文件中,动态的读出来,需要穿另外一种衣服了,只需要打开app.config文件,修改里面的值就行了,不需要项目重新编译。这样这个小程序就能够适应一定的变化了(在上传上去的代码中我会修改一下)。其实它也是设计模式正要解决的问题,在不修改代码的情况下,使项目能够适应一定的客户需求变化。注意,是一定的,并非全部。

    优点:

    • 简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。通过它,外界可以从直接创建具体产品对  象的尴尬局面中摆脱出来。
    • 外界与具体类隔离开来,偶合性低。
    • 明确区分了各自的职责和权力,有利于整个软件体系结构的优化。

    缺点:

    • 工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则 
    • 虽然简单工厂模式能够适应一定的变化,但是它所能解决的问题是远远有限的。它所能创建的类只能是事先教考虑到的,如果需要添加新的类,则就需要改变工厂类了。(这个问题在下一个工厂方法模式将得到很好的解决)

    应用情景

    • 工厂类负责创建的对象比较少 
    • 客户只知道传入了工厂类的参数,对于始何创建对象(逻辑)不关心 
  • 相关阅读:
    vmware ubuntu 异常关机无法连接到网络
    Speed up GCC link
    常用的一些解压命令
    Log4j 漏洞复现
    Test Case Design method Boundary value analysis and Equivalence partitioning
    CCA (Citrix Certified Administrator) exam of “Implementing Citrix XenDesktop 4”
    What is Key Word driven Testing?
    SAP AGS面试小结
    腾讯2013终端实习生一面
    指针的引用
  • 原文地址:https://www.cnblogs.com/tomkillua/p/1602612.html
Copyright © 2011-2022 走看看