设计模式是一种非常有用的编程技巧,它对于代码的重构有些非常重要的作用,对于软件开发人员来说,需要理解并尝试着使用这些设计的方法。

个人感觉《设计模式之禅》这本书中讲解的非常具体,每个模式都配以适当的例子,非常适合学习设计模式的初学者,当然,程杰的《大话设计模式》也是非常好的一本书,都可以拿过来当做一本工具书随时查看理解设计的奥妙。

工厂模式

这个模式的名字就已经告诉了我们它想要做什么,就是让我们构造出一个工厂,然后生产我们需要的东西,即生成对象。那么,为什么要构造一个工厂呢,为什么不直接在代码中直接 new 一个出来呢?

想象这样一种情况:有时我们设计一类东西时,这一类又包含有许多的具体类,那么,当我们需要得到这些对象时,如果我们一个一个的 new 出来,就会显得很粗糙,而且如果构造这些对象时,需要进行一些必要的初始化,而这些初始化操作对于这一类对象都是相似的,那么,我们的代码中就会显得非常的冗余,在 new 之后会出现很多相似的初始化对象代码。

这时,你就会想,有这样一个东西,我只需要告诉它,我需要那个对象,那么,它就会生成那个对象,而且我不需要考虑到它实际的实现细节。那么这个东西就叫做工厂。

工厂模式分为三类:

简单工厂模式,工厂模式,抽象工厂模式

下面就分别对这三个模式进行介绍

简单工厂模式

这是最简单的工厂模式类型,一般的设计会出现三个类或接口:

1> 抽象产品类或者产品接口

      2> 具体产品类

      3> 工厂类

注:这里我想多说几句关于抽象类和接口的区别,抽象类和接口是非常相似的东西,大部分时候它是可以互相代替的,那么它们之间存在什么不同呢?我们从名字中可以看出一个是对一类对象的抽象,一个是类的接口。举一个例子就好像这样,人分为黄种人,白种人。。。,那么,对于人,我们需要设计出一个抽象类还是接口呢?应该设计成为抽象类,因为,它是对人类的抽象,所有的人都应该具有这个特征。接口呢,什么应该设计成为接口呢?就好像人的爱好一样,比如,游泳,台球,乒乓球(这些都是我的爱好,哈哈),它是后天养成的东西,是需要具体的实现的,所以,这些应该是设计成为接口,所以,一个黄种人的类就好像下面这样:

public class YellowHuman extends Human implements Swimming, PingPang ...  { }

好的,回到前面的简单工厂里面,说它简单,因为这个模式只需要实现一个工厂类就能生产出我们需要的产品,还是以人种的例子(“著名的”女娲造人)做出说明。

女娲制造出各种人种,黄种人,白种人,黑种人,首先,人具有的共同特点构造出一个抽象类:

public abstract class __Q_Y_Human
{abstract void __Q_Y_Color();abstract void __Q_Y_Talk();public void __Q_Y_Sex(){System.out.println("every one has sex : man/woman...");}
}

然后,各种人种需要实现这个抽象类,这里举例黄种人实现抽象类:

