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

    • 简单工厂模式概述
    1. 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
    2. 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method)
    3. 需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程
    4. 例如,我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家 披萨店就可以看做工厂(Factory),而生产出来的披萨被成为产品(Product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂模式
    • 简单工厂模式的结构与实现
    •  结构
    1. Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
    2. Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象
    3. ConcreteProduct(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法(有关抽象类)
    • 实现
       1 abstract class Product
       2 {
       3     public void MethName()
       4     {
       5         //公共方法的实现
       6     }
       7     public abstract void MethodDiff();
       8     //声明抽象业务方法
       9 }
      10 class ConcreteProductA : Product
      11 {
      12     public override void MethodDiff()
      13     {
      14         //业务方法的实现
      15     }
      16 }
      17 
      18 class Factory
      19 {    
      20     public static Product GetProduct(string arg)
      21     {
      22         Product product =  null;
      23         if(arg.Equals("A")
      24         {
      25             product = new ConcreteProductA();
      26             //init
      27         }
      28         else if(arg.Equals("B"))
      29         {
      30             product = new ConcreteProductB();
      31             //init
      32         }
      33         else
      34         {
      35         ....//其他情况
      36         }
      37         return product;
      38     }
      39 }
      40 
      41 class Program
      42 {
      43     static void Main(string[] args)
      44     {
      45         Product product;
      46         product = Factory.GetProduct("A");//工厂类创建对象
      47         Product.MethName();
      48         product.MethodDiff();
      49     }
      50 }
    • 简单工厂模式的简化
    1. 为了简化简单工厂模式,将抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中
    2. 客户端可以调用产品父类的静态工厂方法,根据不同的参数创建不同类型的产品子类对象。
    • 简单工厂模式的优缺点和适用环境  

    • 简单工厂模式的优点

        (1)工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
        (2)客户端无需知道所创建具体产品的类名,只需知道参数即可
        (3)也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)

    • 简单工厂模式的缺点

        (1)工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
        (2)使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
        (3)系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
        (4)简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。

    • 简单工厂模式的适用环境

        (1)工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂

        (2)客户端只知道传入工厂类的参数,对如何创建对象不关心

    • 简单案例
    1. 题目:

      使用简单工厂模式设计一个可以创建不同几何图形(Shape),如Circle,Rectangle,Triangle等绘图工具类,每个几何图形均具有绘制Draw()和擦除Erase()两个方法
      要求在绘制不支持的几何图形时,抛出一个UnsuppShapeException异常,绘制类图并使用C#语言实现。

    2. UML:

    3.   1 using System;
        2 using System.Collections.Generic;
        3 using System.Linq;
        4 using System.Text;
        5 /*使用简单工厂模式设计一个可以创建不同几何图形(Shape),如Circle,Rectangle,Triangle等绘图工具类,每个几何图形均具有绘制Draw()和擦除Erase()两个方法
        6  * 要求在绘制不支持的几何图形时,抛出一个UnsuppShapeException异常,绘制类图并使用C#语言实现。
        7 */
        8 
        9 namespace SimpleShapeFactory
       10 {
       11     public interface InShape//图形接口 抽象产品类
       12     {
       13         void Draw();
       14         void Erase();
       15     }
       16 
       17     public class Circle : InShape//圆形类,具体产品类
       18     {
       19         private static int count;   //生成图形计数
       20         string radious;
       21         public Circle()//构造
       22         {
       23             Console.WriteLine("Create Circle");
       24             Console.WriteLine("Input the radious of Circle:");
       25             radious = Console.ReadLine();
       26         }
       27         public void Draw()//实现接口方法
       28         {
       29             int Radious = int.Parse(radious);
       30             Console.WriteLine("Display circle " + (++count) +" information:");
       31             Console.WriteLine("Circle "+ count+ " circumference:" + 2 * Radious * 3.14159);
       32             Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious);
       33         }
       34         public void Erase()//实现接口方法
       35         {
       36             while (true)
       37             {
       38                 Console.WriteLine("Erase current shape(y/n)?");
       39                 string choose;
       40                 choose = Console.ReadLine();
       41                 if (choose.Equals("y") || choose.Equals("Y"))
       42                 {
       43                     Console.WriteLine("Erase Circle "+count +" successfully!");
       44                     count--;
       45                     break;
       46                 }
       47                 else if (choose.Equals("n") || choose.Equals("N"))
       48                 {
       49                     Console.WriteLine("Circle "+ count+" successfully saved!");
       50                     break;
       51                 }
       52                 else
       53                 {
       54                     Console.WriteLine("Input error, re-enter!");
       55                 }
       56             }   
       57         }
       58     }
       59 
       60     class Rectangle : InShape//矩形类,具体产品类
       61     {
       62         private static int count = 0;//生成图形计数
       63         string length;
       64         string wideth;
       65         public Rectangle()//构造
       66         {
       67             Console.WriteLine("Create Rectangle");
       68             Console.WriteLine("Input the length and wideth of Rectangle:");
       69             length = Console.ReadLine();
       70             wideth = Console.ReadLine();
       71         }
       72         public void Draw()//实现接口方法
       73         {
       74             int Length = int.Parse(length);
       75             int Wideth = int.Parse(wideth);
       76             Console.WriteLine("Display rectangle " + (++count) + " information:");
       77             Console.WriteLine("Rectangle "+ count + "circumference:" + 2 * Length * Wideth);
       78             Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth);
       79            
       80         }
       81         public void Erase()//实现接口方法
       82          {
       83              while (true)
       84              {
       85                  Console.WriteLine("Erase current shape(y/n)?");
       86                  string choose;
       87                  choose = Console.ReadLine();
       88                  if (choose.Equals("y") || choose.Equals("Y"))
       89                  {
       90                      Console.WriteLine("Erase rectangle "+count+ "successfully!");
       91                      --count;
       92                      break;
       93                  }
       94                  else if (choose.Equals("n") || choose.Equals("N"))
       95                  {
       96                      Console.WriteLine("Rectangle "+ count+" successfully saved!");
       97                      break;
       98                  }
       99                  else
      100                  {
      101                      Console.WriteLine("Input error, re-enter!");
      102                  }
      103              }   
      104         }
      105     }
      106 
      107     class Triangle : InShape//三角形类,具体产品类
      108     {
      109         private static int count = 0;//生成图形计数
      110         string lengtha;
      111         string lengthb;
      112         string lengthc;
      113         public Triangle()//构造
      114         {
      115             Console.WriteLine("Create Triangle");
      116             Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:");
      117             lengtha = Console.ReadLine();
      118             lengthb = Console.ReadLine();
      119             lengthc = Console.ReadLine();
      120 
      121         }
      122         public void Draw()//实现接口方法
      123         {
      124             int Lengtha = int.Parse(lengtha);
      125             int Lengthb = int.Parse(lengthb);
      126             int Lengthc = int.Parse(lengthc);
      127             if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha))
      128             {
      129                 double S = (Lengtha + Lengthb + Lengthc) * 0.5;
      130                 double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc));
      131                 Console.WriteLine("Display triangle "+ (++count)+" information:");
      132                 Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc));
      133                 Console.WriteLine("Triangle "+ count +" area:" + area);
      134                 Erase();
      135             }
      136             else
      137             {
      138                 Console.WriteLine("Create triangle failed!");
      139             }
      140         }
      141         public void Erase()//实现接口方法
      142          {
      143              while (true)
      144              {
      145                  Console.WriteLine("Erase shape(y/n)?");
      146                  string choose;
      147                  choose = Console.ReadLine();
      148                  if (choose.Equals("y") || choose.Equals("Y"))
      149                  {
      150                      Console.WriteLine("Erase tirangle " +count +" successfully!");
      151                      --count;
      152                      break;
      153                  }
      154                  else if (choose.Equals("n") || choose.Equals("N"))
      155                  {
      156                      Console.WriteLine("Triangle "+ count +" successfully saved!");
      157                      break;
      158                  }
      159                  else
      160                  {
      161                      Console.WriteLine("Input error, re-enter!");
      162                  }
      163              }   
      164         }
      165     }
      166 
      167     class ShapeFactory//图形工厂类,充当工厂类
      168     {
      169         public static  InShape Getshape(string type)//静态工厂方法
      170         {
      171             InShape shape;
      172             shape = null;
      173             if (type.Equals("Circle"))
      174             {
      175                 shape = new Circle();
      176                 Console.WriteLine("Init set Circle");
      177                 shape.Draw();
      178                 shape.Erase();
      179             }
      180             else if(type.Equals("Rectangle"))
      181             {
      182                 shape = new Rectangle();
      183                 Console.WriteLine("Init set Rectangle");
      184                 shape.Draw();
      185                 shape.Erase();
      186             }
      187             else if (type.Equals("Triangle"))
      188             {
      189                 shape = new Triangle();
      190                 Console.WriteLine("Init set Triangle");
      191                 shape.Draw();
      192                 
      193             }
      194             else//异常 这里我应该声明调用异常处理类的,那样会更好些
      195             {
      196                 Console.WriteLine("UnsupportShapeException!");
      197                 Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! ");
      198             }
      199             return shape;
      200         }
      201     }
      202 
      203     class Program//客户端测试类
      204     {
      205         static void Main(string[] args)
      206         {
      207             while (true)
      208             {
      209                 InShape shape;
      210                 Console.WriteLine("Please input the shape you want to create");
      211                 string str = Console.ReadLine();
      212                 shape = ShapeFactory.Getshape(str);//通过静态工厂方法创建产品
      213                 Console.ReadLine();
      214             }
      215         }
      216     }
      217 }
    4. 运行结果:
    5. 自我感觉写的一般般,如有不对的地方,欢迎指正。
  • 相关阅读:
    大型项目使用Automake/Autoconf完成编译配置
    用C语言编写Windows服务程序的五个步骤
    RPC的发展历史(本质就是双方定义好协议,传递参数后远程调用)
    libuv和libev 异步I/O库的比较
    zlog 程序日志的库 交叉编译(Linux生成ARM库,观察执行步骤)
    应用服务
    EvnetBus
    this指向
    CPU使用率
    数据量小,创建索引有必要吗
  • 原文地址:https://www.cnblogs.com/ygsworld/p/10649491.html
Copyright © 2011-2022 走看看