• 简单工厂模式概述

  1. 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
  2. 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method)
  3. 需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程

  1. 例如,我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家 披萨店就可以看做工厂(Factory),而生产出来的披萨被成为产品(Product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂模式
  • 简单工厂模式的结构与实现

  •  结构:

    implements怎么只实现一个方法_工厂类

  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:
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 }
  1. 运行结果:
  2. 自我感觉写的一般般,如有不对的地方,欢迎指正。