本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41142929

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

从下面类图可以看出,抽象的创建者(Creator)提供了一个创建对象方法的接口,也称为“工厂方法”。其中,任何其它实现的方法,都可能使用该工厂方法制造出来的产品,但是只有子类真正实现这个工厂方法并创建产品。

其实,工厂方法是让子类决定要实例化的类是哪一个,但是这里的决定并不是说允许子类本身在运行时做决定,而是指在编写创建者(Creator)时,不需要知道实际创建的产品是哪一个,你选择的了使用哪个子类,那么自然就能决定实际创建的产品是什么。

当你直接地实例化一个类时,就是在依赖它的具体类。下面的类显示的是一个很依赖的面包店。

<span style="font-size:14px;">public class DependentBreadStore {

	public Bread createBread(String style, String type) {
		Bread Bread = null;
		if (style.equals("NY")) {
			if (type.equals("cheese")) {
				Bread = new BJStyleCheeseBread();
			} else if (type.equals("veggie")) {
				Bread = new BJStyleVeggieBread();
			} else if (type.equals("clam")) {
				Bread = new BJStyleClamBread();
			} else if (type.equals("pepperoni")) {
				Bread = new BJStylePepperoniBread();
			}
		} else if (style.equals("Chicago")) {
			if (type.equals("cheese")) {
				Bread = new ChicagoStyleCheeseBread();
			} else if (type.equals("veggie")) {
				Bread = new ChicagoStyleVeggieBread();
			} else if (type.equals("clam")) {
				Bread = new ChicagoStyleClamBread();
			} else if (type.equals("pepperoni")) {
				Bread = new ChicagoStylePepperoniBread();
			}
		} else {
			return null;
		}
		Bread.prepare();
		Bread.bake();
		Bread.cut();
		Bread.box();
		return Bread;
	}
}</span>

这里我们就会联想到OO设计原则中一个很重要的原则:依赖倒置原则——要依赖抽象,而不要依赖具体类。其实,这个原则和“针对接口编程,不针对实现编程”。该

原则说明了:不能够让高层组件依赖于低层组件,而

且,不管是高层组件还是低层组件,“两者”都应该依赖于抽象。就像上面包店一样,BreadStore是“高层组件”,而面包的实现是“低层组件”,“两者”都应该依赖于抽

象,而BreadStore依赖于这些具体的类了。(所谓高层

组件,指的是由其它低层组件定义其行为的类。BreadStore是高层组件,其行为是由面包定义的:BreadStore创建所有不同的面包对象,进行一系列操作;而面包本

身属于低层组件。

避免在OO设计中违反依赖倒置原则主要有:

(1)变量不可持有具体类的引用。(如果使用New,就会持有具体类的引用)

(2)不要让类派生自具体类。(如果派生自具体类,你就会依赖具体类。请派生自抽象(接口或者抽象类))

(3)不要覆盖类中已实现的方法。(如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类已实现的方法,应该由所有子类共享)

通过上面的分析,可知,运用工厂方法可以避免对象之间的依赖关系,从而使代码变得更加灵活。另外,我们也了解了OO设计原则中的依赖倒置原则,并知道以后在什么样的情况下使用该原则。

注意:依赖倒置原则并不是随时都要遵循的原则。也有违反这一指导方针的地方。比如,有一个不像是会改变的类,那么在代码中直接实例化具体类也就没有什么大

碍的了。想想平时我们在程序中不假思索地就实例化字符串对象了?就没有违反这个原则!因为字符串的不可变的。所以,针对不同的场景,我们需要对其进行分

析,从而能够灵活的运行各种原则,而不是一成不变的。



设计模式之——工厂模式(B)的更多相关文章

  1. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

  2. 5. 星际争霸之php设计模式--抽象工厂模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  3. 3. 星际争霸之php设计模式--简单工厂模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  4. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  5. 设计模式之工厂模式(Factory)

    设计模式的工厂模式一共有三种:简单工厂模式,工厂模式,抽象工厂模式 简单工厂模式原理:只有一个工厂类,通过传参的形式确定所创建的产品对象种类 代码如下: #include <stdio.h> ...

  6. php设计模式:工厂模式

    php设计模式:工厂模式 意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂模式实现: 工厂模式中任何创建对象的工厂类都要实现这个接口,实现接口的方法体中都要实现接口中的方法,它声明 ...

  7. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  8. java 设计模式之工厂模式与反射的结合

    工厂模式: /**  * @author Rollen-Holt 设计模式之 工厂模式  */   interface fruit{     public abstract void eat(); } ...

  9. C#学习之设计模式:工厂模式

    最近研究一下设计模式中工厂模式的应用,在此记录如下: 什么是工厂模式? 工厂模式属于设计模式中的创造型设计模式的一种.它的主要作用是协助我们创建对象,为创建对象提供最佳的方式.减少代码中的耦合程度,方 ...

  10. [JS设计模式]:工厂模式(3)

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

随机推荐

  1. mysql catalog的名字

    def 算是一个一点卵用都没有的知识点 然后tmd各个版本不同 用这个语句查 SELECT * FROM information_schema.SCHEMATA where schema_name=' ...

  2. JavaScript基础知识从浅入深理解(一)

    JavaScript的简介 javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互. javascript是由三部分组成:ECMAScript.DO ...

  3. seaborn使用(样式管理)

    seaborn使用(样式管理) Seaborn是一个在Python中制作具有吸引力和丰富信息的统计图形的库.它建立在matplotlib之上,并与PyData堆栈紧密集成,包括支持scipy和pand ...

  4. Fiddler实现对手机抓包

    工具 && 前提条件: 1. 安装了Fiddler的PC一台 2. 手机一部 3. 手机和PC是在同一个局域网内,或者至少能够联通,即手机的流量能够转发到PC端上能够被其捕获 PC端 ...

  5. Node.js 模块系统

    为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的.换言之,一个 Node.js 文件就是一个模块, ...

  6. Docker的Fig 项目

    在你的应用里面添加一个 fig.yml 文件,并指定一些简单的内容,执行 fig up 它就能帮你快速建立起一个容器 快速搭建基于 Docker 的隔离开发环境 使用 Dockerfile 文件指定你 ...

  7. 用Matlab画直方图

    简介 本文介绍如何使用matlab定制自己的直方图. 关键 使用Matlab的 bar() 函数创建柱状图 bar() 画的bin的高度跟数据相关 bar() 数据每一列一个group,有几列数据就画 ...

  8. RunLoop总结:RunLoop 与GCD 、Autorelease Pool之间的关系

    如果在面试中问到RunLoop相关的知识,很有可能也会问到RunLoop与GCD.Autorelease Pool有没有关系,哪些地方用到了GCD.Autorelease Pool等. So,本文就总 ...

  9. java中八种基本数据类型以及它们的封装类,String类型的一些理解

    在我们面试或者考试过程中经常会考到八种基本数据类型以及它们的封装类,那么有哪八种基本数据类型呢?它们的封装类又是什么呢? 首先,八种基本数据类型分别是:int.short.float.double.l ...

  10. 改进版getpass库

    编程伊始 正式实施 改进版 源码 以数字显示 以自定义分隔符delimiter显示 如何使用 下载及安装 在您的代码中使用 源码下载 总结 用过Linux的都知道,尤其是进行使用包管理软件类似于apt ...