论坛首页 Java企业应用论坛

深入浅出设计模式(连载)

浏览 13638 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-25  
内容简介:
          本书总结了许多系统软件在设计开发过程中的难点,力图将设计模式的实际应用与实现原理有机结合起来,破解软件开发人员在学习设计模式过程不能透彻理解并灵活运用设计模式的难题。
本书是笔者在多年项目开发过程中的经验总结,通过本书的学习,希望读者能够深入的认识设计模式的重要性,并能够融会贯通,在自己的项目中灵活的运行设计模式,以高质量实现程序设计和开发。全书共分27章。第1章从软件开发遇到的问题讲起,简要介绍了面向对象的设计原则,已经设计模式的划分和学习途径。第2章对设计模式需要用到的工具进行了简要介绍。从第3章开始,依次讲解了创建型模式:单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和创建者模式;从第9章开始,依次讲解了结构型模式:适配器模式、门面模式、代理模式、合成模式、享元模式、装饰模式和桥模式;从第16章开始,依次讲解了行为型模式:策略模式、迭代器模式、模板方法模式、中介者模式、访问者模式、职责链模式、状态模式、解释器模式、观察者模式、命令模式、备忘录模式,第27章通过一个实现MVC框架的综合示例,深入讲解了各种模式的应用。
本书每个章节都是先通过具体的示例讲解为什么需要使用某个设计模式,然后讲解该模式的实现原理,最后再通过详细的示例或对很多开源框架的分析,来加深读者对设计模式的理解。
本书适用于中、高级软件设计和开发人员,尤其是已经学习过设计模式但没有收获的开发人员,同时也可用作高校相关专业师生和社会培训班的教材。

   发表时间:2012-12-25  
