一、模式概述
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现,学习了此模式可以为后面的很多中模式打下基础。那好,我们就来了解下什么是简单工厂模式?
我们来分析一个现实生活中的案例,每天早晨起床洗唰后是干什么呢?吃早餐(这里只针对在外吃早餐的上班族)、坐车(我是穷人只有坐公交,当然很多有钱人都自己有车,这里不考虑这些)去公司上班、是这样的吗?OK,下面就来分析下吃早餐中的故事,大家先看看下面这个图:
当我们在买早餐的时候,早餐店里都卖得写什么呢?这点你有注意吗?众多食品摆在那里,你只对营业员说你要何种食品,他便会知道给你拿什么样的食品给你,这说明什么呢?如果用面向对象的思想来理解的话,营业员在这里就充当了一个工厂的角色,他负责根据你的请求返回你需要的食品对象。而这一点正是简单工厂模式的意图。
二、模式意图
简单工厂模式根据提供给他的数据,返回几个可能类中的一个类的实例。
三、模式UML图
下面是简单工厂模式的示意性UML图:
如上图,简单工厂模式UML我画了两种,详细如下:
① 只有一个产品对象的简单工厂模式。
② 带有一个抽象产品对象的简单工厂模式。
四、模式参与者
工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象。
抽象产品(AbstractProduct)角色: 是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。
具体产品(ConcreteProduct)对象:工厂模式所创建的对象都是这个角色的实例。
五、模式实现
我们通过上面的分析,已经清晰的知道了工厂模式中的各种角色和职责,那工厂模式通过代码是怎么实现的呢?OK,下面将继续分析上面的吃早餐中的故事,做一个简单的示例实现。
1、首先我们来看看只有一个产品对象的简单工厂模式的实现。其实这很好理解,就当店里只卖一种食品,这里以馒头为例。
写道
/// <summary>
/// 馒头
/// </summary>
public class SteamedBread
{
/// <summary>
/// 构造方法
/// </summary>
public SteamedBread()
{ }
/// <summary>
/// 销售价格
/// </summary>
private double price=0.5;
public double Price
{
get { return price; }
set { price = value; }
}
}
OK,产品对象建立好了,下面就是创建工厂(Factory)对象了。
/// <summary>
/// 工厂角色
/// </summary>
public class Factory
{
/// <summary>
/// 创建一个馒头(SteamedBread)对象
/// </summary>
/// <returns></returns>
public static SteamedBread CreateInstance()
{
return new SteamedBread();
}
}
此时,客户端可以这样来调用:
public class Client
{
public static void Main(string[] args)
{
//通过工厂创建一个产品的实例
SteamedBread sb = Factory.CreateInstance();
Console.WriteLine("馒头{0}元一个!", sb.Price);
}
}
如上就完成了一个简单工厂模式的简单实现,一个产品和一个工厂,工厂负责创建这个产品。但是者种实现有一定的缺陷,为每一种产品创建一个静态方法来完成产品对象的创建,如果有多个产品则需要定义多个静态方法分别返回不同的对象,用设计原则来说的话这样的实现不符合依赖倒置原则(DIP)。如果系统里只有一个单独的产品对象,那么采用这种实现是完全可以的。UML图如下:
2、带抽象产品(AbstractProduct)角色的简单工厂模式实现
从上面分析中得知,这种实现得为每一种产品创建一个静态方法来完成产品对象的创建。虽然带有简单工厂的性质,但是又好象不能够完全体现出简单工厂模式的意图。简单工厂的意图是:根据提供给他的数据,返回几个可能类中的一个类的实例。根据意图出发进行分析,要实现完全满足简单工厂模式意图的程序,也就得根据提供给工厂的数据,让工厂根据这个数据来进行判断,然后返回相应的对象。OK,看看是下面这样的吗?
示意性代码如下:
1 /// <summary>
2 /// 食品接口----扮演抽象产品角色
3 /// </summary>
4 public interface IFood
5 {
6 /// <summary>
7 /// 每种食品都有销售价格,这里应该作为共性提升到父类或是接口来
8 /// 由于我们只需要得到价格,所以这里就只提供get属性访问器
9 /// </summary>
10 double price{get;}
11 }
12 ------------------------------------------------------------------------------------
13 /// <summary>
14 /// 馒头
15 /// </summary>
16 public class SteamedBread:IFood
17 {
18 /// <summary>
19 /// 构造方法
20 /// </summary>
21 public SteamedBread()
22 { }
23
24 public double price
25 {
26 get
27 {
28 return 0.5;
29 }
30 }
31 }
32 ------------------------------------------------------------------------------------
33 /// <summary>
34 /// 包子
35 /// </summary>
36 public class SteamedStuffed:IFood
37 {
38 public SteamedStuffed()
39 { }
40
41 /// <summary>
42 /// 销售价格
43 /// </summary>
44 public double price
45 {
46 get
47 {
48 return 0.6; //0.6元一个
49 }
50 }
51 }
52 ------------------------------------------------------------------------------------
53 /// <summary>
54 /// 工厂角色
55 /// </summary>
56 public class Factory
57 {
58 /// <summary>
59 /// 创建一个馒头(SteamedBread)对象
60 /// </summary>
61 /// <returns></returns>
62 public static IFood CreateInstance(string key)
63 {
64 if (key == "馒头")
65 {
66 return new SteamedBread();
67 }
68 else
69 {
70 return new SteamedStuffed();
71 }
72 }
73 }
74 ------------------------------------------------------------------------------------
75 public class Client
76 {
77 public static void Main(string[] args)
78 {
79 //通过工厂创建一个产品的实例
80 IFood food = Factory.CreateInstance("馒头");
81 Console.WriteLine("馒头{0}元一个!", food.price);
82
83 food = Factory.CreateInstance("包子");
84 Console.WriteLine("包子{0}元一个!", food.price);
85 }
86 }
此时的设计就已经完全符合简单工厂模式的意图了。顾客(Client)对早餐店营业员(Factory)说,我要“馒头”,于是营业员便根据顾客所提供的数据(馒头),去众多食品中找,找到了然后就拿给顾客。
3、模式的演变实现
有些情况下Simple Factory可以由抽象产品角色扮演,一个抽象产品类同时是子类的工厂。也就是说,抽象产品角色扮演两种角色和职责,出了基本的定义还还兼任工厂角色的职责,负责产品的创建工作。这里我们在上面的例子基础上适当修改一下OK了,新建立一个抽象类(Evolution):
1 /// <summary>
2 /// 兼任抽象产品角色和工厂角色两种角色
3 /// </summary>
4 public abstract class Evolution
5 {
6 /// <summary>
7 /// 共性字段
8 /// </summary>
9 private double price;
10 public double Price
11 {
12 get { return price; }
13 set { price = value; }
14 }
15
16
17 public static Evolution CreateInstance(string key)
18 {
19 if (key == "馒头")
20 {
21 return new SteamedBread();
22 }
23 else
24 {
25 return new SteamedStuffed();
26 }
27 }
28 }
那现在,具体的产品对象的设计也应该修改了,把原来实现于IFood接口改为继承此抽象类,如下
public class SteamedBread : Evolution
2 {
3 public SteamedBread()
4 {
5 this.Price = 0.5; //在构造方法里初始话属性的值
6 }
7 }
9 public class SteamedStuffed : Evolution
10 {
11 public SteamedStuffed()
12 {
13 this.Price = 0.6;
14 }
通过上面的演化,此时客户端的调用如下:
1 public class Client
2 {
3 public static void Main(string[] args)
4 {
5 Evolution el = Evolution.CreateInstance("包子");
6 Console.WriteLine("包子{0}元一个!", el.Price);
7 }
8 }
UML草图如下:
在实际的开发中,这种演化是很适用的,可以说是一种编程技巧吧。
4、模式的其他演变
如果系统中只有唯一的一个具体产品对象,那么可以省略抽象产品角色。这一种其实也就是本钱前面的第一种模式实现。
如果抽象产品角色省略,那么工厂角色就可以与具体产品角色合并。也就是说一个产品类就是自身的工厂。这样把原有三个独立的角色:抽象产品角色、具体产品角色和工厂角色合并为一个,这个类自己负责创建自己的实例。
注:以上演变可以从上面的程序代码中直接修改而来,这里我就不贴代码了。
六、模式优缺点
工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。
当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
七、相关模式
工厂方法模式:每个产品由一个专门的工厂来负责创建。是一种只有唯一一个产品的实现,带有简单工厂的性质。
抽象工厂模式:大致和工厂方法相同。
单例模式:单例的实现和上面模式演变中的最后一种很相似,只要把构造器私有便OK。
八、参考资料
Addison-Wesley,1995,p.185. 中文版:《设计模式:可复用的面向对象软件的基础》 李英军等译.
Alan Sharroway & James r.Trott.中文版:《设计模式精解
张逸 著《软件设计精要与模式》
分享到:
相关推荐
本资料来源于吕震宇博客...C#设计模式(5)-Factory Method Pattern C#设计模式(4)-Simple Factory Pattern C#设计模式(3) - 设计原则(2) C#设计模式(2) - 设计原则(1) C#设计模式(1) - 面向对象基本概念复习
总的来说,这个"calculator-of-Simple-Factory-Pattern.rar_factory"项目展示了如何运用简单工厂模式来构建一个计算器系统,使得系统能够根据不同的计算需求动态地创建相应的计算器对象,同时也为未来的功能扩展打下...
六个创建型模式 简单工厂模式-Simple Factory Pattern 工厂三兄弟之简单工厂模式(一) 工厂三兄弟之简单工厂模式(二) 工厂三兄弟之简单工厂模式(三) 工厂三兄弟之简单工厂模式(四) 工厂方法模式-Factory ...
1. **模式定义**:简单工厂模式(Simple Factory Pattern)是一种将实例化过程封装到一个单独的类中,这个类被称为“工厂”,它负责创建用户需要的对象。工厂类可以根据传入的参数或条件来决定返回哪个类的实例。 2...
简单工厂模式是面向对象设计模式中的一种,它属于创建型模式,主要解决的是在系统中如何创建对象的问题。设计模式是软件开发中的经验总结,旨在提高代码的可重用性、可读性和可维护性。 在简单工厂模式中,一个工厂...
简单工厂模式(Simple Factory Pattern)是一种常用的创建型设计模式。它提供了一种方式来封装对象的创建过程,使得整个系统更加灵活,易于扩展。在简单工厂模式中,存在一个专门用于创建对象的工厂类,它负责根据...
1. **简单工厂模式**(Simple Factory Pattern):由一个静态方法或单例类负责创建对象,适用于对象种类较少且不会频繁变动的情况。 2. **工厂方法模式**(Factory Method Pattern):定义一个创建对象的接口,让...
简单工厂模式实际上不属于23个GoF模式,但它可以作为GoF的工厂方法模式(Factory Method)的一个引导。 UML: <<Interface>> ConcreteProduct Creator Product <------ --------------- <----- ----------...
赠送jar包:sentinel-transport-simple-http-1.8.0.jar; 赠送原API文档:sentinel-transport-simple-http-1.8.0-javadoc.jar; 赠送源代码:sentinel-transport-simple-http-1.8.0-sources.jar; 赠送Maven依赖信息...
在Java中,简单工厂模式适用于对象的创建过程较为固定或不复杂的情况。它定义一个公共的工厂类,根据传入的参数或者条件来决定返回哪个具体类的实例。这种方式降低了代码的耦合度,使得在不修改客户端代码的情况下,...
简单工厂模式是面向对象设计中的一种经典设计模式,它属于创建型模式,主要用来解决对象的创建问题。在Java编程中,简单工厂模式通过一个中心工厂类来负责创建相关的对象,而无需让客户端代码直接new具体的产品类。...
**简单工厂模式**是软件设计模式中的一种,属于创建型模式。在Java编程中,它是一种用于创建对象的简便方法,将对象的实例化过程封装到一个单独的工厂类中,使得客户端代码无需直接调用具体类的构造函数,而是通过...
简单工厂模式是软件设计模式中的一种基础模式,它属于创建型设计模式。在Java编程中,我们常常会遇到需要创建一系列相关或相互依赖的对象,而这些对象的创建过程可能会非常复杂。这时,简单工厂模式就提供了一种封装...
【描述】"Simple Factory Design-Pattern for Calculate Salary for VC6 project" 描述了项目的核心设计思想——简单工厂模式。这是一种创建型设计模式,它提供一个创建对象的接口,但允许子类决定实例化哪一个类。...
2. **简单工厂模式(Simple Factory Pattern)**: 简单工厂模式定义了一个专门的类来创建其他类的实例,通常是基于传入的参数。这种模式的角色包括工厂角色、抽象产品角色和具体产品角色。它满足单一职责原则,但...
赠送jar包:cxf-rt-frontend-simple-3.0.1.jar; 赠送原API文档:cxf-rt-frontend-simple-3.0.1-javadoc.jar; 赠送源代码:cxf-rt-frontend-simple-3.0.1-sources.jar; 赠送Maven依赖信息文件:cxf-rt-frontend-...
### 设计模式之工厂模式详解 #### 一、概述 工厂模式是一种常用的设计模式,属于创建型模式之一。它的核心思想在于将对象的创建过程封装起来,并通过特定的工厂类来实现对象的创建,以此达到降低系统耦合度的目的...