OO本身就是一种大的设计模式,它是随着软件规模越来越大产生出来帮助人们建模和开发的理念,生来就带着封装、继承、多态等可复用基因。为了充分发挥这些基因的功效,使用者需要遵守一定的原则,就是所谓的面向对象设计原则。然而正确地使用这些运用这些原则并不容易,只有把这些原则吸收成为身体一部分的经验丰富的工程师才能在遇到各种问题时,灵活地使用它们。一些OO大师为了方便新手更好地理解OO原则,就根据经验假象了一些软件设计过程中经常碰到的问题,并给出了遵循OO原则的解决这些问题的设计方案,就产生了设计模式,正如设计模式的定义:设计模式就是我们周围不断重复发生的问题,以及该问题的解决方案的核心【Christopher Alexander】。
        
      OO设计原则是根本,设计模式是设计原则在具体问题中的应用。本文将尝试汇总究竟有哪些OO设计原则,以及它们之间的内在联系。
      首先不得不提著名的SOLID原则:Single responsibility, Open closed, Liskov substitution, Interface segregation, Dependency inversion。
    单一责任原则SRP(Single Responsibility Principle):一个类/对象只有一个引起变化的原因。换言之,一个类只有一个类型责任。(高内聚)
    开放封闭原则OCP(Open Closed Principle):软件实体对扩展开放(对于系统),修改关闭(对于成型模块)。
    里氏替换原则LSP(Liskov Substitution Principle):子类的实例能够替换其父类的实例。基本地说,也就是“子类型必须能够替换掉它们的父类型”。一个软件实体如果运用的是一个父类的话,那          么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。在程序中,把父类都替换成它的子类,程序的行为没有变化.(正方形不是长方形),最有难度的约束设计.
    接口分离原则ISP(Interface Segregation Principle):使用多个专门的接口比使用单一的总接口要好。一个类对另一个的依赖性建立在最小的接口上。
    依赖倒置原则DIP(Dependency Inversion Principle):依赖抽象不要依赖具体实现。(1)高层模块不应该依赖底层模块。两个都应该依赖抽象(2)抽象不应该依赖细节,细节应该依赖于抽象
      其它OO设计原则:
    DRY原则(Don't repeat yourself):避免重复的代码,这样会降低可维护性。
    封装变化原则:把会变化的部分独立出来,让其他部分不受影响。
    组合复用原则:优先使用组合而不是继承,通过获得对其他对象的引用而在运行时刻动态改变对象行为。
    针对接口编程而不是实现:依赖抽象类的接口,可以在运行时改变对象行为,也就是多态。
    迪米特法则LoD(Law of Demeter):也称为最少知识原则LKP(Least Knowledge Principle)。就是说,一个对象应当对其它对象有尽可能少的了解.如果两个类不必彼此直接通信,那么这两个          类就不应当发生直接的相互作用。如果其中一个类须要调用另一个类的某一个要领的话,可以通过第三者转发这个调用。“。它强调我们在封装类的时候,在类的设计结构上,每一个类都          应当降低成员的访问权限。类与类之间的耦合度越低越好,因为一个类被修改,不会对有关联的其他类也执行 修改。(发布-订阅模式),低耦合.
    松耦合原则:对象之间的依赖尽量的少。
    好莱坞原则:别调用我们,我们会调用你。

看到这么多设计原则可能会有些头晕,就像小时候妈妈教我们的做人大道理,宽泛而很难体会,没有经验的工程师只能把他们背下来,在以后的实践过程中慢慢体会。我们可以初步分析一下这些原则的内在联系。
      其中DRY原则松耦合原则,是所有原则的基础,不仅是OO设计的根本,也是所有软件设计的灵魂,我们暂且不归为OO设计原则,应该作为公理存在潜意识中,就像”你要做个好人“。
      封装变化原则,目的是为了提高代码的可维护性,就面向对象设计而言,开放封闭原则就包含了封装变化原则,不仅包含了,跟进一步用扩展的方法来约束变化,所以该原则可以纳入开放封闭原则。
      针对接口编程而不是实现依赖倒置原则很相似,可以说是同一原则的着眼点不同,针对接口编程原则强调的是接口的客户,接口使用者不用关心接口的具体实现;依赖倒置原则强调的是高层模块与底层模块的依赖关系。其实二者是一个原则。
      好莱坞原则依赖倒置原则在框架设计中的一种技巧,可以不作为一个单独的原则。

经过萃取,我们留下了七大面向对象设计原则,他们是:单一责任原则、开放封闭原则、里氏替换原则、接口分离原则、依赖倒置原则、组合复用原则、迪米特法则

※单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。

单一是一个类的优良设计。交杂不清的职责将使得代码看起来特别别扭牵一发而动全身,

有失美感和必然导致丑陋的系统错误风险。

※开放封闭原则:是说软件实体(类、模块、函数等等)应该可以扩展但不可修改。

实现开开放封闭原则的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。

让类依赖于固定的抽象,所以修改就是封闭的;而通过面向对象的继承和多态机制,

又可以实现对抽象类的继承,通过覆写其方法来改变固有行为,实现新的拓展方法,所以就是开放的。

“需求总是变化”没有不变的软件,所以就需要用封闭开放原则来封闭变化满足需求,

同时还能保持软件内部的封装体系稳定,不被需求的变化影响。

※依赖倒置原则:依赖抽象,不要依赖具体。

抽 象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,

也是依赖倒置原则的核心。依赖于抽象是一个通用的原则,而某些时候依 赖于细节则是在所难免的,

必须权衡在抽象和具体之间的取舍,方法不是一层不变的。依赖于抽象,就是对接口编程,不要对实现编程。

 ※里氏代换原则:子类型必须能够替换到他们的父类型。

Liskov 替换原则,主要着眼于对抽象和多态建立在继承的基础上,因此只有遵循了Liskov替换原则,

才能保证继承复用是可靠地。实现的方法是面向接口编程:将公 共部分抽象为基类接口或抽象类,

通过ExtractAbstractClass,在子类中通过覆写父类的方法实现新的方式支持同样的职责。Liskov替 换原则能够

保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余,避免运行期的类型判别。

 ※接口隔离原则:多个和客户相关的接口要好于一个通用接口。

分离的手段主要有以下两种:1、委托分离,通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,

但是会增加系统的开销。2、多重继承分离,通过接口多继承来实现客户的需求,这种方式是较好的。

下边是前面没有提到过的两个原则,也是设计时要考虑的重要原则。

※迪米特法则:不相互直接通信的类之间,不要直接发生相互作用。

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用领一个类的

某个方法话,可以通过第三者转发这个调用。迪米特法则首先强调的前提是在类的设计上,每一类都应当尽量

降低成员的访问权限。它的根本思想是强调类之间的松耦合。

 ※合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用继承。

合 成(Composition)和聚合(Aggregation)都是关联的特殊种类,聚合表示一种弱的拥有关系;

合成这是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。

优先使用合成或聚合原则将有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承

层次会保持较小规 模,并且不太可能增长为不可控制的庞然大物。

OO设计基本原则的更多相关文章

  1. SOLID (面向对象设计) 基本原则

      SOLID (面向对象设计) 基本原则    在 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特•C•马丁在21世纪早期[1] 引入的记忆术首字母缩略 ...

  2. OO设计

    Todd.log - a place to keep my thoughts on programming 评OO设计 昨天在微博上看到InfoQ提供了一本新书<完美软件开发:方法与逻辑> ...

  3. OO设计原则 -- OO设计的原则及设计过程的全面总结

    这部分增加一点自己的感想,OO设计原则下面讲述的很清晰;看完之后有点感想如果我们在实际开发当中能够把这些原则熟烂于心的话那我们的代码质量和个人能力会有很显著的提神.根据自己的实际经验看很多开发者在开发 ...

  4. 常用的OO设计原则

    常用的OO设计原则: 1 封装变化:找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起. 2 针对接口编程,而不是针对实现编程. 3 多用组合,少用继承. 4 松耦合:为了 ...

  5. mysql优化-数据库设计基本原则

    mysql优化-数据库设计基本原则 一.数据库设计三范式 第一范式:字段具有原子性 原子性是指数据库的所有字段都不可被再次划分,如下表就不满足原子性,起点与终点 字段就可被拆分为起点与终点两个字段. ...

  6. 动态变化的OO设计

    今天看到个题目:对象会动态的变化. 游戏精灵,有人和神仙,但是随着人的不断积分,会升级为神仙:神仙也可能会因为积分的减少而降级为人.这种情况怎么画出个类图来. 这是第一版的设计,正常思维.人和神仙都是 ...

  7. HIS系统患者实体OO设计的一点思考

    软件开发的生命周期中,数据库建模后,在某个数据库系统中形成相对应的表,之后再根据数据库模型设计相关的业务对象及其关系.这其实是进行了两次设计,一次是数据库模型设计,数据库模型设计是根据现实业务提取出来 ...

  8. RESTful API设计基本原则

    REST四个基本原则:1.使用HTTP动词:GET POST PUT DELETE:2.无状态连接,服务器端不应保存过多上下文状态,即每个请求都是独立的:3.为每个资源设置URI:4.通过XML JS ...

  9. OO设计原则

    开闭原则(OCP) 里氏代换原则(LSP) 依赖倒转原则(DIP) 接口隔离原则(ISP) 合成/聚合利用原则(CARP) 迪米特法则(LOD)

随机推荐

  1. jenkins-启动和关闭服务

    笔者没有把Jenkins配置到tomcat中,每次都是用命令行来启动Jenkins.但是遇到一个问题:Jenkins一直是开着的,想关闭也关闭不了.百度了一些资料,均不靠谱(必须吐槽一下百度).于是进 ...

  2. git clone 时显示Filename too long的解决办法

    在git bash中,运行下列命令: git config --global core.longpaths true 就可以解决该问题. --global是该参数的使用范围,如果只想对本版本库设置该参 ...

  3. SpringCloud教程 | 第十二篇: 断路器监控(Hystrix Dashboard)

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://blog.csdn.net/forezp. http://blog.csdn.net/forezp/art ...

  4. 修改maven仓库位置

    在eclipse中安装好maven2的插件后: 第一步: 默认会放在~/.m2/repository目录下 (“~”代表用户的目录,比如windows7下一般都是C:\Users\zz\.m2\rep ...

  5. Java8新特性Optional、接口中的默认方法与静态方法

    Optional Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念 ...

  6. 使用sqlmap执行SQL注入攻击

    sqlmap是开源的SQL注入自动攻击工具,它可以自动的探测SQL注入点并且进一步控制网站的数据库. Kali Linux默认安装了这个工具. 找到潜在的攻击目标 第一步是找到有SQL注入漏洞的网站. ...

  7. 当导用模块与包的import与from的问题(模块与包的调用)

    当在views.py里写impor models会不会报错呢? 1.Python里面的py文件都是每一行的代码. 2.Python解释器去找一个模块的时候,只去sys.path的路径里找 3.djan ...

  8. loader疑惑

    今天写自己的loader管理类时,发现一个问题,如果证明flash是并发加载资源的呢? var loader:Loader=new Loader; loader.contentLoaderInfo.a ...

  9. CF 1088(A , B , C , D)——思路

    http://codeforces.com/contest/1088 A:Ehab and another construction problem 输出 2 和 n(偶数的话)或者 2 和 n-1( ...

  10. css3动画学习笔记

    具体学习地址:http://www.imooc.com/learn/33CSS3中的三种动画:tranform形变动画/transition缓动动画/animation逐帧动画; tranform: ...