文档章节

『创建型』简单工厂SimpleFactory、工厂方法FactoryMethod、抽象工厂AbstractFactory

灰大羊
 灰大羊
发布于 2016/07/05 10:15
字数 1810
阅读 9
收藏 0

几点说明

  1. 永远不要纠结于在什么时候使用什么模式
  2. 永远不要纠结于什么模式适用于什么情景
  3. 永远不要去死记任何的模式
  4. 并不是说,23种设计模式可以应付所有的问题,要知道,使用一种方法的时候,往往伴随着新问题的出现
  5. 只有最适合你当前所遇到问题的解决方案,而没有最适合的设计模式,任何一种设计模式在应用的时候,都应该根据问题的实际情况去做适当的改变,不然一定会陷入设计模式的陷阱之中

 

三种工厂的说明

简单工厂(SimpleFactory):定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类或接口。

工厂方法(FactoryMethod):定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到了子类。

抽象工厂(AbstractFactory):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。

 

三种工厂的实现

注意:Singleton.SingletonOperateClass_1/2/3/4/5/6 是使用之前写的一个关于单例模式的笔记时创建的。

简单工厂的实现思路:在工厂类中,使用一个以「产品基类」作为返回值类型的方法,用于生产。这个方法需要有一个参数,用于表述需要创建的是哪一种「产品子类」。然后再在这个方法中进行判断,以返回相应的对象。

简单工厂的好处:通过使用工厂方法来创建对象,可以有效的解决在创建对象时耦合性过高的问题。如果我在客户类中,直接使用New来实例化产品类,那么,如果当我想使用另一种更好的类来替代之前的类的时候,我就得每一个客户类中都去修改。而使用工厂方法,就可以做到只修改这一个方法,从而实现低耦合性。当然,简单工厂的一个很致命的缺点,就是必须要知道传入什么以及会传出什么。这样对于类的扩展不是十分的方便。

「简单工厂 - Simple Factory」 
public static Singleton.OperateBase getSingletonOperateClass(int selected) {
 switch (selected) {
  case 1:
   return Singleton.SingletonOperateClass_1.Operate;
  case 2:
   return Singleton.SingletonOperateClass_2.Single;
  case 3:
   return Singleton.SingletonOperateClass_3.Operate;
  case 4:
   return Singleton.SingletonOperateClass_4.Operate;
  case 5:
   return Singleton.SingletonOperateClass_5.Operate;
  case 6:
   return Singleton.SingletonOperateClass_6.Operate;
  default:
   return null;
 }
}

工厂方法的实现思路:如果说,简单工厂是使用传入的参数来控制生成什么样的子类来返回,从而在解决耦合性问题的同时,也带来了不够灵活的问题。那么工厂方法就是使用多个相应对象的工厂来返回实例化后的子类,而不是通过传入参数来控制。

这里根据一篇参考的文章中提出的方法,可以使用反射来解决工厂方法中,要使用哪种子类,以及解决简单工厂中的传入参数的问题。个人觉得十分的好!具体的实现方法,就是写一个XML配置文件,或者干脆写在app.config中,然后来读取相应的节点,从而获取到有关的参数信息。

「工厂方法 - Factory Method」 
/// <summary> 
/// Factory Mathod Interface 
/// </summary> 
public interface IFactory_A {
 Singleton.OperateBase getSingletonOperateClass();
}
/// <summary> 
/// Factory Method 1 
/// </summary> 
public sealed class OperateFactory_1: IFactory_A {
  public Singleton.OperateBase getSingletonOperateClass() {
   return Singleton.SingletonOperateClass_1.Operate;
  }
 }
 /// <summary>
 /// Factory Method 2
 /// </summary> 
public class OperateFactory_2: IFactory_A {
 public Singleton.OperateBase getSingletonOperateClass() {
  return Singleton.SingletonOperateClass_2.Single;
 }
}

抽象工厂的实现思路:如果说简单工厂与工厂方法是对同一个问题的两种不同的解决方法的话,抽象工厂就是解决一系列这种问题的方法。因为其主要的作用就是生产一系列相互依赖的对象,而不用去关心它们具体的实现。

当然,抽象工厂相对于前两种方法来说,也是有一点复杂的。而也正是从这种方法开始,使用设计模式就需要一个好的「设计」了,不然会很惊讶的发现,越用设计模式,所产生的问题越多、系统越复杂、可控性越差。

这个模式的实现相对来说,还是比较直观的。首先要有一个总的工厂接口或者抽象类(建议使用接口),这个接口就是在客户类中,要实例化的那个模板。然后要有这个接口的多种不同的工厂实现类。具体有多少个实现类,这个要看你的系统需要而定。这些实现类都是用于实例化一系统的产品对象。也就是说,我们还要有一系列的产品对象用于实例化。我们首先要有这一系列产品对象的抽象类,然后再针对每一个系列创建相应的子类,当然,子类的数量以及内容还是要看你具体的需要了。

「抽象工厂 - Abstract Factory」 
public interface IFactory_A {
 ProductBass_1 getProduct_1();
 ProductBass_2 getProduct_2();
}
public sealed class OperateFactory_1: IFactory_A {
 public static ProductBass_1 getProduct_1() {
  return new ProductClass_1_1();
 }
 public static ProductBass_2 getProduct_2() {
  return new ProductClass_2_1();
 }
}
public class OperateFactory_2: IFactory_A {
  public ProductBass_1 getProduct_1() {
   return new ProductClass_1_2();
  }
  public ProductBass_2 getProduct_2() {
   return new PorductClass_2_2();
  }
 }
 /// <summary> 
 /// Description of ProductBass_1. 
 /// </summary> 