目录
第一章  如何学习设计模式
1.1  软件开发遇到的问题
1.2  面向对象的设计原则
1.3  设计模式的产生和分类
1.4  设计模式学习路线
1.5  小结
第二章  学习设计模式的工具
2.1  建模语言概述
2.2  设计模式的工具使用
2.3  UML类图
2.4  小结
第三章  单例模式(Singleton)
3.1  哪里会使用到单例模式
3.2  单例模式的实现原理
3.3  双检测锁机制的单例模式
3.4  单例模式在日志管理中的实际应用
3.5  单例模式在数据库连接池管理中的实际应用
3.6  小结
第四章  简单工厂模式(Simple Factory)
4.1  哪里会使用到简单工厂模式
4.2  简单工厂模式的实现原理
4.3  简单工厂模式在翻译器中的实际应用
4.4  小结
第五章  工厂方法模式(Factory Method)
5.1  哪里会使用到工厂方法模式
5.2  工厂方法模式的实现原理
5.3  简单工厂模式与工厂方法模式比较
5.4  工厂方法模式在Spring中的实际应用
5.5  小结
第六章  抽象工厂模式(Abstract Factory)
6.1  哪里会使用到抽象工厂模式
6.2  抽象工厂模式的实现原理
6.3  抽象工厂模式在翻译器中的实际应用
6.4  小结
第七章  原型模式(Prototype)
7.1  哪里会使用到原型模式
7.2  原型模式的实现原理
7.3  原型模式在Java中的实际应用
7.5  小结
第八章  创建者模式(Builder)
8.1  哪里会使用到创建者模式
8.2  创建者模式的实现原理
8.3  创建者模式在薪酬模块中的实际应用
8.4  小结
第九章  适配器模式(Adapter)
9.1  哪里会使用到适配器模式
9.2  适配器模式的实现原理
9.3  在模块的接口间使用适配器模式
9.4  适配器模式在Spring中的实际应用
9.5  适配器模式在JUnit中的实际应用
9.6  小结
第十章  门面模式(Facade)
10.1  哪里会使用到门面模式
10.2  门面模式的实现原理
10.3  门面模式在Spring JDBC中的实际应用
10.4  门面模式在Hibernate中的实际应用
10.5  小结
第十一章  代理模式(Proxy)
11.1  哪里会使用到代理模式
11.2  代理模式的实现原理
11.3  动态代理的实现
11.4  面向方面的程序编程
11.5  代理模式在Struts2中的实际应用
11.6  小结
第十二章  合成模式(Composite)
12.1  哪里会使用到合成模式
12.2  合成模式的实现原理
12.3  合成模式在JUnit中的实际应用
12.4  合成模式在薪酬系统中的实际应用
12.5  小结
第十三章  享元模式(Flyweight)
13.1  哪里会使用到享元模式
13.2  享元模式的实现原理
13.3  采用单例模式和享元模式来实现数据库连接池
13.4  小结
第十四章  装饰模式(Decorator)
14.1  哪里会使用到装饰模式
14.2  装饰模式的实现原理
14.3  装饰模式在Java中的实际应用
14.4  小结
第十五章  桥模式(Bridge)
15.1  哪里会使用到桥模式
15.2  桥模式的实现原理
15.3  桥模式在网上商城系统的实际应用
15.4  小结
第十六章  策略模式(Strategy)
16.1  哪里会使用到策略模式
16.2  策略模式的实现原理
16.3  策略模式在Spring的实际应用
16.4  小结
第十七章  迭代器模式(Iterator)
17.1  哪里会使用到迭代器模式
17.2  迭代器模式的实现原理
17.3  迭代器模式在Java中的具体实现原理
17.4  迭代器模式在公交售票系统的使用
17.5  小结
第十八章  模板方法模式(Template Method)
18.1  哪里会使用到模板方法模式
18.2  模板方法模式的实现原理
18.3  模板方法模式在JUnit中的使用
18.4  模板方法模式在Servlet中的应用
18.5  采用模板方法模式操作数据库的实际应用
18.6  小结
第十九章  中介者模式(Mediator)
19.1  哪里会使用到中介者模式
19.2  中介者模式的实现原理
19.3  中介者模式在消息队列的实际应用
19.4  小结
第二十章  访问者模式(Visitor)
20.1  哪里会使用到访问者模式
20.2  访问者模式的实现原理
20.3  访问者模式在银行排号机系统的实际应用
20.4  小结
第二十一章  职责链模式(Chain of  Responsibility)
21.1  哪里会使用到职责链模式
21.2  职责链模式的实现原理
21.3  职责链模式在Struts中的实现
21.4  职责链模式在OA办公中的实际应用
21.5  小结
第二十二章  状态模式(State)
22.1  哪里会使用到状态模式
22.2  状态模式的实现原理
22.3  状态模式在工作流引擎中的实际应用
22.4  小结
第二十三章  解释器模式(Interpreter)
23.1  哪里会使用到解释器模式
23.2  解释器模式的实现原理
23.3  解释器模式在数学公式中的实际应用
23.4  小结
第二十四章  观察者模式(Observer)
24.1  哪里会使用到观察者模式
24.2  观察者模式的实现原理
24.3  观察者模式在Spring中的实现
24.4  观察者模式在网上商城的实际应用
24.5  小结
第二十五章  命令模式(Command)
25.1  哪里会使用到命令模式
25.2  命令模式的实现原理
25.3  命令模式在Struts中的实际应用
25.4  小结
第二十六章  备忘录模式(Memento)
26.1  哪里会使用到备忘录模式
26.2  备忘录模式的实现原理
26.3  用备忘录模式实现公文系统撤回功能的实际应用
26.4  小结
第二十七章  综合应用设计模式实现MVC框架
27.1  MVC模式
27.1.1  MVC模式的核心思想
27.1.2  实现MVC框架需要考虑的内容
27.2  建立MVC框架的开发环境
27.3  实现视图层功能
27.4  实现控制层功能
27.4.1  实现返回页面的映射方式
27.4.2  实现页面数据的传递
27.4.3  实现Servlet控制器
27.5  实现持久层功能
27.6  用MVC框架实现信息发布系统
27.6.1  建立项目及配置文件
27.6.2  实现信息发布的视图层代码
27.6.3  实现信息发布的控制层代码
27.6.4  实现信息发布的模型层代码
27.6.5  实现信息发布的持久层代码
27.6.6  运行信息发布系统
27.7  小结
0 请登录后投票
   发表时间:2012-12-25  
第1章  如何学习设计模式
作为一名软件开发人员,如果在日常的软件开发中,代码编写的都很顺利,能够很好的适应用户的需求变化,那学不学习设计模式都没什么大问题,如果因为用户需求不断的发生变化,而造成程序代码频繁的修改,程序缺陷满天飞,项目经常延期,那学习并掌握设计模式就显得异常重要了。设计模式就像武侠小说中的独孤九剑,掌握了设计模式,开发人员就能够将软件开发过程中遇到问题化解于无形之中。
1.1  软件开发遇到的问题
软件开发真正的大面积流行起来,也就是最近的这20年的时间,在软件项目中,通常追求的目标是:高效率、高品质、低成本,但是常常会遇到这样那样的问题,比如:
 项目常常延期
 总是觉得缺少足够的资源
 提交给用户的产品bug满天飞
 员工常常抱怨自己待遇的不公平
 不同项目间在效率、质量、客户满意度等方面差异很大
