设计模式之六大原则

上传人:daj****de2 文档编号:163531748 上传时间:2022-10-21 格式:DOCX 页数:9 大小:40.38KB
收藏 版权申诉 举报 下载
设计模式之六大原则_第1页
第1页 / 共9页
设计模式之六大原则_第2页
第2页 / 共9页
设计模式之六大原则_第3页
第3页 / 共9页
资源描述:

《设计模式之六大原则》由会员分享,可在线阅读,更多相关《设计模式之六大原则(9页珍藏版)》请在装配图网上搜索。

1、开闭原则开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定 的、灵活的系统。定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。Softeware entities like classes,modules and functions should be open for extension but closed for modifications.开闭原则的含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有代码来实现变化。 软件实体包括以下几个部分: 项目或软件产品中按照一定的逻辑规则划分的模块 抽象和类

2、方法开闭原则是为软件实体的未来事物而制定的对现行开发设计进行约束的一个原则。注意:开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模 块进行耦合,否则就是一个孤立无意义的代码片段了。变化的类型: 逻辑变化 子模块变化 可见试图变化一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计 和代码进行修改,运维尽量减少对原有代码修改,保持历史代码的纯洁性,提高系统的稳定性。开闭原则的重要性: 开闭原则对测试的影响开闭原则可是保持原有的测试代码仍然能够正常运行,我们只需要对扩展的代码进行测试就可以了。 开闭原则可以提高复用性在面

3、向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。 只有这样代码才可以复用,粒度越小,被复用的可能性就越大。 开闭原则可以提高可维护性 面向对象开发的要求如何使用开闭原则:抽象约束 第一,通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public 方法;第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;第三,抽象层尽量保持稳定,一旦确定即不允许修改。 元数据(metadata)控制模块行为元数据就是用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据 库中获得。Spring容器

4、就是一个典型的元数据控制模块行为的例子,其中达到极致的就是控制反转(Inversion ofControl) 制定项目章程在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说, 约定优于配置。 封装变化对变化的封装包含两层含义:第一,将相同的变化封装到一个接口或者抽象类中;第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类 中。二、迪米特法则定义:迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP)。一个对象应该对其他对象有最少的了解。

5、通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的public方法, 我就调用这么多,其他的一概不关心。含义: 只和朋友交流朋友类的定义是这样的:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体 内部的类不属于朋友类。下面的代码在方法体内部依赖了其他类,这严重违反迪米特法则1234public class Teacher public void commond(GroupLeader groupLeader) List listGirls = new ArrayList(); for