public class __Q_Y_YellowHuman extends __Q_Y_Human{@Overridepublic void __Q_Y_Color() {// TODO Auto-generated method stubSystem.out.println("黄色皮肤。。。");}@Overridepublic void __Q_Y_Talk() {// TODO Auto-generated method stubSystem.out.println("一般说的都是双字节。。。");}}

工厂类也很容易写出来,就好像下面这样:

public class __Q_Y_Factory
{/*制造一个黄种人*/public __Q_Y_YellowHuman __Q_Y_CreateYellowHuman(){return new __Q_Y_YellowHuman();}public __Q_Y_BlackHuman __Q_Y_CreateBlackHuman(){return new __Q_Y_BlackHuman();}public __Q_Y_WhiteHuman __Q_Y_CreateWhiteHuman(){return new __Q_Y_WhiteHuman();}
}

当我们需要构造出一个人的对象时,只需要调用工厂中的方法就可以了,是不是比以前单纯的 new 出来要清晰的多了呢!

不过,这样会产生出扩展问题,假如现在又需要添加一种新的人种 -- 红种人,怎么办呢?具体的人种对象实现起来很简单,继承那个抽象类就可以了,那么,工厂类呢?我们不得不修改工厂中的方法,需要新增加一个,也许你会说这样也不难呀,添加一个方法就可以了。不过,这仅仅是增加一种人,如果有很多种呢?同时,这也破坏了原来的代码结构。所以,一种对简单工厂模式的改进出现了 -- 工厂模式。
      这个改进了的模式比简单工厂模式好的地方在于它是建立一个抽象工厂,具体生产产品的工厂需要继承抽象工厂,实现具体的生产方法以生产需要的不同产品。

所以,它的思想也是很简单的,我们首先需要看下抽象工厂的实现:

public abstract class __Q_Y_Factory {public abstract <T extends __Q_Y_Human> T __Q_Y_CreateHuman(Class<T> _c);
}

这里,它很简单,只是写了一个泛型方法,我们限定它的返回类型和参数都是 Human 的子类,下面看看具体实现的工厂类:

public class __Q_Y_HumanFactory extends __Q_Y_Factory {@SuppressWarnings("unchecked")@Overridepublic <T extends __Q_Y_Human> T __Q_Y_CreateHuman(Class<T> _c) {// TODO Auto-generated method stub__Q_Y_Human _human = null;try {/*这里就是反射的应用,即仅仅是利用类的名字就能构造它的对象*/_human = (__Q_Y_Human)Class.forName(_c.getName()).newInstance();} catch (Exception e) {// TODO: handle exceptionSystem.out.println("创建人失败了。。。");}return (T) _human;}
}

可以看到,这个方法根据不同的参数(类名)就可以得到不同的人种了,当我们新增加一个人种的时候,只是需要写出表示那个人种的类就可以了,其他的都不需要改变。

为方便看代码的结构,下面贴出以上方法的类图:

从上面的类图中可以看到,三类人都继承自 “人” 的抽象类,具体的工厂也是继承自工厂抽象类。

下面介绍抽象工厂模式:

抽象工厂模式与工厂模式的构造大致是一样的,它们的区别之处在于抽象两个字,抽象工厂模式的抽象程度要高于工厂模式,意思是抽象工厂的同一套接口能够得到不同类型的对象。

人分为男和女,那么,代码中生产的人也需要分出性别来,如果依照上面的工厂接口我们没办法做到这一点,当然,表示人的类也是需要变化的,要有不同肤色的男人类,不同肤色的女人类。首先,我们需要看看人类的设计。

第一层抽象类:

public abstract class __Q_Y_Human {public abstract void __Q_Y_Sex();public abstract void __Q_Y_Color();
}

第二层抽象类:

public abstract class __Q_Y_YellowHuman extends __Q_Y_Human{public void __Q_Y_Color() {System.out.println("yellow human...");}
}

第三层具体类(两个):

public class __Q_Y_MaleYellowHuman extends __Q_Y_YellowHuman{@Overridepublic void __Q_Y_Sex() {// TODO Auto-generated method stubSystem.out.println("male yellow human...");}}
public class __Q_Y_FamaleYellowHuman extends __Q_Y_YellowHuman{@Overridepublic void __Q_Y_Sex() {// TODO Auto-generated method stubSystem.out.println("famale yellow human...");}}

这里就很明显了,我们只要构造一个抽象工厂能够 “生产” 不同类别的人就行了,抽象工厂的定义如下:

public abstract class __Q_Y_Factory {public abstract __Q_Y_Human __Q_Y_Create();
}

从上面的例子中可以看到,工厂返回的只是 Human 类型的对象,不知道 Human 的肤色是什么,也不知道 Human 的性别是什么。这也就是抽象工厂的意思,它生产出来的对象更为抽象,抽象到可以表示不同的类型的对象。

好吧,我们看下具体的实现方式是怎么样:

生产黄种男性:

public class __Q_Y_FamaleFactory extends __Q_Y_Factory{@Overridepublic __Q_Y_Human __Q_Y_Create() {// TODO Auto-generated method stubreturn new __Q_Y_FamaleYellowHuman();}}

生产黄种女性:

public class __Q_Y_MaleFactory extends __Q_Y_Factory{@Overridepublic __Q_Y_Human __Q_Y_Create() {// TODO Auto-generated method stubreturn new __Q_Y_MaleYellowHuman();}}

当然,除了黄种人,黑种人,白种人都可以自己去实现加到这个模式中,为方便理解模式的构造,贴出抽象工厂模式实现的类图:

工厂模式(简单工厂模式,工厂模式,抽象工厂模式)是实际运用中最多的设计模式,所以,需要理解这种模式,并在实际的软件开发中尝试用这种设计模式构造容易理解的架构。

读秦小波《设计模式之禅》 -- 工厂模式相关推荐

