在OO设计领域,我们知道前人总结了不少的经验,许多的经验在现代软件工程过程中已经被认为是原则来遵守。下面笔者摘抄几项下文涉及到的OO原则的定义。
OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。我的理解是,对于一个已有的软件,如果需要扩展,应当在不需修改已有代码的基础上进行。
DIP(依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。我的理解是,对于不同层次的编程,高层次暴露给低层次的应当只是接口,而不是它的具体类。
LoD (迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信。众所周知类(或模块)之间的通信越少,耦合度就越低,从而更有利于我们对软件的宏观管理。 老子论“圣人之治”有相同的思想,《老子》云:“是以圣人之治,虚其心,实其腹,弱其志,常使民无知无欲。”,又云:“小国寡民,邻国相望,鸡犬之声相 闻,民至老死,不相往来。”。佩服我们的老祖宗,N千年前就想到了西方N千年后才想到的东西,同时也佩服《java与模式》的作者阎宏,可以用中国传统哲 学思想这么生动的说明这一软件设计原则。
简单工厂模式及实例
简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化目标类的静态类。下面我主要通过一个简单的实例说明简单工厂及其优点。
比 如有个国家的运动员协会,他们是负责登记与注册职业运动员的(就好像我们国家的体育总局,呵呵,无论足球篮球还是乒乓球的运动员都必须在这里注册才能拿到 我们国家职业运动员牌照)。一家体育俱乐部(比如篮球的广东宏远,足球的深圳健力宝)想获得球员为自己俱乐部效力,就必须通过这个运动员协会。
根据DIP我们可以设计一个“运动员”接口,“足球运动员”和“篮球运动员”(还有其他运动员)都实现“运动员”这个接口。而“运动员协会”就是一个简单工 厂类,它负责实例化“运动员”。我们这里的“俱乐部”就是一个客户端(Client),不同的“俱乐部”就是不同的客户端。
对于不同的俱乐部对象(无论是八一还是深圳健力宝),他们都是面向“运动员”接口编程,而不用管是“足球运动员”还是“篮球运动员”,也就是说实现了“运动 员”接口的具体类“足球运动员”无需暴露给客户端。这也满足了DIP。但具体的俱乐部(比如足球的深圳健力宝)如何确保自己获取的是自己想要的运动员(健 力宝俱乐部需要的当然是足球运动员)呢?这就需要“运动员协会”这一工厂类了。俱乐部通过调用“运动员协会”的具体方法,返回不同的实例。这同时也满足了 LoD,也就是“深圳健力宝足球俱乐部”对象不直接与“足球运动员:李毅”对象通信,而是通过他们共同的“朋友”——“国家体育总局”通信。
下面给出各个类的程序,会有助于读者更好的了解笔者之前的介绍。
Code: | [Copy to clipboard] |
|
以上就是简单工厂模式的一个简单实例,读者应该想象不用接口不用工厂而把具体类暴露给客户端的那种混乱情形吧(就好像没了体育总局,各个俱乐部在市场上自己胡乱的寻找仔细需要的运动员),简单工厂就解决了这种混乱。
我 们用OCP看看简单工厂,会发现如果要对系统进行扩展的话治需要增加实现产品接口的产品类(上例表现为“足球运动员”,“篮球运动员”类,比如要增加个 “乒乓球运动员”类),而无需对原有的产品类进行修改。这咋一看好像满足OCP,但是实际上还是需要修改代码的——对,就是修改工厂类。上例中如果增加 “乒乓球运动员”产品类,就必须相应的修改“体育协会”工厂类,增加个“注册乒乓球运动员”方法。所以可以看出,简单工厂模式是不满足OCP的。
工厂方法模式及其实例
谈 了简单工厂模式,下面继续谈谈工厂方法模式。前一节的最末点明了简单工厂模式最大的缺点——不完全满足OCP。为了解决这一缺点,设计师们提出了工厂方法 模式。工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接 口的工厂类。下面我们通过修改上一节的实例来介绍工厂方法模式。
我们在不改变产品类(“足球运动员”类和“篮球运动员”类)的情况下,修改下工厂类的结构,如下图所示:
相关代码如下:
Code: | [Copy to clipboard] |
|
很明显可以看到,“体育协会”工厂类变成了“体育协会”接口,而实现此接口的分别是“足球协会”“篮球协会”等等具体的工厂类。
这样做有什么好处呢?很明显,这样做就完全OCP了。如果需要再加入(或扩展)产品类(比如加多个“乒乓球运动员”)的话就不再需要修改工厂类了,而只需相应的再添加一个实现了工厂接口(“体育协会”接口)的具体工厂类。
从以上对两种模式的介绍可以了解到,工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。但是,工厂方法模式就一定比简单工厂模式好呢?笔者的答案是不一定。下面笔者将详细比较两种模式。
1. 结构复杂度
从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。
2.代码复杂度
代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。
3.客户端编程难度
工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优点。
4.管理上的难度
这是个关键的问题。
我 们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同 样具备良好的扩展性——扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但笔者认为不需要太拘 泥于设计理论,要知道,sun提供的java官方工具包中也有想到多没有满足OCP的例子啊(java.util.Calendar这个抽象类就不满足 OCP,具体原因大家可以分析下)。
然后我们从维护性的角度分析下。假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时 需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式 仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。
由以上的分析,笔者认为简单工厂模式更好用更方便些。当然这只是笔者的个人看法而已,毕竟公认的,工厂方法模式比简单工厂模式更“先进”。但有时过于先进的东西未必适合自己,这个见仁见智吧。
发表评论
-
Log4j(1)
2007-07-16 11:40 5591、 Log4j是什么? Log4j可以帮助调试(有时候 ... -
Ant
2007-07-16 11:42 535ant使用教程 Ant是什么? Ant是一种基 ... -
Log4j(2)
2007-07-16 17:07 585Log4j由三个重要的组件 ... -
java基础
2007-07-18 16:50 653第一,谈谈final, finally, finalize的区 ... -
spring hibernate struts异常解决办法
2007-07-20 09:56 5391。Caused by: java.lang.NoClassD ... -
eclipse3.2.0+myeclipse5.5.1开发struts1.2+spring2.0+hibernate3.1
2007-07-20 13:37 6421.首先新建一个Web工程2.添加Struts框架1.2版本3 ... -
Java.io包
2007-08-14 10:23 5711.1 以字节为导向的stream 以字节为导向的str ... -
struts中javascript验证登陆
2007-08-21 10:57 531<script type="text/java ... -
Validator验证框架使用教程
2007-08-21 16:05 561Terry原创,转载请 ... -
Struts:与Tiles框架的第一次亲密接触
2007-08-22 10:37 8681.在你的struts配置文件struts-config.x ... -
用过滤器filter解决乱码
2007-09-25 10:36 795当在做程序的是你也许会遇到一些很让你恼火的乱码问题 ... -
简单工厂模式,工厂方法模式和抽象工厂模式的区别
2008-04-01 11:37 542我记得看的阎宏发表在天极网上的文章上举的例子挺好的,他以一个后 ... -
JAVA中获取年月日
2008-04-22 14:48 3312Java 语言提供了许多处理日期的工具。其中一些工具在其他语言 ... -
jsp内置對象
2008-04-27 23:00 547一般来说,我们在使用Struts时,如果要在JSP隐式的传 ... -
spring+javamail
2008-10-08 19:02 5911.首先必须要有spring.jar, mail.jar, c ... -
Spring对IBatis的支持
2008-10-09 15:06 595Spring对IBatis提供了完善的内建支持。使用Sprin ... -
spring+ibatis实例
2008-10-09 16:18 2694首先需要以下这些jar包:commons-dbcp.jar, ... -
jboss虚拟镜像自动部署
2008-12-25 11:04 7111.修改C:\jboss-4.0.5.GA\server\de ... -
Spring配置初始化ApplicationContext
2008-12-30 11:36 5521. 在struts-config.xml里,以插件的形式 ... -
写自定义标签时标记attribute里rtexprvalue的用法
2008-12-31 14:39 464其实以前也有写过自定义标签, 但是没有注意到过<rtex ...
相关推荐
介绍的是工厂模式 包括简单工厂模式、工厂方法模式、抽象工厂模式 包括PPT和代码
本文章通俗易懂的对工厂模式进行了讲解,相信您看完这篇文章会对工厂模式有更深入的了解
java设计模式 简单工厂模式uml类图,一张图就让你秒懂简单工厂模式
运用两个典型案例,实现软件设计模式的简单工厂模式,从该案例中,可以体会简单工厂模式的特点
工厂方法模式和抽象工厂模式的区别,对工厂方法模式和抽象工厂模式做了简单的比较
C#中的简单工厂模式与工厂方法模式实例 在学C#的可以下载是比较好的技术哦
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂...
JAVA设计模式(01):创建型-工厂模式【简单工厂模式】(Simple Factory)
反射例子代码、简单工厂模式例子代码、工厂模式例子代码
6. 简单工厂模式 部分源码实例: // 奔驰工厂 class BenzFactory : public AFactory { public: ICar* CreateCar() { return new BenzCar(); } }; // 宝马工厂 class BmwFactory : public AFactory { public: ...
工厂方法模式工厂方法模式工厂方法模式工厂方法模式工厂方法模式
从简单工厂,到工厂方法到抽象工厂,这几种都带有“工厂”的模式,总是容易叫人迷糊,我仔细研究了下,然后用简单的例子做类比,列出了自己的通俗理解和比较,大部分是自己的体会,感觉理的比较清楚,末尾提了下...
java设计模式 工厂方法模式uml类图,一张图就让你秒懂工厂方法模式
简单工厂模式,简单工厂模式课件,简单工厂模式PPT
设计模式之简单工厂模式案例
c#工厂模式 简单工厂,抽象工厂,单件模式
通过C++实现了简单工厂模式、工厂模式、抽象工厂模式三大设计模式的经典案例。
基于简单工厂模式的实例在安卓平台下。项目是AndroidStudio下的
Java简单工厂模式和传统模式实现对比,通过简单实例比对两种方式差异,体现传统模式的弊端及工厂模式优势。利于初学者后续接触spring
设计模式课程资料——简单工厂模式,使用Java实现,在eclipse进行编译