没有合适的资源?快使用搜索试试~ 我知道了~
论设计模式的重要性-《重学设计模式》
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 1 下载量 82 浏览量
2022-07-05
23:48:19
上传
评论
收藏 2.07MB PDF 举报
温馨提示
试读
130页
带书签,带案例,带使用场景,一看就懂。 事实上,我们可能很多情况下都是在不了解设计模式或者了解的不多的情况下作为程序员工作了多年。也在不经意间实现了一些设计模式。 那么我们为什么还要学习设计模式? 一方面,设计模式教我们如何使用面向对象设计的原则解决各种问题; 另一方面,设计模式定义了一种通用语言(跟框架一样,统一一个标准),让大家在做系统设计的时候,能更有效的交流。 我们学习设计模块的核心思想是解耦合,并不是消除耦合,而是把耦合控制在一定范围,保证这个范围的整洁。 使用设计模式的步骤可以总结成两句话: 1)设计模式中提到一句很精髓的话:找到稳定点和变化点,运用抽象,把变化点隔离起来。 2)先满足设计原则,再迭代出设计模式。 其实各设计模式之间都是有共通之处的(在java中是抽象、继承、多态、组合的综合运用),有些看起来十分类似但又能解决不同的问题,这些都是前人总结的经验,你也可以组合出更适用于你所编写的程序的一种模式。
资源推荐
资源详情
资源评论
重学设计模式
1、设计模式概述
1.1、软件设计模式的产生背景
“设计模式”最初并不是出现在软件设计中,而是被用于建筑领域的设计中。
1997年,美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫·亚历山大
(Christopher Alexander)在他的著作《建筑模式语言:城镇、建筑、构造(A Pattern Language:
Towns Building Construction)中描述了一些常见的建筑设计问题,并提出了 253 种关于对城镇、邻
里、住宅、花园和房间等进行设计的基本模式。
直到 1990 年,软件工程界才开始研讨设计模式的话题,后来召开了多次关于设计模式的研讨会。
1995 年,艾瑞克·伽马(ErichGamma)、理査德·海尔姆(Richard Helm)、拉尔夫·约翰森(Ralph
Johnson)、约翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《设计模式:可复用面向对象软
件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)一书,在本教程中
收录了 23 个设计模式,这是设计模式领域里程碑的事件。
GoF反复向你强调一个宗旨:要让你的程序尽可能的可重用。
1.2、什么是设计模式
设计模式(Design Pattern)是一种模式,是前辈们对代码开发经验的总结,是解决特定问题的一系
列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的
解决方案,它是思想的体现,而非具体的实现。
这 23 种设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及
类的关联关系和组合关系的充分理解(即包含了面向对象的精髓)。
1.3、我们为什么要学习设计模式
事实上,我们可能很多情况下都是在不了解设计模式或者了解的不多的情况下作为程序员工作了多
年。也在不经意间实现了一些设计模式。
那么我们为什么还要学习设计模式?
一方面,设计模式教我们如何使用面向对象设计的原则解决各种问题;
另一方面,设计模式定义了一种通用语言(跟框架一样,统一一个标准),让大家在做系统设计的时
候,能更有效的交流。
我们学习设计模块的核心思想是解耦合,并不是消除耦合,而是把耦合控制在一定范围,保证这个范
围的整洁。
使用设计模式的步骤可以总结成两句话:
1)设计模式中提到一句很精髓的话:找到稳定点和变化点,运用抽象,把变化点隔离起来。
2)先满足设计原则,再迭代出设计模式。
1.4、接口与抽象类
在学习设计模式前,我们先来复习一下什么是接口、什么是抽象类。
在面向对象的设计领域里,有时候会用is-a、has-a、like-a来描述他们之间的关系。例如:A is-a B,代
表B是A的父类;A has-a B,那么B就是A的组成部分。A like-a B,则代表B就是A的接口。
设计模式并非只针对于java,而是所有面向对象语言的设计模式,在接下来的设计模式讲解中,我们以
java为例。为什么选择java?java作为一门集大成的语言,博纳众多语言之所长,是最优秀的面向对象语
言之一。
1.4.1、什么是接口
接口通常代表一种承诺或者规范,是对象必须遵守的承诺,即使实现类发生再大的变化,也能保证所
有的实现类都有相关的方法可供调用;也就是说,实现类有责任去编写实现我接口中的方法,即使是一
个空方法。
java将接口的概念升为独立的结构,体现了接口与实现的分离。
1.4.2、什么是抽象类
在面向对象的概念中,我们所有的对象都是通过类来描述的。而反过来确不是这样的,并不是所以的
类都是用来描绘对象的,如果一个类中没有足够的信息来描绘一个具体的对象,那么这样的类就是抽象
的。
抽象类除了不能实例化对象之外,类的其它功能依然存在。抽象类更多的是对通用的、基础的方法封
装,让子类复用,避免在子类开发重复的代码。子类只需实现抽象方法,也可以有选择的覆盖抽象父类
的方法。
1.4.3、接口与抽象类的区别
一个类可以实现多个接口,但是只能继承一个抽象类;
接口都是抽象方法,而抽象类中既可以有抽象方法,也可以有实例(具体)方法;
接口中的变量都是public static final;而抽象类中的变量可以被任何通用修饰符修饰;
接口的方法都是public;抽象类中的方法可以是public、protected、private或者默认的package;
接口不能定义构造函数,但抽象类可以。
2、软件设计的七大原则
设计模式不是为每个人准备的,而是基于业务来选择设计模式,要明白一点,技术永远为业务服务,
技术只是满足业务需要的一个工具。在软件开发中,应当尽量提高系统的可维护性和可复用性,增加软
件的可扩展性和灵活性。
在了解设计模式之前,我们先了解下软件设计的七大原则,它们分别是:单一职责原则、里氏替换原
则、接口隔离原则、开闭原则、依赖倒置原则、迪米特法则和合成复用原则。
实际上,这些原则的目的只有一个:降低对象之间的耦合,增加程序的可复用性、可扩展性和可维护
性。
2.1、单一职责原则-SRP
2.1.1、定义
单一职责原则(Single Responsibility Principle,SRP)又称单一功能原则,由罗伯特·C.马丁
(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中提出的。
英文定义:There should never be more than one reason for a class to change。
一个类改变的原因不应该超过一个(这里的职责被定义为“变化的原因”)。
单一职责原则:是指一个类(大到模块、小到方法)只负责完成一个职责。通俗的说就是一个类、模
块、方法不要承担过多的任务,要符合高内聚、低耦合的思想。
所以我们设计一个类的时候不应该设计成大而全的类,要设计粒度小,功能单一的类。一个类承担的
职责越多,它被复用的可能性更小,当一个职责变化时,可能会影响其他职责的运作。
单一职责原则,就是为了处理“胖”接口的缺点,如果一个类有两个或者两个以上互不想干的功能,那
我们就说它违背了单一职责原则(是不内聚的类),应该将其拆分功能单一、粒度更细的类。但是如果
拆分得过细,实际上会适得其反,反倒会降低内聚性,也会影响代码的可维护性。
2.1.2、原则解析
其实在生活的方方面面都体现了我们设计中的很多原则。古人说的不错:狡兔死,走狗烹;飞鸟尽,
良弓藏;敌国破,谋臣亡。善谋略、握兵权,功高震主,一个人功能太多,太锋芒毕露,就是比较危险
的人物。
同理,一个类承担过多的职责,也是比较危险的一种行为。一旦涉及到修改,尤其是较大的修改,就
可能出现出人意料的bug。
在JavaEE中的分层架构中,实际上就体现了单一职责原则。对用户操作,可以分解为存储数据的实体
类User,完成数据库操作的UserDao,完成业务操作的业务类UserService以及显示用户信息的页面
user.jsp。
案例实践
如果有这样一个抽象类Door。
一个很纯粹的抽象类,符合单一职责。那现在我们需要为这个门增加一个报警功能alarm方法呢?你
会怎么加?
或者是
abstract class Door{
abstract void open();
abstract void close();
}
abstract class Door{
abstract void open();
abstract void close();
abstract void alarm();
}
你觉得哪种方式对呢?
其实,上面两种方式都违反了ISP原则。
首先第一种方式:把Door概念本身具有的行为方法和另外一个概念“报警器”的行为混在一起了。并不
是所有的门都需要报警器这个功能,门这个抽象类(或接口)已经被不需要的功能污染了,那么以Door
作为基类的子类会因“报警器”这个概念的改变而改变,并使其变“胖”。
第二种方式:这个AlarmDoor在概念本质上到底是Door还是报警器?一般使用继承在本质上就是is-a
的关系。既然open、close和alarm属于两个不同的概念,根据ISP原则就应该把alarm拆出来。
注:这样写说明AlarmDoor本质上是Door,又具有报警概念。如果AlarmDoor本质上是报警器,那
就应该反过来。
2.1.3、总结及建议
单一职责原则是开发中最基础、最简单的一个原则,但又是一个最难把握的一个原则,在实际中有时
很难界定职责的边界,这个变化原因的粒度也需要结合实际去运用,因为可能每个人理解的职责范围或
者考虑方向不一样,得出的结论可能就不一样。就像做菜,说明上是写,盐方少许,那这个少许的标准
是多少?我们和厨师区别大概就在这个度的把握上。
再比如:在西方文化中,吃饭的工具有刀和叉,他们对刀和叉的分工就很明确,刀负责分离食物,叉
负责运送食物。而我们吃饭的工具就是筷子,一双筷子既可以分离食物也可以运送食物。很大程度上,
中西文化差异也会造成理解上的差异。
所以呢,不必严格遵守原则,只是作为参考。实际开发中可以参考以下意见:
1)一般对一个类或模块职责的分解可以从两个方面去考虑:一个是属性(结构)职责和一个是行为职
责。
2)类依赖过多的其他类,或者代码直接依赖关系过于复杂时,不符合高内聚低耦合的设计思想时,就
可以考虑对代码进行拆分;
3)类名和实际功能关系不大或者没有任何关联时,可以把无关的功能独立出去;
4)类的代码函数过多影响可读性和代码维护时,可以对代码进行方法级别的拆分;
总之一句话:接口尽量做到单一职责,类的设计尽量做到只有一个原因引起变化,因为我们的最终目
的都是让我们的代码具有更好的复用性、可读性、可维护性、可扩展性......
class AlarmDoor extends Door{
void open();
void close();
void alarm();
}
interface Alarm{
void alarm();
}
class AlarmDoor extends Door implements Alarm{
void open();
void close();
void alarm();
}
2.2、开闭原则-OCP
2.2.1、定义
1988年,Bertrand Meyer在他的著作《Object Oriented Software Construction》中提出了开闭原
则(Open-Closed Principle, OCP)。
英文定义:Software entities(classes,modules,function,etc)should be open for extension but
closed for modification。
一个软件实体(如类、模块和函数等)应该对扩展开放,对修改关闭。
开闭原则中的“开”,是指对于组件功能(提供方)的扩展是开放的,是允许对其进行功能扩展的;开
闭原则中的“闭”,是指对于原有代码的修改(使用方)是封闭的,即不应该修改原有的代码。
抽象化是开闭原则的关键,强调的是用抽象构建框架,用实现扩展细节。简单的说:尽量通过扩展软件
实体的行为来实现变化,而不是通过修改已有的代码来引入新功能,达到开闭原则的要求。
其他设计原则都可以看作是开闭原则实现的手段和方法。
2.2.2、原则解析
其实看完上面那些定义就很抽象,因为我也没明白怎么扩展?怎么关闭?
什么是为扩展开放?为修改关闭?
有一句话总结的不错:对扩展开放是为了应对需求的变化,对修改关闭是为了保证代码的稳定性。
我们添加一个新的功能,应该是通过在已有代码基础上扩展代码(新增模块、类、方法、属性等,比
如:说普遍一点就是通过继承和组合的方式扩展,说的详细一点,实际中我们常见的方式有多态、依赖
注入、面向接口编程等等),而非修改已有代码(修改模块、类、方法、属性等)的方式来完成。
这里的关闭并不是说完全杜绝了修改,因为不管一个模块有多“封闭”,总会有一些变化,它不会或者
无法完全关闭。这就要我们找到代码的稳定点和变化点,将变化控制在一定的范围,事先在这里预留好
扩展点,以最小的代价来完成新功能的开发,新代码能够很灵活的插入到扩展点上。
开闭原则作为最重要的原则之一,我们这里就描述的更详细一点。
为什么抽象是开闭原则的关键?
我们来看一个案例:
这符合开闭原则吗?首先这是一个客户端连接服务端的一个例子。客户端是固定的,稳定点是客户
端,服务端是不固定的变化点,有一天我需要新增或者更换服务端,那我客户端Client的代码是不是需
要较大的修改了。这不符合开闭原则。
那如何保证整体的稳定性,如何去隔离变化点,使其趋于稳定?
剩余129页未读,继续阅读
资源评论
- 云晓10142022-11-03超级好的资源,很值得参考学习,对我启发很大,支持!
穆瑾轩
- 粉丝: 1871
- 资源: 48
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功