设计模式 -- 设计原则

设计原则

一句话归纳

目的

开闭原则

对扩展开放,对修改关闭

降低维护带来的新风险

依赖倒置原则

高层不应该依赖低层,要面向接口编程

更利于代码结构的升级扩展

单一职责原则

一个类只干一件事,实现类要单一

便于理解,提高代码的可读性

接口隔离原则

一个接口只干一件事,接口要精简单一

功能解耦,高聚合、低耦合

迪米特法则

不该知道的不要知道,一个类应该保持对其它对象最少的了解,降低耦合度

只和朋友交流,不和陌生人说话,减少代码臃肿

里氏替换原则

不要破坏继承体系,子类重写方法功能发生改变,不应该影响父类方法的含义

防止继承泛滥

合成复用原则

尽量使用组合或者聚合关系实现代码复用,少使用继承

降低代码耦合

1. 开闭原则(Open Close Principle)OCP

对扩展开放,对修改关闭。

当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

使用接口和抽象类,达到热插拔的效果。

实现方法

用抽象构建框架,用实现扩展细节(用细节实现扩展)

可以通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。

只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。

2. 里氏替换原则(Liskov Substitution Principle) LSP

任何基类可以出现的地方,子类一定可以出现。

子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法

  • 子类中可以增加自己特有的方法

  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松

  • 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的输出/返回值)要比父类的方法更严格或相等

通过重写父类的方法来完成新的功能写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。

关于里氏替换原则的例子,最有名的是“正方形不是长方形”。当然,生活中也有很多类似的例子,例如,企鹅、鸵鸟和几维鸟从生物学的角度来划分,它们属于鸟类;但从类的继承关系来看,由于它们不能继承“鸟”会飞的功能,所以它们不能定义成“鸟”的子类。同样,由于“气球鱼”不会游泳,所以不能定义成“鱼”的子类;“玩具炮”炸不了敌人,所以不能定义成“炮”的子类等。

举例:一个继承树中,所有树节点都是抽象类,所有的叶子节点都是具体实现类。使用父类的地方可以传入任何一个子类。这个最经典的就是Android中的View继承树了,所有传入ViewGroup的方法可以传入任何一个继承自ViewGroup的容器;可以传入View的方法可以传入任何一个ViewGroup或者继承自View的控件。如setContentView(Viewv),既然参数是View,那么传入任何一个继承自View的控件都可以,如TextView,LinearLayout等。

实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现。

里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。

3. 依赖倒转原则(Dependence Inversion Principle)DIP

针对接口编程,依赖于抽象而不依赖于具体。

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。

要面向接口编程,不要面向实现编程。

依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。

使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成。

实现方法

依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点:

  • 每个类尽量提供接口或抽象类,或者两者都具备。

  • 变量的声明类型尽量是接口或者是抽象类。

  • 任何类都不应该从具体类派生。

  • 使用继承时尽量遵循里氏替换原则。

4. 单一职责原则(Single Responsibility Principle)SRP

一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。

单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。

实现方法

单一职责原则是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。

5. 接口隔离原则(Interface Segregation Principle)ISP

客户端不应该被迫依赖于它不使用的方法。

一个类对另一个类的依赖应该建立在最小的接口上。

要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。

要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

也称接口最小化原则,强调的是一个接口拥有的行为应该尽可能的小。

一个类/接口/方法只负责一项原则

实现方法

  • 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。

  • 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。

  • 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑。

  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

6. 迪米特法则(最少知道原则)(Law of Demeter,LoD)

一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

一个对象应该对其他对象保持最少的了解。

尽量降低类与类之间的耦合。

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

实现方法

从迪米特法则的定义和特点可知,它强调以下两点:

  1. 从依赖者的角度来说,只依赖应该依赖的对象。

  2. 从被依赖者的角度说,只暴露应该暴露的方法。

所以,在运用迪米特法则时要注意以下 6 点。

  1. 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。

  2. 在类的结构设计上,尽量降低类成员的访问权限。

  3. 在类的设计上,优先考虑将一个类设置成不变类。

  4. 在对其他类的引用上,将引用其他对象的次数降到最低。

  5. 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。

  6. 谨慎使用序列化(Serializable)功能。

7. 合成复用原则(Composite Reuse Principle)CRP

尽量使用合成/聚合的方式,而不是使用继承。

又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

通常类的复用分为继承复用合成复用两种。

实现方法

合成复用原则是通过将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而达到复用。


根据以下文章总结:

  1. Java设计模式:23种设计模式全面解析(超级详细)HYPERLINK http://c.biancheng.net/design_pattern/ n委派模式在JDK以及Spring源码中的应用_蒙奇D灬小武的博客-CSDN博客

  2. 3种设计模式详解 https://www.iteye.com/blog/zz563143188-1847029 

  3. Android系统编程思想:设计模式https://github.com/sucese/android-open-source-project-analysis/blob/master/doc/Android%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%AF%87/02Android%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%AF%87%EF%BC%9A%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md#35-%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F

  4. 设计模式 https://blog.csdn.net/shusheng0007/category_8638565.html 永不磨灭的设计模式(有这一篇真够了,拒绝标题党)_ShuSheng007的博客-CSDN博客_永不磨灭的设计模式

  5. java设计模式 https://blog.csdn.net/qq_37909508/category_8976362.html

  6. 设计模式 设计模式 - 随笔分类 - 左潇龙 - 博客园

  7. 设计模式 在源码中的应用 https://blog.csdn.net/qq_36970993/category_10620886.html

  8. Android系统设计中存在设计模式分析 https://www.2cto.com/kf/201208/150650.html

  9. Android设计模式系列 - 基于android的各种代码分析各种设计模式 https://www.cnblogs.com/qianxudetianxia/category/312863.html 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值