public abstract class ProductBass_1 {}
public class ProductClass_1_1: ProductBase_1 {
 public ProductClass_1_1() {}
}
public class ProductClass_1_2: ProductBase_1 {
 public ProductClass_1_2() {}
}
public abstract class ProductBass_2 {}
public class ProductClass_2_1: ProductBase_2 {
 public ProductClass_2_1() {}
}
public class ProductClass_2_2: ProductBase_2 {
 public ProductClass_2_2() {}
}

三种工厂的区别

 

相比较而言,简单工厂在实现上是最简单的,工厂方法在实现上,较简单工厂更复杂一点,但在灵活性上,更好一些。而抽象工厂方法是这三种方法中,最复杂的一种,当然,其与之前两种要解决的问题也有一定的区别。

我们可以认为,抽象工厂的实现是依托于之前两种方法的。我们也可以认为,抽象工厂是对之前两种方法在创建一系列对象上不足的一个有效补充。

如果说,在设计上做到极致,或整体项目比较小的话,在简单工厂与工厂方法中,个人比较倾向于简单工厂这种方式。因为其不用包含太多的子类。

有文章指出,简单工厂在内聚方面不够充分。这在OOP方面,确实是简单工厂的一个感伤。但是如果我们的换种思路去考虑的话,将工厂类看做是一个静态不变对象,其也是一个高内聚的实现,因为其只有一个作用,就是生产……当然,这是有点阿Q了……

 

参考

  1. http://www.cnblogs.com/anlyren/archive/2008/01/25/simple_factory_pattern.html
  2. http://www.cnblogs.com/anlyren/archive/2008/01/26/factory_method.html
  3. http://www.cnblogs.com/terrylee/archive/2005/12/13/295965.html
  4. http://www.cnblogs.com/terrylee/archive/2006/01/04/310716.html
  5. http://www.cnblogs.com/shenfx318/archive/2007/01/09/614844.html
  6. http://www.cnblogs.com/millen/archive/2009/02/13/1389974.html

© 著作权归作者所有

灰大羊
粉丝 4
博文 96
码字总数 95147
作品 0
浦东
项目经理
私信 提问
设计模式(四)工厂模式

我们在第一次学习对象这个概念的时候,新建对象用的是这样的代码: 但是真正到了工程上这样的代码是“生硬”的,当遇到 Product 改变,或者 Product 初始化流程更改这样的新需求时,要改变的...

Arnold_J
2017/12/12
0
0
【白话设计模式六】抽象工厂模式(Abstract Factory)

白话设计模式 工厂模式 单例模式 【白话设计模式一】简单工厂模式(Simple Factory) 【白话设计模式二】外观模式(Facade) 【白话设计模式三】适配器模式(Adapter) 【白话设计模式四】单例模式...

陶邦仁
2016/02/21
561
0
设计模式-抽象工厂(Abstract Factory)

2018-1-21 by Atlas 设计思想 客户类和工厂类分开。消费者任何时候需要某套产品集合时,只需向抽象工厂请求即可。抽象工厂会再向具体的工厂生产出符合产品集规格的产品。 应用场景 抽象替代具...

水天云黑白
2018/10/28
0
0
简单工厂模式--SimpleFactory

simply_factory.png 版权声明:本文为博主原创文章,未经博主允许不得转载 PS:转载请注明出处 作者: TigerChain 地址: www.jianshu.com/p/36fe35ad7… 本文出自 TigerChain 简书 Android 设...

TigerChain
2017/11/04
0
0
创建型设计模式-抽象工厂模式

模式介绍 前段时间介绍了工厂方法模式。 本次介绍的模式非常容易和工厂方法模式混淆,并且复杂度也有一定的提升,叫做抽象工厂模式。 其实在现实生活中,工厂都会生产某一样具体的产品,不存...

黑色小老虎丶
2017/08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

db.properties

jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&characterEncoding=utf8&useSSL=falsejdbc.username=rootjdbc.pas......

行者终成事
28分钟前
3
0
从 Storm 到 Flink,汽车之家基于 Flink 的实时 SQL 平台设计思路与实践

在 2019 年之前,之家的大部分实时业务都是运行在 Storm 之上的。Storm 作为早期主流的实时计算引擎,凭借简单的 Spout 和 Bolt 编程模型以及集群本身的稳定性,俘获了大批用户。下图是实时计...

阿里云官方博客
28分钟前
4
0
网络安全-Day04

2.1.1 什么是SQL注入 2.1.2 注入分类 2.1.3 MySQL手工注入 2.1.4 sqlmap使用 2.1.5 总结 什么是SQL注入 SQL注入漏洞原理 什么是SQL 结构化查询语言(Structured Query Language),是一种特殊目...

Jerry1101
28分钟前
3
0
docker容器内安装yum,vim等命令,以及配置ls指令

使用国内镜像 mv /etc/apt/sources.list /etc/apt/sources.list.bakecho "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >> /etc/apt/sources.listecho "deb http://......

长恭
29分钟前
3
0
超详细的MySQL8.0.17版本安装教程

下载MySQL MySQL的官网地址:https://www.mysql.com/。 如下图所示: 然后点击DOWNLOADS ==> Community,选择MySQL Community Server。如图所示: 滑到页面的最下面,找到Recommended Downl...

彩色泡泡糖
32分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部