为什么会造成上述问题呢?通常有以下这些原因:
 业务越来越复杂,而需求变更却很难管控
 技术更新频繁,而人员水平却参差不齐
 系统的功能越来越强大,而bug却越来越多
 文档越来越多,而版本管理混乱
 人员越来越多,而流动越来越大
 项目越来越多,做事情的方法却各不相同
在一般的软件开发公司中,针对上面介绍的这些原因,通常的做法是出台各种规章制度,设立专职的QA(质量保证)人员,建立质量保证体系,如图1.1所示:

           图1.1  质量保证体系
各种质量保证的制度出台了,也有专人天天检查了,可问题更多了,需求人员抱怨需求文档太难写,设计开发人员抱怨需求人员写的文档看不懂,以至于项目比以前延期的时间更长了,程序缺陷更多了,文档到后期都没人看了。这是目前国内大多数软件开发项目的真实写照,问题出在哪里呢?即便需求人员能够很好的编写出需求文档,难道需求就不会发生变化了吗?
0 请登录后投票
   发表时间:2012-12-25  
1.2  面向对象的设计原则
上一节讲述了目前软件开发存在的问题,该如何解决这些问题?从前面的分析可以看出,用户的需求是在不断发生变化的,既然作为软件开发人员不能拒绝这些变化,那就要正视这些变化,拥抱变化,尽量的满足用户需求的变化,要达到上述目的,就只有依靠程序设计,因为只有程序设计的更加灵活了,才能更好的适应需求的变化,才能更少的改动代码,从而产生更少的程序缺陷。
程序如何才能设计的更加灵活呢?随着经验的积累,程序设计人员总结出了一些面向对象的设计原则,大体上可以分为:单一职责原则、开闭原则、依赖注入原则、里氏替换原则、迪米特原则、接口分离原则和优先使用组合而不是继承原则。依据这些设计原则来进行程序设计和开发,就有可能使程序设计的更加灵活,能够更好的适应用户需求的复杂多变。下面来详细的讲解一下这些设计原则:
1.单一职责原则
单一职责原则的英文缩写是SRP,全称是Single Responsibility Principle。它的意思是说系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。
这是软件开发人员经常会违反的一个设计原则,通常为了省事,开发人员会将很多功能集中在一个类里面,从而造成这个类庞大无比,难于维护。
2.开闭原则
开闭原则的英文缩写是OCP,全称是Open for Extension,Closed for Modification的核心思想就是:一个对象对扩展开放,对修改关闭。它的意思是说对类的改动是通过增加代码进行的,而不是改动现有的代码。通俗的说就是,软件开发人员一旦写出了可以运行的代码,就不应该去改变它,而是要保证它能一直运行下去。
这也是软件开发人员经常会违反的一个设计原则,为了满足用户的新需求,需要修改或扩充原来的代码,这样造成的后果就是如果这个类中有一个功能要进行修改,就很可能会引起其他功能的变动,从而产生不可预知的后果,在软件开发中,经常会出现为了修改一个程序缺陷会产生新的程序缺陷的问题,就是违法了这一原则造成的。
3.依赖注入原则
依赖注入原则的英文缩写是DIP,全称是Dependence Inversion Principle。它的意思是说要依赖于抽象,不要依赖于具体的实现。在软件开发中,所有的类如果需求调用其他的类,就应该调用该类的接口或抽象类,而不是直接调用该类的实现类。
依赖注入原则在Spring中,得到了充分的应用,这样才能保证Spring的灵活性,因此在采用Spring开发代码时,要针对接口编程,而不是针对实现编程。
4.里氏替换原则
里氏替换原则的英文缩写是LSP,全称是Liskov Substitution Principle。它的意思是说在任何抽象类出现的地方都可以用它的实现类来替代。采用里氏替换原则可以更好的使用继承。
5.迪米特原则
迪米特原则的英文缩写是LOD,全称是Law of Demeter。它的意思是说一个对象应当对其他对象尽可能少的了解,从而能够降低各个对象之间的耦合,提高系统的可维护性。
在程序设计中,各个模块之间互相调用时,通常都会提供一个统一的接口来实现,这样其他模块就不需要了解另一个模块的内部实现细节,这样当一个模块内部的实现发生改变时,不会影响的其他模块的使用。
6.接口分离原则
接口分离原则的英文缩写是ISP,全称是Interface Segregation Principle。它的意思是说不应该强迫客户程序依赖它们不需要使用的方法。
在软件开发中,开发人员经常会将很多对外提供的方法防止一个类中实现,然后提供给其他模块使用,这就违反了接口分离原则,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中。
7.优先使用组合而不是继承原则
优先使用组合而不是继承原则的英文缩写是CARP,全称是Composite/Aggregate Reuse Principle。它的意思是说优先使用组合,而不是继承。
经过这么多年的开发经验积累,很多开发人员对于继承都是深恶痛绝,因为父类的任何改变都可能影响子类的行为,采用继承时,如果用户需求发生变化而造成父类进行修改,则所有的子类都要进行修改。而在使用组合时,就降低了这种依赖关系。
上面介绍的这些设计原则,都是前人通过多年设计经验总结出来的,从上面的讲解也可以看出,这些设计原则的一个核心思想就是强调尽量降低代码之间的依赖,从而能够灵活多变,适应用户需求的不断变化,这也是“高内聚、低耦合”思想的具体实现。
0 请登录后投票
   发表时间:2012-12-25  
