您的位置:1010cc时时彩经典版 > 操作系统 > 二种工厂格局计算,轻便工厂格局

二种工厂格局计算,轻便工厂格局

发布时间:2019-08-18 11:31编辑:操作系统浏览(152)

    iOS设计模式 - (3)简单工厂模式

     

     

    简单工厂模式(FACTORY),通过面向对象的封装,继承和多态来降低程序的耦合度。将一个具体类的实例化交给一个静态工厂方法来执行。

    Android中,工厂模式分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。

          前段时间也简单的了解过设计模式,一直都没有认真的学习过,不过打算连续学习一下;

    一。简述

     

    简单工厂模式(FACTORY),通过面向对象的封装,继承和多态来降低程序的耦合度。将一个具体类的实例化交给一个静态工厂方法来执行。

    该模式中的角色包括:

     

    工厂类(Simple Factory): 只包含了创建具体类的静态方法。抽象产品(Product):定义简单工厂中要返回的产品。具体产品(ConcreteProduct):具体产品。我们用一张类图描述这个模式。图片 1这里, 客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象。

    该模式中的角色包括:

    一.简单工厂模式。

          主要借鉴了这两个地方的博客:  主要讲了设计模式的框架,后面的文章也有代码实现;在UML实现时加入了客户端

    二。实例

    涉及代码下载: 比如, 如果我们要实现一个计算器功能, 它包含 - * / 等基本运算.它的功能大致如下:图片 2在不使用设计模式之前, 我们很常规的会写出下面这样的代码:

    - (IBAction)getResult:(id)sender
    {
        //得到三个文本输入框的内容
        NSString* strFirstNum = self.FirstNumTextField.text;
        NSString* strSecondNum = self.SecondNumTextField.text;
        NSString* strOperation = self.OperationTextField.text;
        //进行运算操作
        if ([strOperation isEqualToString:@ ])
        {
            NSLog(@ );
            double result = [strFirstNum doubleValue] [strSecondNum doubleValue];
            self.ResultTextField.text = [NSString stringWithFormat:@%f,result];
        }
        else if([strOperation isEqualToString:@-])
        {
            NSLog(@-);
            double result = [strFirstNum doubleValue]-[strSecondNum doubleValue];
            self.ResultTextField.text = [NSString stringWithFormat:@%f,result];
        }
        else if([strOperation isEqualToString:@*])
        {
            NSLog(@*);
            double result = [strFirstNum doubleValue]*[strSecondNum doubleValue];
            self.ResultTextField.text = [NSString stringWithFormat:@%f,result];
        }
        else if([strOperation isEqualToString:@/])
        {
            NSLog(@/);
            //判断除数不能为0
            if ([strSecondNum isEqualToString:@0])
            {
                NSLog(@除数不能为0);
                UIAlertView* tempAlert = [[UIAlertView alloc] initWithTitle:@警告 message:@除数不能为0 delegate:nil cancelButtonTitle:@取消 otherButtonTitles:nil];
                [tempAlert show];
            }
            else
            {
                double result = [strFirstNum doubleValue]/[strSecondNum doubleValue];
                self.ResultTextField.text = [NSString stringWithFormat:@%f,result];
            }
        }
    
    }
    

    也就是写了一个方法, 通过传入的值. 来计算。上面代码确实可以实现这个功能,但是我们却没有考虑到:如果以后需要提供开平方运算,乘方运算扩展时候,改如何做呢?直接加个if else?如果加入了100种运算呢?如果这样去做是不是每次都要去改这部分代码,这样有悖我们可扩展性原则。所以我们需要引入简单工厂模式,把运算给抽象出来,并且加入运算工厂用于接收用户的操作。

    先看下简单工厂的实现类图:图片 3

    根据这一思路. 我们可以写出如下代码:
    协议接口:

    #import 
    
    /*!
     *  操作方法协议接口
     *
     *  @since V1.0
     */
    @protocol OperationProtocol 
    
    -(double)getResult;
    
    @end
    

    父类: 实现接口, 说明它有getResult方法

    #import 
    #import OperationProtocol.h
    
    /*!
     *  操作方法父类
     *
     *  @since V1.0
     */
    @interface Operation : NSObject
    
    @property double firstNum;//第一个操作数
    @property double secondNum;//第二个操作数
    
    @end
    

    子类:(以加法为例)

    #import Operation.h
    
    /*!
     *  加法实现类
     *
     *  @since V1.0
     */
    @interface OperationAdd : Operation
    
    @end
    

    实现:

    #import OperationAdd.h
    
    @implementation OperationAdd
    
    -(double)getResult
    {
        double result = 0;
        result = self.firstNum self.secondNum;
        return result;
    }
    
    @end
    

    其他运算类似, 就不重复了。
    工厂类:

    #import 
    #import Operation.h
    #import OperationAdd.h
    #import OperationSub.h
    #import OperationMultiply.h
    #import OperationDivide.h
    
    /*!
     *  操作工厂类
     *
     *  @since V1.0
     */
    @interface OperationFactory : NSObject
    
    //获得操作对象
     (Operation*)createOperate:(NSString*)operateStr;
    
    @end
    
    
    
    #import OperationFactory.h
    
    @implementation OperationFactory
    
     (Operation*)createOperate:(NSString*)operateStr
    {
        Operation* oper = nil;
        if ([operateStr isEqualToString:@ ])
        {
            oper = [[OperationAdd alloc] init];
        }
        else if ([operateStr isEqualToString:@-])
        {
            oper = [[OperationSub alloc] init];
        }
        else if ([operateStr isEqualToString:@*])
        {
            oper = [[OperationMultiply alloc] init];
        }
        else if ([operateStr isEqualToString:@/])
        {
            oper = [[OperationDivide alloc] init];
        }
        return oper;
    }
    
    @end
    

    这里, 通过工厂类创建了运算方法的具体类。
    而我们在客户端部分, 只要传入对应的方法即可, 无需知道它的具体实现过程, 如下:

    - (IBAction)clickingOperation:(id)sender
    {
        NSString* strFirstNum = self.firstNumTextField.text;
        NSString* strSecondNum = self.secondNumTextField.text;
        Operation* oper;
        oper = [OperationFactory createOperate:self.operationTextField.text];
        oper.firstNum = [strFirstNum doubleValue];
        oper.secondNum = [strSecondNum doubleValue];
        self.resultTextField.text = [NSString stringWithFormat:@%f,[oper getResult]];
    
    }
    

    通过简单工厂模式的重构,这样我们就实现了低耦合度的代码结构,做到了对扩展开放,对修改关闭。如果再增加任何的操作方法,只需要继承操作方法父类,新建一个操作子类,并且在工厂方法里面多加一个if else的判断即可。怎么样很简单吧。
    大概就是这样, 现在做个总结:

    工厂类(Simple Factory): 只包含了创建具体类的静态方法。抽象产品(Product):定义简单工厂中要返回的产品。具体产品(ConcreteProduct):具体产品。我们用一张类图描述这个模式。

    定义:简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法);简单工厂模式可以理解为负责生产对象的一个类,称为“工厂类”。

                                                http://www.jellythink.com/archives/tag/designpattern/page/2 这个是原创博客的分享网站,讲的设计模式通俗易懂,很好理解,两者配合学习,应该效果更好!

    三。总结

    优点:
    职责单一,实现简单,且实现了客户端代码与具体实现的解耦。工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。缺点:
    由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。因此它是违背开放封闭原则的。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;注:这些缺点在工厂方法模式中得到了一定的克服。
    使用场景:工厂类负责创建的对象比较少;客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

    学习的路上, 与君共勉

     

    - (3)简单工厂模式 一。简述 简单工厂模式(FACTORY),通过面向对象的封装,继承和多态来降低程序的耦合度。将一个具体类的实...

    这里, 客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象。

    概括:Concrete Product 具有共同的父类Product。工厂类Factory只有一个,没有子父类,通过向Factory的static方法中传入不同的参数,得到返回的不同的Concrete Product。

          工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。

    总结:一个抽象产品类,可以派生出多个具体产品类。一个具体工厂类,通过往此工厂的static方法中传入不同参数,产出不同的具体产品类实例。

          做了一个windows 8平台的阅读器。首先,需要将电子书中的内容渲染到屏幕上,而电子书每一页都包含各种各样的内容,比如:图形、图像和文字等等;不同的内容,就是不同的对象;在将不同的内容渲染到屏幕上之前,就需要new操作,建立不同的对象,然后再在屏幕上进行描绘。这个时候,就需要进行很多new操作,new操作分布在代码的不同地方,管理起来很麻烦,而且也很乱,到后期扩展和维护的时候,有的时候,对象多的让开发人员不知道这个对象是干什么的,这就增加了难度;同时,new操作,都会有对应的异常处理,最后,就会发现,在代码中,new了一个对象,然后,就跟着一段异常处理代码,这时编码变的极其混乱和臃肿。那么怎么办?怎么办?此时,我们需要一个新的类,专门从事对象的建立和释放,之后,对象的各种操作,和这个类没有任何关系。这个专门建立对象的类,向外暴漏创建对象的接口,供外部调用。

    图片 4

    对于工厂模式,具体上可以分为三类:

    简单工厂模式 UML类图

    1. 简单工厂模式;
    2. 工厂方法模式;
    3. 抽象工厂模式。

    优点:

    对于上面的三种工厂模式,从上到下逐步抽象,并且更具一般性。

    1.将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;

    UML类图

    图片 5

    ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象。

    2.把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。

    适用场合

    1. 在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;
    2. 由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。

      #include #include using namespace std;

      typedef enum ProductTypeTag {

      TypeA,
      TypeB,
      TypeC
      

      }PRODUCTTYPE;

      // Here is the product class class Product { public:

      virtual void Show() = 0;
      

      };

      class ProductA : public Product { public:

      void Show()
      {
          cout<<"I'm ProductA"<<endl;
      }
      

      };

      class ProductB : public Product { public:

      void Show()
      {
          cout<<"I'm ProductB"<<endl;
      }
      

      };

      class ProductC : public Product { public:

      void Show()
      {
          cout<<"I'm ProductC"<<endl;
      }
      

      };

      // Here is the Factory class class Factory { public:

      Product* CreateProduct(PRODUCTTYPE type)
      {
          switch (type)
          {
          case TypeA:
              return new ProductA();
      
          case TypeB:
              return new ProductB();
      
          case TypeC:
              return new ProductC();
      
          default:
              return NULL;
          }
      }
      

      };

      int main(int argc, char *argv[]) {

      // First, create a factory object
      Factory *ProductFactory = new Factory();
      Product *productObjA = ProductFactory->CreateProduct(TypeA);
      if (productObjA != NULL)
          productObjA->Show();
      
      Product *productObjB = ProductFactory->CreateProduct(TypeB);
      if (productObjB != NULL)
          productObjB->Show();
      
      Product *productObjC = ProductFactory->CreateProduct(TypeC);
      if (productObjC != NULL)
          productObjC->Show();
      
      delete ProductFactory;
      ProductFactory = NULL;
      
      delete productObjA;
      productObjA = NULL;
      
      delete productObjB;
      productObjB = NULL;        
      
      delete productObjC;
      productObjC = NULL;
      
      return 0;
      

      }

         

          由于简单工厂模式的局限性,比如:工厂现在能生产ProductA、ProductB和ProductC三种产品了,此时,需要增加生产ProductD产品;那么,首先是不是需要在产品枚举类型中添加新的产品类型标识,然后,修改Factory类中的switch结构代码。是的,这种对代码的修改,对原有代码的改动量较大,易产生编码上的错误(虽然很简单,如果工程大了,出错也是在所难免的!!!)。这种对代码的修改是最原始,最野蛮的修改,本质上不能称之为对代码的扩展。同时,由于对已经存在的函数进行了修改,那么以前进行过的测试,都将是无效的,所有的测试,都将需要重新进行,所有的代码都需要进行重新覆盖。这种,增加成本,不能提高效率的事情,在公司是绝对不允许的(除非昏庸的PM)。出于种种原因,简单工厂模式,在实际项目中使用的较少。那么该怎么办?怎么办呢?需要对原有代码影响降到最小,同时能对原有功能进行扩展。

    缺点:

    UML类图

          那么今天介绍的工厂方法模式,就隆重登场了。它只是对简单工厂模式的扩展,在GOF的介绍中,它们是合并在一起的,而我则是单独分开进行讲解的,就是为了区分二者的利弊,便于大家在实际项目中进行更好的把握与应用。工厂方法模式是在简单工厂模式的基础上,对“工厂”添加了一个抽象层。将工厂共同的动作抽象出来,作为抽象类,而具体的行为由子类本身去实现,让子类去决定生产什么样的产品。

    图片 6

          如图,FactoryA专心负责生产ProductA,FactoryB专心负责生产ProductB,FactoryA和FactoryB之间没有关系;如果到了后期,如果需要生产ProductC时,我们则可以创建一个FactoryC工厂类,该类专心负责生产ProductC类产品。由于FactoryA、FactoryB和FactoryC之间没有关系,当加入FactoryC加入时,对FactoryA和FactoryB的工作没有产生任何影响,那么对代码进行测试时,只需要单独对FactoryC和ProductC进行单元测试,而FactoryA和FactoryB则不用进行测试,则可省去大量无趣无味的测试工作。

    1.工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;

    适用场合

          工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

    1. 在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;
    2. 产品结构较复杂的情况下,可以使用工厂方法模式;

    由于使用设计模式是在详细设计时,就需要进行定夺的,所以,需要权衡多方面的因素,而不能为了使用设计模式而使用设计模式。

    #include <iostream>
    using namespace std;
    
    class Product
    {
    public:
        virtual void Show() = 0;
    };
    
    class ProductA : public Product
    {
    public:
        void Show()
        {
            cout<< "I'm ProductA"<<endl;
        }
    };
    
    class ProductB : public Product
    {
    public:
        void Show()
        {
            cout<< "I'm ProductB"<<endl;
        }
    };
    
    class Factory
    {
    public:
        virtual Product *CreateProduct() = 0;
    };
    
    class FactoryA : public Factory
    {
    public:
        Product *CreateProduct()
        {
            return new ProductA ();
        }
    };
    
    class FactoryB : public Factory
    {
    public:
        Product *CreateProduct()
        {
            return new ProductB ();
        }
    };
    
    int main(int argc , char *argv [])
    {
        Factory *factoryA = new FactoryA ();
        Product *productA = factoryA->CreateProduct();
        productA->Show();
    
        Factory *factoryB = new FactoryB ();
        Product *productB = factoryB->CreateProduct();
        productB->Show();
    
        if (factoryA != NULL)
        {
            delete factoryA;
            factoryA = NULL;
        }
    
        if (productA != NULL)
        {
            delete productA;
            productA = NULL;
        }
    
        if (factoryB != NULL)
        {
            delete factoryB;
            factoryB = NULL;
        }
    
        if (productB != NULL)
        {
            delete productB;
            productB = NULL;
        }
        return 0;
    }
    

          C 设计模式——工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理;由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的产品(不继承自Product)时,发现工厂方法是心有余而力不足。

          举个例子来说:一个显示器电路板厂商,旗下的显示器电路板种类有非液晶的和液晶的;这个时候,厂商建造两个工厂,工厂A负责生产非液晶显示器电路板,工厂B负责生产液晶显示器电路板;工厂一直就这样运行着。有一天,总经理发现,直接生产显示器的其余部分也挺挣钱,所以,总经理决定,再建立两个工厂C和D;C负责生产非液晶显示器的其余部件,D负责生产液晶显示器的其余部件。此时,旁边参谋的人就说了,经理,这样做不好,我们可以直接在工厂A中添加一条负责生产非液晶显示器的其余部件的生产线,在工厂B中添加一条生产液晶显示器的其余部件的生产线,这样就可以不用增加厂房,只用将现有厂房进行扩大一下,同时也方便工厂的管理,而且生产非液晶显示器电路板的技术人员对非液晶显示的其余部件的生产具有指导的作用,生产液晶显示器电路板也是同理。总经理发现这是一个不错的主意。

          再回到软件开发的过程中来,工厂A和B就是之前所说的C 设计模式——工厂方法模式;总经理再次建立工厂C和D,就是重复C 设计模式——工厂方法模式,只是生产的产品不同罢了。这样做的弊端就如参谋所说的那样,增加了管理成本和人力成本。在面向对象开发的过程中,是很注重对象管理和维护的,对象越多,就越难进行管理和维护;如果工厂数量过多,那么管理和维护的成本将大大增加;虽然生产的是不同的产品,但是可以二者之间是有微妙的关系的,如参谋所说,技术人员的一些技术经验是可以借鉴的,这就相当于同一个类中的不同对象,之间是可以公用某些资源的。那么,增加一条流水线,扩大厂房,当然是最好的主意了。

    实际问题已经得到了解决,那么如何使用设计模式模拟这个实际的问题呢?那就是接下来所说的抽象工厂模式。

    2.违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。

    UML类图

           现在要讲的抽象工厂模式,就是工厂方法模式的扩展和延伸,但是抽象工厂模式,更有一般性和代表性;它具有工厂方法具有的优点,也增加了解决实际问题的能力。

    图片 7

           如图所示,抽象工厂模式,就好比是两个工厂方法模式的叠加。抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。在工厂Factory中的每一个方法,就好比是一条生产线,而生产线实际需要生产什么样的产品,这是由Factory1和Factory2去决定的,这样便延迟了具体子类的实例化;同时集中化了生产线的管理,节省了资源的浪费。

    3.简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。

    适用场合

           工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

     

    #include <iostream>
    using namespace std;
    
    // Product A
    class ProductA
    {
    public:
        virtual void Show() = 0;
    };
    
    class ProductA1 : public ProductA
    {
    public:
        void Show()
        {
            cout<<"I'm ProductA1"<<endl;
        }
    };
    
    class ProductA2 : public ProductA
    {
    public:
        void Show()
        {
            cout<<"I'm ProductA2"<<endl;
        }
    };
    
    // Product B
    class ProductB
    {
    public:
        virtual void Show() = 0;
    };
    
    class ProductB1 : public ProductB
    {
    public:
        void Show()
        {
            cout<<"I'm ProductB1"<<endl;
        }
    };
    
    class ProductB2 : public ProductB
    {
    public:
        void Show()
        {
            cout<<"I'm ProductB2"<<endl;
        }
    };
    
    // Factory
    class Factory
    {
    public:
        virtual ProductA *CreateProductA() = 0;
        virtual ProductB *CreateProductB() = 0;
    };
    
    class Factory1 : public Factory
    {
    public:
        ProductA *CreateProductA()
        {
            return new ProductA1();
        }
    
        ProductB *CreateProductB()
        {
            return new ProductB1();
        }
    };
    
    class Factory2 : public Factory
    {
        ProductA *CreateProductA()
        {
            return new ProductA2();
        }
    
        ProductB *CreateProductB()
        {
            return new ProductB2();
        }
    };
    
    int main(int argc, char *argv[])
    {
        Factory *factoryObj1 = new Factory1();
        ProductA *productObjA1 = factoryObj1->CreateProductA();
        ProductB *productObjB1 = factoryObj1->CreateProductB();
    
        productObjA1->Show();
        productObjB1->Show();
    
        Factory *factoryObj2 = new Factory2();
        ProductA *productObjA2 = factoryObj2->CreateProductA();
        ProductB *productObjB2 = factoryObj2->CreateProductB();
    
        productObjA2->Show();
        productObjB2->Show();
    
        if (factoryObj1 != NULL)
        {
            delete factoryObj1;
            factoryObj1 = NULL;
        }
    
        if (productObjA1 != NULL)
        {
            delete productObjA1;
            productObjA1= NULL;
        }
    
        if (productObjB1 != NULL)
        {
            delete productObjB1;
            productObjB1 = NULL;
        }
    
        if (factoryObj2 != NULL)
        {
            delete factoryObj2;
            factoryObj2 = NULL;
        }
    
        if (productObjA2 != NULL)
        {
            delete productObjA2;
            productObjA2 = NULL;
        }
    
        if (productObjB2 != NULL)
        {
            delete productObjB2;
            productObjB2 = NULL;
        }
    }
    

     

    二 、工厂方法模式

    本文由1010cc时时彩经典版发布于操作系统,转载请注明出处:二种工厂格局计算,轻便工厂格局

    关键词: