`

设计原则(Java 与模式-笔记 一)

阅读更多

 

第二部分 面向对象的设计原则

 

如何同时提高一个软件系统的可维护性Maintainability)和可复用性Reuseability)是面向对象的设计要解决的核心问题。

一个好的系统设计应该有如下的性质:可扩展性(Extensibility)、灵活性(Flexibility)、可插入性(Pluggability

系统的可扩展性是由“开-闭”原则、里氏代换原则、依赖倒转原则和组合/聚合复用原则所保证的。

恰当地提高系统的可复用性,可以提高系统的灵活性。在一个设计得当的系统中,每一个模块都相对于其他模块独立存在,并只保持与其他模块的尽可能少的通信。这样一来,在其中某一个模块发生代码修改的时候,这个修改的压力不会传递到其他的模块。

系统的灵活性是由“开-闭”原则、迪米特法则、接口隔离原则所保证的。

恰当地提高系统的可复用性,可以提高系统的可插入性。在一个符合“开-闭”原则的系统中,抽象层封装了与商业逻辑有关的重要行为,这些行为的具体实现由实现层给出。当一个实现类不再满足需要,需要以另一个实现类取代的时候,系统的设计可以保证旧的类可以被“拔出(Unplug)”,新的类可以被“插入(Plug)”。

系统的可插入性是由“开-闭”原则、里氏代换原则、依赖倒转原则和组合/聚合复用原则所保证的。

 

1、“开-闭原则”(Open-Closed Principle,缩写为OCP

“开-闭”原则:一个软件实体应当对扩展开放,对修改关闭

如何实现?

1)抽象化是关键

Java 语言里,可以给出一个或多个抽象 Java 类或Java 接口,规定出所有的具体类必须提供的方法的特征作为系统设计的抽象层。这个抽象层预见了所有的可能扩展,因此,在任何扩展情况下都不会改变。这就使得系统的抽象层不需要修改,从而满足了“开-闭”原则的第二条:对修改关闭。

同时,由于从抽象层导出一个或多个新的具体类可以改变系统的行为,因此系统的设计对扩展时开发的,这就满足了“开-闭”原则的第一条:对扩展开放。

2)对可变性的封装原则

找到一个系统的可变因素,将它封装起来。一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。一种可变性不应当与另一种可变性呼喝在一起。所有的类图的继承接口一般不会超过两层,不然就意味着将两种不同的可变性混合在了一起。

相关的设计模式:策略模式、简单工厂模式、工厂方法模式、抽象工厂模式、建造模式、桥梁模式、门面模式、调停者模式、访问者模式迭代子模式。

当读者学习设计模式的时候,要学会问一个问题:这个设计模式可以对什么样的变换开放,以及它做到这一点所付出的代价是什么。通过这样的思考,可以更加透彻地了解这种模式对“开-闭”原则的支持程度,以及这种设计模式本身。

当代码包含大段大段的代码转移语句块往往意味着某种可变性。可以将这种可变性用多态代替,就意味着将这种可变性封装起来。但是如果一个条件转移语句没有涉及重要的商务逻辑,或者不糊随着时间的变化而变化,也不意味着任何的可扩展性,那么它就没有涉及任何有意义的可变性,这时候运用多态性就是毫无意义的。

 

附加专题内容:

Java 接口的常见的用法:单方法接口、标识接口、常量接口

在设计中,只要有可能,不要从具体类继承。从继承的等级结构里面,树叶节点均应当是具体类,而树枝节点均应当是抽象类(或接口)。这样的设计是所有的Java 设计师都应当努力做到的。

继承使用的条件,当以下的条件全部满足时:

1)子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分“Has-A”与“Is-A”两种关系的不同。Has-A关系应当使用聚合关系描述,而只有Is-A关系才符合继承关系。

2)永远不会出现需要将子类换成另一个类的子类的情况。如果设计师不是很肯定一个类会不会在将来变成另一个类的子类的话,就不应当将这个类设计成当前这个超类的子类。

3)子类具有扩展超类的责任,而不是具有置换掉(Override)或者注销掉(Nullify)超类的责任。如果子类需要大量地置换掉超类的行为,那么这个子类不应当成为这个超类的子类。

4)只有在分类学角度上有意义时,才可以使用继承,不要从工具类继承。

 

2、里氏代换原则(Liskov Substitution Principle,缩写为LSP

里氏代码原则的严格表达是:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。换而言之,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别

里氏代换原则讲的是基类与子类的关系。如果有两个具体类A之间的关系违反了这一原则的设计,根据具体情况可以在下面的两种重构方案中选择一种。

 



 相关的设计模式
:策略模式、合成模式、代理模式。

 

3、依赖倒转原则(Dependence Inversion Principle,缩写为DIP

依赖倒转原则讲的是:要依赖于抽象,不要依赖于具体。也就是说抽象不应当依赖于细节;细节应当依赖于抽象。另一种表述是,要针对接口编程,不要针对实现编程。

下图是违反依赖倒转原则的设计:

 



 正确的设计应该是:

 



 相关设计模式
:工厂方法模式、模板方法模式、迭代子模式。

依赖倒转原则的缺点是因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以比秒对具体类的直接引用,此原则的使用还会导致大量的类。

 

4、接口隔离原则(Interface Segreation Principle,缩写为ISP

接口隔离原则讲的是:使用多个专门的接口比使用单个的总接口要好。换而言之,从一个客户类的角度来讲,一个类对另外一个类的依赖性应当是建立在最小的接口上的。

接口隔离原则的一般常用的有:角色的合理划分、定制服务

 

5、合成/聚合复用原则(Composite/Aggregate Reuse Principle,缩写为CARP

合成/聚合复用原则就是:在一个新的对象里面使用一些已有的对对象,使之成为新对象的一部分,新的对象通过向这些对象的委派达到复用已有功能的目的。另一种表述是:尽量使用合成/聚合,尽量不要使用继承

合成和聚合的区别:聚合用来表示“拥有”关系或者整体与部分的关系;而合成则用来表示一种强得多的“拥有”关系,在合成关系里,部分和整体的生命周期是一样的。

 

6、迪米特法则(Law of Demeter,缩写为LoD

迪米特法则又叫做最少知识原则,就是说,一个对象应当对其他对象有尽可能少的了解

狭义的迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

下图是一个不满足迪米特法则的系统:

 



 满足地卡特法则的系统应该为:

 



 上图中使用了Friend 类作为中间层,间接调用Strange 类的方法。这样使得调用的具体细节被隐藏在Friend内部,从而使SomeoneStrange 之间的直接联系被省略掉了。这样一来,使得系统内部的耦合度降低。

但这样做有个明显的缺点:会在系统里造出大量的小方法,散落在系统的各个角落。这些方法仅仅是传递间接的调用。

广义的迪米特法则:其实,迪米特法则所谈论的,就是对对象之间的信息流量、流向以及信息的影响的控制。

在软件系统中,一个模块设计得好与不好的最主要、最重要的标志,就是该模块在多大的程度上将自己的内部数据和其他与实现有关的细节隐藏起来。一个设计得好的模块可以将它所有的实现细节隐藏起来,彻底地将提供给外界的API和自己的实现分隔开来,而不理会模块内部的工作细节。这一概念就是“信息的隐藏”,或者叫封装

迪米特法则的主要用意是控制信息的过载。在将迪米特法则运用到系统设计中时,要注意下面的几点:

1)在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。一个处在弱耦合中的类一旦被修改,不会对有关系的类造成波及。

2)在类的结构设计上,每一个类都应当尽量降低成员的访问权限。换言之,一个类包装好各自的private 状态。这样一来,想要了解其中的一个类的意义时,不需要了解更多别的类的细节。一个类不应当public 自己的属性,而应当提供取值和赋值方法让外界间接方法自己的属性。

3)在类的设计上,只要有可能,一个类应当设计成不变类

4)在对其他类的引用上,一个对象对其对象的引用应当降低到最低

相关设计模式:门面模式、调停者模式。

 

   这篇总结是我在一年前从 Java 与模式书上摘录的,自己觉得有用,容易忘记的,有时间便记录总结下。发表在这主要是为了方便以后能更好的回顾,还有几篇也将陆续整理下发表。。by zhxing

  • 大小: 40.1 KB
  • 大小: 18.3 KB
  • 大小: 16 KB
  • 大小: 19.9 KB
  • 大小: 13.4 KB
1
0
分享到:
评论

相关推荐

    java-design-patterns:Java 设计模式学习笔记

    在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式装饰器模式适配器模式外观模式组合模式享元模式行为型模式(更新中...)作用:将不同的行为代码解耦观察...

    尚硅谷设计模式源码笔记课件.zip

    1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种...

    设计模式之六大原则详解,Markdown笔记

    详细介绍了设计模式六大原则,配有示例代码和图片,有开闭原则,单一职责原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则等等。

    Java容器学习笔记:容器概览,容器中的设计模式,容器源码分析 - List,容器源码分析 - Map,容器源码分析 - 并发容

    它采用了“一次编写,到处运行”的原则,即一次编写的程序可以在不同的操作系统上运行,这得益于Java虚拟机(JVM)的存在。JVM是Java的核心组成部分,它可以将Java代码解释成特定平台上的机器码,从而实现跨平台运行...

    设计模式+UML.rar

    包含以下文件: Java设计模式-图解-附代码.pdf 从Java类库看设计模式.doc 六大UML类图关系.docx 认识UML类图元素_java之UML.doc 设计模式6大原则.doc 设计模式学习笔记.doc 深入浅出设计模式(中文版).pdf

    java学习笔记 初学者必读

    7.3.3. 运行时多态的三原则 7-19 7.3.4. 关系运算符:instanceof 7-20 7.4. 静态变量,方法和类 7-20 7.5. Singleton模式 7-22 7.6. final关键字 7-22 7.6.1. final变量不能被改变; 7-22 7.6.2. final方法不能被改写...

    设计模式经典样例笔记与代码Swift.zip

    设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...

    java版中国象棋源码-hello-design-pattern:设计模式学习笔记

    设计模式学习笔记,此项目参考《大话设计模式》,只能作为入门级设计模式学习 设计原则 职责单一原则 开放-封闭原则 依赖倒转原则 高层模块不依赖底层模块,两个模块都应该依赖抽象。抽象不依赖细节,细节依赖抽象。...

    Java/JavaEE 学习笔记

    第六章 设计原则与模式..................307 EJB学习笔记..................314 EJB前言................314 EJB2.0.....315 第一章 EJB介绍 .315 第二章 First EJB....318 第三章 EJB原理.320 第四章 Session ...

    初级java笔试题-oopnotes:面向对象编程笔记本,设计原则和模式参考指南

    我已将此笔记本作为面向对象编程概念和设计模式的参考指南。 我的目标是让任何人都能找到遵循面向对象范式正确设计可重用且高效的代码所需的核心概念。 在尝试学习自己的同时,我一直在努力研究并浪费大量时间在多个...

    java8源码-jcohy-study-sample:个人学习整理

    Ps:Java设计模式 [设计原则] [单一职责原则] [里氏替换原则] [依赖倒转原则] [接口隔离原则] [迪米特法则] [合成复用原则] 设计模式 创建型模式(5种) 结构型模式(7种) 关系型模式(11种) 适配器模式、装饰模式、代理...

    酒店管理客房系统Java源码-GOF23:Java实现23种设计模式学习笔记

    简单工厂模式:用来生产同一等级结构中的任意产品(对已有产品新增功能,需要修改源代码)虽然能通过工厂来创建对象,但是违反了开闭原则。一旦增加功能需要在原有基础上修改代码。 工厂方法模式:用来生产同一等级...

    android源码java-Omni-Notes:Android的开源笔记记录应用程序

    素描笔记模式 主屏幕上的Notes快捷方式 导出/导入注释以备份 与Google即时集成:只需先说“写便笺”,然后再讲内容 多个小部件,DashClock扩展,Android 4.2锁屏兼容性 多国语言:支持30多种语言: 进一步的发展将...

    高级java笔试题-Notebook:记录日常学习知识的笔记本

    内容包括三大原则(继承、封装、多态)、类图、设计原则。 数据库 :floppy_disk: 参考 数据库系统原理。 参考 SQL 必知必会。 Leetcode 上数据库题目的解题记录。 参考 高性能 MySQL。 参考 Redis 设计与实现、Redi

    设计模式.docx

    设计模式笔记,囊括23种设计模式,Java语言实现。 每个设计模式包含以下几块(1)问题案例,引出问题(2)解决思路与实现(3)注意点,模式解释,使用场合,关键点,相思模式差异。 在笔记最后进行设计模式总结(1)...

    程序员考试刷题-java8-ocp-study-notes:跟踪OCPJava8书籍学习指南的存储库

    程序员考试刷题java8-ocp-study-...设计模式和原则 第 3 章 - 泛型和集合 第 4 章 - 函数式编程 第 5 章 - 日期、字符串和本地化 第 6 章 - 异常和断言 第 7 章 - 并发 第 8 章 - IO 第 9 章 - NIO.2 第 10 章 - JDBC

    java-patterns:Java 23种基本的设计模式整料整理学习,责任链模式过滤器,工厂模式BeanFactory,观察者模式ContextListen等。结合Spring源码理解学习

    项目:Java模式 官方网站: : describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器...

    java培训上课资料pdf

    JavaSE/JavaEE:熟悉Swing、JDBC编程,了解Socket、多线程以及反射机制,对面向对象编程有较为 深刻的理解,理解常用设计模式和设计原则,能够熟练运用Struts、Spring、Hibernate等开 源框架,了解XML及其解析技术...

    整理后java开发全套达内学习笔记(含练习)

    原则,原理,主义 ['prinsipl] priority n. 优先级 [prai'ɒriti] process n. 程序, 进程 ['prɒses] protected (关键字) 受保护的,私有的 [prә'tektid] provide v.规定(供应,准备,预防)[prә'vaid] refer to v....

    谷歌师兄的leetcode刷题笔记-JavaNote:javaesguavajdkjdk8jsonlombokmdthreadjvmsprin

    基于以下的面向对象设计原则。 - 对接口编程而不是对实现编程。 - 优先使用对象组合而不是继承。 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern)...

Global site tag (gtag.js) - Google Analytics