1.3  设计模式的产生和分类
有了上一节介绍的这些设计原则,是不是就能设计好程序了呢?一般来讲,如果真正掌握了这些设计原则,在程序设计是能够灵活运用这些原则,设计出来的程序就一定会在以后的程序变动时,减少对其他程序的影响,从而能够更快的响应用户需求的改变,减少项目延期的可能性。
但是上面的这些设计原则只是理论,还不够具体,很少有开发人员能够深刻的理解并掌握这些设计原则,有没有更加具体的程序设计原则呢?这要从1979年说起,在1979年,建筑师Alexander(亚历山大)编写了一本叫《建筑的永恒之道》的书籍,这本书通过对当代建筑进行研究,发现那些优秀的建筑中,总是存在着一些相似之处,如果能够找到这些优秀建筑的特征,就能够找到这些建筑是采用了哪些方法,如何设计才变得优秀的,从而也就能够客观的评价一个建筑设计的好与坏。这些建筑与规划的新观点,在当时造成了很大的影响,人们开始讨论这些问题,并最终找到了一些答案。
程序设计和上面讲的建筑设计类似,很多软件开发人员也开始了寻找如何才能使程序设计的更加优秀的方法,只要遵循这些方法,程序就能设计的更加优秀。在20世纪90年代中期Gamma、Johnson、Helm、Vlissides等4个人就总结了前人的程序设计经验,写出了《设计模式》一书,该书研究了很多好的程序设计的方法,总结出了能够使程序设计的更好的23中方法,称为23种设计模式。
0 请登录后投票
   发表时间:2012-12-25  
这些模式分别从对象的创建、对象的结构和对象的行为3个方面来总结软件开发人员在程序设计方面的经验,并给出了具体的实现方法,和前面的面向对象的设计原则比起来,这些设计模式更加具体,开发人员也更容易理解,这23种设计模式也同样遵循了面向对象的设计原则。
(1)创建型模式
 单例模式(Singleton)
 简单工厂模式(Simple Factory),简单工厂模式并不在这23种设计模式之中。
 工厂方法模式(Factory Method)
 抽象工厂模式(Abstract Factory)
 原型模式(Prototype)
 创建者模式(Builder)
(2)结构型模式
 适配器模式(Adapter)
 门面模式(Facade)
 代理模式(Proxy)
 合成模式(Composite)
 享元模式(Flyweight)
 装饰模式(Decorator)
 桥模式(Bridge)
(3)行为型模式
 策略模式(Strategy)
 迭代器模式(Iterator)
 模板方法模式(Template Method)
 中介者模式(Mediator)
 访问者模式(Visitor)
 职责链模式(Chain of Responsibility)
 状态模式(State)
 解释器模式(Interpreter)
 观察者模式(Observer)
 命令模式(Command)
 备忘录模式(Memento)
0 请登录后投票
   发表时间:2012-12-25  