6、(int i = 0; i 20; i+) 5678910111213listGirls.add(new Girl();groupLeader.countGirls(listGirls);方法是类的一个行为,类竟然不知道自己的行为与其他类产生了依赖关系,这是不允许的。正确的做法是:1234567public class Teacher public void commond(GroupLeader groupLeader) groupLeader.cou nt Girls();123public class GroupLeader 4private List listGirls;5public

7、 GroupLeader(List _listGirls) 6this.listGirls = listGirls;78public void countGirls() 9System.out.println(女生数量是:+ listGirls.sizeO);10111213注意:一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD ()这种情况(在一 种极端情况下允许出现这种访问,即每一个点号后面的返回类型都相同),类与类之间的关系是建立在类 间的,而不是方法间,因此一个方法尽量不引入一个类中不存在的对象,当然, JDK API 提供的类除外。朋友间

8、也是有距离的一个类公开的 public 属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。因此, 为了保持朋友类间的距离,在设计时需要反复衡量:是否还可以再减少public方法和属性,是否可以修改 为private、package-private (包类型,在类、方法、变量前不加访问权限,则默认为包类型)、prot ected 等访问权限,是否可以加上 final 关键字等。注意:迪米特法则要求类羞涩”一点,尽量不要对外公布太多的public方法和非静态的public变量,尽 量内敛,多使用 private、package-private、protected 等访问权限。 是

9、自己的就是自己的如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,就放置在本类中。 谨慎使用 Serializable最后,迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。三、接口隔离原则接口隔离原则 Interface Segregation Principle定义: 客户端不应该依赖它不需要的接口 类间的依赖关系应该建立在最小的接口上我们可以把这两个定义概括为一句话:建立单一接口,不要建立臃肿庞大的接口。再通俗一点讲:接口尽 量细化,同时接口中的方法尽量少。提供给每个模块的都应该是单一接口,提供给几个模块就应该有几个接口,而不是建立一个庞大

10、的臃肿的 接口,容纳所有的客户端访问。接口是我们设计时对外提供的契约,通过分散定义多个接口,可以预防未来变更的扩散,提高系统的灵活 性和可维护性。含义: 接口要尽量小这是接口隔离原则的核心定义,不出现臃肿的接口(Fat Interface),但是小”是有限度的,首先就是不 能违反单一职责原则。根据接口隔离原则拆分接口时,首先必须满足单一职责原则。 接口要高内聚高内聚就是要提高接口、类、模块的处理能力,减少对外的交互。具体到接口隔离原则就是,要求在接口中尽量少公布public方法,接口是对外的承诺,承诺地越少对系统 开发越有利,变更的风险也就越少,同时也有利于降低成本。 定制服务定制服务就是单独

11、为一个个体提供优良的服务。接口设计是有限度的 接口的设计粒度越小,系统越灵活,这是不争的事实。但是,灵活的同时也带来了结构的复杂化,开发难 度增加,可维护性降低,这不是一个项目或产品所期望看到的,所以接口设计一定要注意适度,这个度只 能根据经验和常识判断,没有一个固化或可测量的标准。四、依赖倒置原则依赖倒置原则(Dependence Inversion Principle, DIP)的原始定义: 高层模块不应该依赖底层模块,两者都应该依赖其抽象; 抽象不应该依赖细节; 细节应该依赖抽象。依赖倒置原则在Java语言中的表现是: 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系

12、是通 过接口或者抽象类产生的; 接口或抽象类不依赖于实现类; 实现类依赖接口或抽象类。依赖倒置原则实际上就是要求“面向接口编程”。采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可 读性和可维护性。例如:司机接口12345public interface IDriver public void driver(ICar car);司机实现类12public class Driver implements IDriver public void driver(ICar car) 1234567public class Benz implements ICa

13、r public void run() Sys tem.ou t.prin tln(“ 奔驰汽车开始运行.); 1234567public class BMW implements ICar public void run() Sys tem.ou t.prin tln(“ 宝马汽车开始运行.); 场景类123456789101112public class Client /* param args*/publics tati c void main(S tring args) IDriver zhangSan = new Driver。;ICar benz = new Benz(); zha

14、ngSan.driver(benz);抽象是对实现的约束,对依赖者而言,也是一种契约,不仅仅约束自己,还同时约束自己与外部的关系, 其目的是保证所有的细节不脱离契约的范畴,确保约束双方按照既定的契约(抽象)共同发展,只要抽象 这根基线在,细节就脱离不了这个圈圈,始终让你的对象做到“言必信,行必果”。依赖的三种写法只要做到抽象依赖,即使是多层的依赖传递也无所谓惧!构造函数传递依赖对象构造函数注入12345678910111213public class Driver implements IDriver private ICar car;public Driver(ICar _car) t hi

15、s.car = _car;public void driver() t his.car.run();Sette r方法传递依赖对象Sette r依赖注入12345678910111213141516public class Driver implements IDriver private ICar car;/* param car the car to set */public void setCar(ICar car) t his.car = car;public void driver() t his.car.run();接口声明依赖对象接口注入12345public class Dri

16、ver implements IDriver public void driver(ICar car) car.run();6本质:依赖倒置原则的本质就是通过抽象(接口或者抽象类)使各个类或模型的实现彼此独立,不互相影响,实 现模块间的松耦合。规则: 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备; 变量的表面类型尽量是接口或者抽象类; 任何类都不应该从具体类派生; 尽量不要覆写基类的方法; 结合里氏替换原则使用。接口负责定义 public 属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现 实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。依赖倒置与依赖正

17、置依赖正置就是类间的依赖是实实在在的实现类间的依赖,也就是面向实现编程,这也是正常人的思维方式, 我要开奔驰车就依赖奔驰车,我要使用笔记本电脑就直接依赖笔记本电脑,而编写程序需要的是对现实世 界的事物进行抽象,抽象的结构就是有了抽象类和接口,然后我们根据系统设计的需要产生了抽象间的依 赖,代替了人们传统思维中的事物间的依赖, “倒置”就是从这里产生的。五、里氏替换原则里氏替换原则(Liskov Substitution Principel)是解决继承带来的问题。继承的优点: 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性; 提高代码的重用性; 子类可以形似父类,但又异于父类; 提

18、高代码的可扩展性; 提高产品或项目的开放性。继承的缺点: 继承是侵入性的,只要继承就必须拥有父类的所有属性和方法; 降低代码的灵活性,子类必须拥有父类的属性和方法,让子类增加了约束; 增强了耦合性,当父类的常量、变量和方法被修改时,必须考虑子类的修改。定义:所有引用基类的地方必须能透明地使用其子类的对象。通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者 可能根本就不需要知道是父类还是子类。但是,反过来就不行了,有子类出现的地方,父类未必就能适应。含义: 子类必须完全实现父类的方法在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,则说明类

19、的设计已经违背了里氏 替换原则。如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中发生了“畸变”,则建议断开父子继承 关系,采用依赖、聚集、组合等关系代替继承。 子类可以有自己的个性 覆盖或实现父类的方法时输入参数可以被放大如果子类的前置条件较小,子类在没有覆写父类的方法的前提下,子类方法被执行了,这会引起业务逻辑 混乱,因为在实际应用中父类一般都是抽象类,子类是实现类,你传递一个这样的实现类就会“歪曲”了父 类的意图,引起一堆意想不到的业务逻辑混乱。 覆盖或实现父类的方法时输出结果可以被缩小目的:采用里氏替换原则的目的就是增强程序的健壮性,版本升级是也可以保持非常好的兼容性。即使增

20、加子类, 原有的子类还可以继续运行。在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不 同的子类完成不同的业务逻辑。六、单一职责原则定义:应该有且仅有一个原因引起类的变更。There should never be more than one reason for a class to change.优点:1、类的复杂性降低,实现什么职责都有清晰明确的定义;2、可读性提高,复杂性减低,可读性当然提高;3、可维护性提高,可读性提高,可维护性当然提高;4、变更引起的风险减低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的类有 影响,对其他接口无影响,这对系统的扩展性、维护性都有非常大的帮助。注意:单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是 “职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。建议:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!