欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

简单工厂模式(Simple Factory Pattern)

程序员文章站 2022-07-02 17:58:15
简单工厂模式概述 简单工厂模式的结构与实现 结构: 实现 1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的实现 6 } 7 public abstract void MethodDiff(); 8 //声明抽象业务 ......
  • 简单工厂模式概述
  1. 定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父亲
  2. 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(static factory method)
  3. 需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程
  4. 例如,我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家 披萨店就可以看做工厂(factory),而生产出来的披萨被成为产品(product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂模式
  • 简单工厂模式的结构与实现
  •  结构简单工厂模式(Simple Factory Pattern)
  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. 简单工厂模式(Simple Factory Pattern)
  3. 客户端可以调用产品父类的静态工厂方法,根据不同的参数创建不同类型的产品子类对象。
  • 简单工厂模式的优缺点和适用环境
  1. 简单工厂模式的优点

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

    2. 简单工厂模式的缺点

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

    3. 简单工厂模式的适用环境

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

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

  • 简单案例
  1. 题目:

    使用简单工厂模式设计一个可以创建不同几何图形(shape),如circle,rectangle,triangle等绘图工具类,每个几何图形均具有绘制draw()和擦除erase()两个方法
    要求在绘制不支持的几何图形时,抛出一个unsuppshapeexception异常,绘制类图并使用c#语言实现。

  2. uml:
  3. 简单工厂模式(Simple Factory Pattern)
  4.   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 }
  5. 运行结果:
  6. 简单工厂模式(Simple Factory Pattern)
  7. 自我感觉写的一般般,如有不对的地方,欢迎指正。