  1. 读-秦小波-编写高质量代码:改善java程序的151个建议

    有些建议不太用到,但是用到的时候如果不注意就会进坑,所以书名改成java的151个坑更合适. 不要在常量和变量中出现易混淆的字母 包名全小写,类名首字母全大写,常量全大写下划线分割,变量驼峰: 字母l ...

  2. 读秦小波《设计模式之禅》 -- 单例模式

    新年第一天,在这里首先要祝大家新年快乐! 这篇文章中,介绍的是非常重要,也是非常常用的一种设计模式 -- 单例模式.例如,我们在电脑上登录QQ的时候,同一个QQ号码就只能登录一次,而不可能出现一个号码 ...

  3. 设计模式 之 抽象工厂模式

    项目源码:https://gitee.com/Jacob-gitee/DesignMode 个人博客 :https://jacob.org.cn 女娲的失误 工厂模式中讲了女娲造人的故事.人是造出来了 ...

  4. .NET设计模式(1): 简单工厂模式

    .NET设计模式(1): 简单工厂模式 最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足.园子里其实关于此类文章已经很多了,如果d ...

  5. getinstance方法详解_二、设计模式总览及工厂模式详解

    二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场 ...

  6. 工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)

    简单工厂不是一个标准的设计模式,但是它实在是太常用了,简单而又神奇,所以还是需要好好掌握的,就当是对学习设计模式的热身运动吧.为了保持一致性,我们尽量按照学习其它模式的步骤来进行学习. 1  场景问题 ...

  7. 设计模式之简单工厂模式(C#版)

    设计模式之简单工厂模式(C#版) 简介 假设有个女朋友 总结 简介 我用最简洁而直接的方式来描述一下,什么是简单工厂模式.一句话就是,工厂类使用switch case语句返回特定类型. 下面,我们用一 ...

  8. php工程模式,PHP设计模式(八):工厂模式

    Introduction 在PHP设计模式(七):设计模式分类中我们提到过创建设计模式(Creation patterns),创建设计模式专注于设计对象(Object)和实例(Instance)的创建 ...

  9. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

最新文章

  1. mysql多语句查询结果_MySQL查询从多个选择语句获取结果?
  2. HTML5 将改变Web开发模式
  3. git 本地代码到github(转)
  4. wchar_t*和string相互转换
  5. HtmlAgilityPack的简单使用
  6. 方立勋_30天掌握JavaWeb_Session
  7. 在java面向对象编程中_谈一谈你对封装_继承_多态概念的理解_Java新职篇:面向对象编程的3个原则是什么?...
  8. 阿里云盘小白羊版 v2.9.19 绿色版
  9. oracle “**with as**”短语,也叫做子查询部分。
  10. linux怎么进入windows系统安装目录下,windows下Linux子系统的安装配置
  11. python水果超市管理系统流程图_超市管理流程图-超市管理系统业务流程图
  12. 博士申请 | 香港科技大学(广州)王林助理教授招收计算机视觉博士生
  13. JAV迷你共享单车项目
  14. 从侵权看“人肉搜索”
  15. 锁机制与原子操作 第四篇
  16. Linux内核系统论文写作虚拟机方案
  17. MDN Web Docs
  18. linux基本命令(3)——pwd命令
  19. DELPHI bpl使用
  20. 软件工程毕业设计 SSM房屋租赁管理系统(源码+论文)

热门文章

  1. js获取微信验证实现微信自动跳转 检验code操作
  2. 从各方面数据来看《猎场》为什么收官后热度依旧
  3. 假设写一段代码引导PC开机这段代码是 ? Here is a tiny quot;OSquot; :-D
  4. layui的几个简单使用(简单弹窗,加载效果,移除加载效果)
  5. css你所不知道技巧
  6. POJ3982 序列
  7. iOS NSArray数组过滤
  8. 齐聚上海,get多媒体开发新技能(内附讲师资料下载)
  9. Case when then esle end
  10. 自学习 与 无监督特征学习