简单工厂模式(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 : Product11 {12     public override void MethodDiff()13     {14         //业务方法的实现15     }16 }17 18 class Factory19 {
    20     public static Product GetProduct(string arg)21     {22         Product product =  null;23         if(arg.Equals("A")24         {25             product = new ConcreteProductA();26             //init27         }28         else if(arg.Equals("B"))29         {30             product = new ConcreteProductB();31             //init32         }33         else34         {35         ....//其他情况36         }37         return product;38     }39 }40 41 class Program42 {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                  else100                  {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             else137             {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                  else160                  {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. 运行结果:

(0)

相关推荐

  • PAT (Basic Level) Practice 1001

    using System; namespace _1001 { class Program { static void Main(string[] args) { // bool b= int.Try ...

  • 大白话简单工厂模式 (Simple Factory Pattern)

    从买车经历说起 毕业两年,码农张小两口无法忍受挤公交,凌晨起床抢火车票的痛苦,遂计划买车.逛了多家4S店,最终定下日产某车型的轿车.4S店接受订单后,向工厂说明车型,工厂随后进行汽车制造,运输到4S店 ...

  • 工厂模式(Factory Pattern)

    Factory Pattern 创造型设计模式,提供一个创造对象的方式,在工厂模式中,创造对象的逻辑不对外暴露创建,只提供一个创建的接口. 定义一个创建对象的接口,其子类决定去创建哪一个实例对象,创建 ...

  • 设计模式之工厂模式(factory pattern)

    工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式.该模式用于封装和管理对象的创建,是一种创建型模式.本文从一 ...

  • 抽象工厂模式(Abstract Factory Pattern)

    抽象工厂模式概述 定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类 抽象工厂抽象工厂,顾名思义,就是比工厂模式更抽象的工厂模式.在工厂模式中,一个具体工厂只负责生产一个具体产品 ...

  • 【6/25】使用简单工厂模式(Simple Factory Pattern)改写Page基类

    这是<小游戏从0到1设计模式重构>系列内容第6篇,所有源码及资料在"程序员LIYI"公号回复"小游戏从0到1"获取. 工厂模式有三个姐妹:简单工厂模 ...

  • PHP设计模式之简单工厂模式

    PHP设计模式之简单工厂模式 先从简单工厂入门,不管是面试还是被他人面试,在问到设计模式的时候,大多数人都会提到工厂模式.毫无疑问,工厂相关的几种模式在设计模式中是最出名的也是应用比较广泛的一种模式. ...

  • [PHP小课堂]PHP设计模式之简单工厂模式

    PHP设计模式之工厂方法模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 【C++设计模式一】C++简单工厂模式

    (1)定义 定义一个简单工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类. (2)结构 简单工厂模式有以下的结构: 工厂(Factory):根据客户提供的具体产品类的参数 ...

  • 【重温设计模式】之002简单工厂模式

    [重温设计模式系列源码] 简单工厂模式 基本原理 含义 简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法). 在现实生活中,工厂是生产产品的, 同样的,在设计模式中,一个负责生产" ...