做企划的网站,关于网站建设的请示范文,本周的新闻大事10条,怎么提高网站权重本文首发于博客园,地址:http://www.cnblogs.com/beniao/archive/2008/08/09/1263318.html 一、模式概述 从设计模式的类型上来说#xff0c;简单工厂模式是属于创建型模式#xff0c;又叫做静态工厂方法#xff08;Static Factory Method#xff09;模式#xff0c;但不属…本文首发于博客园,地址:http://www.cnblogs.com/beniao/archive/2008/08/09/1263318.html 一、模式概述 从设计模式的类型上来说简单工厂模式是属于创建型模式又叫做静态工厂方法Static Factory Method模式但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式可以理解为是不同工厂模式的一个特殊实现学习了此模式可以为后面的很多中模式打下基础。那好我们就来了解下什么是简单工厂模式 我们来分析一个现实生活中的案例每天早晨起床洗唰后是干什么呢吃早餐这里只针对在外吃早餐的上班族、坐车我是穷人只有坐公交当然很多有钱人都自己有车这里不考虑这些去公司上班、是这样的吗OK下面就来分析下吃早餐中的故事大家先看看下面这个图 当我们在买早餐的时候早餐店里都卖得写什么呢这点你有注意吗众多食品摆在那里你只对营业员说你要何种食品他便会知道给你拿什么样的食品给你这说明什么呢如果用面向对象的思想来理解的话营业员在这里就充当了一个工厂的角色他负责根据你的请求返回你需要的食品对象。而这一点正是简单工厂模式的意图。 二、模式意图 简单工厂模式根据提供给他的数据返回几个可能类中的一个类的实例。 三、模式UML图 下面是简单工厂模式的示意性UML图 如上图简单工厂模式UML我画了两种详细如下 ① 只有一个产品对象的简单工厂模式。 ② 带有一个抽象产品对象的简单工厂模式。 四、模式参与者 工厂Factory角色接受客户端的请求通过请求负责创建相应的产品对象。 抽象产品AbstractProduct角色: 是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。 具体产品ConcreteProduct对象工厂模式所创建的对象都是这个角色的实例。 五、模式实现 我们通过上面的分析已经清晰的知道了工厂模式中的各种角色和职责那工厂模式通过代码是怎么实现的呢OK下面将继续分析上面的吃早餐中的故事做一个简单的示例实现。 1、首先我们来看看只有一个产品对象的简单工厂模式的实现。其实这很好理解就当店里只卖一种食品这里以馒头为例。 1 /// summary 2 /// 馒头 3 /// /summary 4 public class SteamedBread 5 { 6 /// summary 7 /// 构造方法 8 /// /summary 9 public SteamedBread() 10 { } 11 12 /// summary 13 /// 销售价格 14 /// /summary 15 private double price0.5; 16 public double Price 17 { 18 get { return price; } 19 set { price value; } 20 } 21 }OK产品对象建立好了下面就是创建工厂(Factory)对象了。 1 /// summary 2 /// 工厂角色 3 /// /summary 4 public class Factory 5 { 6 /// summary 7 /// 创建一个馒头(SteamedBread)对象 8 /// /summary 9 /// returns/returns 10 public static SteamedBread CreateInstance() 11 { 12 return new SteamedBread(); 13 } 14 }此时客户端可以这样来调用
1 public class Client 2 { 3 public static void Main(string[] args) 4 { 5 //通过工厂创建一个产品的实例 6 SteamedBread sb Factory.CreateInstance(); 7 Console.WriteLine(馒头{0}元一个, sb.Price); 8 } 9 }如上就完成了一个简单工厂模式的简单实现一个产品和一个工厂工厂负责创建这个产品。但是者种实现有一定的缺陷为每一种产品创建一个静态方法来完成产品对象的创建如果有多个产品则需要定义多个静态方法分别返回不同的对象用设计原则来说的话这样的实现不符合依赖倒置原则(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接口改为继承此抽象类如下 1 public class SteamedBread : Evolution 2 { 3 public SteamedBread() 4 { 5 this.Price 0.5; //在构造方法里初始话属性的值 6 } 7 } 8 9 public class SteamedStuffed : Evolution 10 { 11 public SteamedStuffed() 12 { 13 this.Price 0.6; 14 } 15 }通过上面的演化此时客户端的调用如下
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.中文版《设计模式精解 张逸 著《软件设计精要与模式》