1.4  设计模式学习路线
本书后面的所有示例都将采用Java语言编写,所以在您看这本书之前,您需要具有Java语言的基础知识,尤其是有关接口和抽象类、实体类的使用方法,因为在后面讲解设计模式时有时会用到接口、有时会用到抽象类,而设计模式中抽象的定义可能指的是接口,也可能指的是抽象类,所以请读者务必区分清楚,为了强化读者对Java中,接口和抽象类的理解,这里重点进行讲述。在Java中,针对抽象有两种实现方式,一种是接口,一种是抽象类,两者在语法定义和使用方法上是不同的,更重要的是两者的根本思想是不一致的。
(1)基本语法不一致
在Java中,接口采用interface来定义,抽象类采用abstract class来定义,其中定义接口的示意代码如下:
//******* Test.java**************
package com;
public interface Test {
public void do();//只能定义抽象的方法
}
定义抽象类的示意代码如下:
//******* Test.java**************
package com;
public abstract class Test {
public abstract void do();//定义抽象方法
/*具体实现方法*/
public void doTest() {//也可以定义具体实现方法
    ……
}
}
代码说明:
 在接口内只能定义抽象方法,意味着这个接口是要被用来实现的,因此在接口中,所有的属性肯定是public static final,所有的方法都是abstract。
 在抽象类中既可以定义抽象方法,也可以定义具体实现方法。
接口和抽象类除了定义方式不一样外,它们的派生类(实现类)的定义方式也是不一样的,其中接口派生类的示意代码如下:
//******* TestImpl.java**************
package com;
public class TestImpl implements Test {
/*实现抽象方法*/
public void do() {
    ……
}
}
抽象类的派生类示意代码如下:
//******* TestImpl.java**************
package com;
public class TestImpl extends Test {
/*实现抽象方法*/
public void do() {
    ……
}
}
0 请登录后投票
   发表时间:2012-12-25  
代码说明:
 在接口的派生类中,标识符为implements,接口中所有的抽象方法必须要有具体的实现类,如果不希望所有的抽象方法都有具体实现,则实现类可以为抽象类。而且一个接口的实现类,可以实现多个接口。
 在抽象类的派生类中,标识符为extends,抽象类中所有的抽象方法必须要有具体的实现类,如果不希望所有的抽象方法都有具体实现,则实现类也可以为抽象类。一个抽象类的实现类,则只能实现一个抽象类。
(2)设计思想不一致
从前面接口和抽象类的语法可以得知,一个具体的派生类只能继承一个抽象类,所以父类和子类在概念上应该是相同的。一个具体的派生类可以实现多个接口类,所以父类和子类在概念上不一定相同,接口只是抽取相互之间没有关系的类的共同特征,而不去关注类之间的关系,它可以使没有层次关系的类具有相同的行为。所以抽象类是对一组具有相同属性和方法的逻辑上有关系的事物的一种抽象,表示的是“is a”的关系,而接口则是对一组具有相同属性和方法的逻辑上不相关的事物的一种抽象,表示的是“like a”的关系。
深刻的理解了Java中,接口和抽象类的区别,对于后面设计模式的学习很有帮助,所以读者需要多看、多练习,认真体会它们之间的区分。
在了解了Java中,接口和抽象类的区别后,接下来就要正式进入设计模式的学习了,从前面可以得知,通过对优秀的程序设计代码进行研究,设计模式主要是从对象的创建、结构和行为3个方面进行总结程序设计开发的实践经验。因此在学习的时候,也要按照这3个方面分门别类的进行学习,多多体会都是创建型模式,到底应用在什么场景呢?一定要通过具体的场景来学习设计模式。
另外,一定要记住,设计模式是为了使程序设计变得更加灵活、简单,能够适应用户需求的不断变化,而不是使程序设计的更复杂,因此,一定要避免过度的使用设计模式。过度的使用设计模式会增加程序的复杂性,从而降低了程序的易维护性。因此,学习设计模式,首先要了解该设计模式适用的场景,如果不采用设计模式提供的这种解决方式,会带来什么后果,接着总结每个设计模式的原理,在采用设计模式进行程序设计时,一定要牢记面向对象的设计原则。
0 请登录后投票
   发表时间:2012-12-25  
1.5  小结
本章首先描述了目前软件开发遇到的困境,以及软件开发人员为此所做的努力,接着引申出面向对象所遵循的设计原则,并重点讲解了这些设计原则,然后由引出了设计模式的产生原因,并对设计模式进行分门别类的介绍,最后重点讲解了设计模式的学习方法及注意事项,在介绍学习方式前,又对Java中接口和抽象类进行了深入的分析。
有了前面的这些基础介绍,其实已经可以进行详细的设计模式讲解了,但为了便于读者可以边学习边演练,所以接下来的一章中,将重点介绍一下本书使用的开发工具以及面向对象的设计语言UML。
0 请登录后投票
   发表时间:2012-12-25  
理解的云里雾里~
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics