面向对象的7大设计原则

设计原则

在面向对象的软件系统设计中,可维护性,可复用性是衡量一个软件系统是否健壮的重要指标。而可维护性和可复用性是可以遵从基本的准则来得以实现。而这些准则就是面向对象设计的基本原则。面向对象的设计原则一共有7种,这些原则都是以前的软件工程师在实践中总结的基本原则,经得起项目的考验,时间的检验,这些原则也是设计模式的基础。每种原则都蕴含面向对象的思想,从而从不同的纬度去提高软件结构的设计水平。

1:单一指责原则(SRP:Simple Responsibility Principle)

一个类只负责一个功能领域的相应职责。
在使用该原则来进行软件设计的时候一定要注意,不要让类的承担过多的职能,承担的职能越多,功能模块间的耦合性越强,维护成本也就越高,而且这个类被复用的可能性就越小。我们要将不同类型的职责拆分开来,分别封装到不同的类中,来实现职责的单一化。

2:开闭原则(OCP:Open-Close Principle)

软件实体对扩展开放,对修改关闭。软件实体应当在不修改源代码的情况下对功能进行扩展。
在软件开发中,我们不得不面临一个问题,那就是软件的需求会随着时间的推移而不断的变化,这时候一个可扩展性强,灵活度高的软件系统就显的十分必要了。要满足这样要求的系统,必须要具备一些基本特定。如果一个软件系统符合开闭原则,那么这个系统就可以很好的满足扩展性,灵活性的需求。
而在实现开闭原则的过程中。抽象化的设计是重中之重,抽象化才是开闭原则的关键,在Java中我们可以利用接口或抽象类来构建一个抽象层,而将具体的实现行为移至实现层完成。当需要修改系统的行为时,我们不需要修改抽象层,只需要新增新的具体类来实现新的业务逻辑就可以了。这样我们就可以在不修改源代码的基础上实现新的功能,满足开闭原则的要求。

3:里氏代换原则(LSP:Liskov Substitution Principle)

所有引用基类对象的地方能够透明地使用其子类的对象。
如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。
换言之,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
比如,假设有两个类,一个是Base类,另一个是Child类,并且Child类是Base的子类。那么一个方法如果可以接受一个基类对象b的话:method1(Base b)那么它必然可以接受一个子类的对象method1(Child c).

注意事项

  • 为了保证软件系统的扩展性,子类要重写父类中所有的方法。若在子类中存在父类中没有的特有方法,那么通过父类则无法调用该方法。
  • 在运用里氏代换原则时候,父类尽量设计成接口或者抽象类,子类继承父类或者父接口,实现父类中声明的方法,在运行时,子类实例替代父类实例。这样就可以很方便的扩展系统的功能,
  • Java语言中,在编译阶段,Java编译器会检查一个程序是否符合里氏代换原则,这是一个与实现无关的、纯语法意义上的检查,但Java编译器的检查是有局限的。

4:依赖倒转原则(DIP:Dependence Inversion Principle)

抽象不应该依赖于细节,细节应该依赖于抽象。换句话说,要针对接口编程,而不是针对实现编程。
根据依赖倒置原则,我们应当尽量使用抽象类或接口来定义成员变量,参数类型,返回值类型,不要使用具体的实现类来做这些事情,
为了保证依赖倒置原则的良好应用,具体类应该只实现抽象层的方法,不要给出多余的方法,抽象类无法调用具体类中特有的方法。
在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。

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

使用多个专门的接口,而不使用单一的总接口。客户端不应该依赖那些不需要的接口。每一种接口应该承担相对独立的功能,不该干的不要干,自己该干的就要干好。
其中的接口有两层含义

  • 某个类型中所有的方法,是逻辑上的抽象。
    当把“接口”理解成一个类型所提供的所有方法特征的集合的时候,这就是一种逻辑上的概念,接口的划分将直接带来类型的划分。可以把接口理解成角色,一个接口只能代表一个角色,每个角色都有它特定的一个接口,此时,这个原则可以叫做“角色隔离原则”。
  • 具体指代某个编程编程语言,“接口”的定义。
    如果把“接口”理解成狭义的特定语言的接口,那么ISP表达的意思是指接口仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。在面向对象编程语言中,实现一个接口就需要实现该接口中定义的所有方法,因此大的总接口使用起来不一定很方便,为了使接口的职责单一,需要将大接口中的方法根据其职责不同分别放在不同的小接口中,以确保每个接口使用起来都较为方便,并都承担某一单一角色。接口应该尽量细化,同时接口中的方法应该尽量少,每个接口中只包含一个客户端(如子模块或业务逻辑类)所需的方法即可,这种机制也称为“定制服务”,即为不同的客户端提供宽窄不同的接口。

在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

6:合成复用原则(CRP:Composite Reuse Principle)

尽量使用对象组合,而不是继承来达到复用的目的。
一个对象通过关联关系来引入其他已有的对象,通过委派调用已有对象中的方法,来实现复用功能的目的。
通常来说,如果两个类之间是“Has-A”的关系应使用组合或聚合,如果是“Is-A”关系可使用继承。"Is-A"是严格的分类学意义上的定义,意思是一个类是另一个类的"一种";而"Has-A"则不同,它表示某一个角色具有某一项责任。

7:迪米特法则(LoD:Law of Demeter)

一个软件实体应当尽可能少地与其他实体发生相互作用。
迪米特法则要求,当系统中的一个模块发生变更时,应该尽可能少的影响其他模块,那样系统的扩展会比较容易。迪米特原则可以降低系统的耦合程度,使类与类之间保持一种松耦合的关系。
迪米特原则要求我们“不要跟陌生人交谈,只跟熟人打交道”,以下条件就是我们需要打交道的熟人。

  • 当前对象this。
  • 对象中方法的形式参数。
  • 对象中映入的成员对象。
  • 如果成员对象是集合,那么集合中的元素也是我们的熟人。
  • 当前对象中创建的其他对象。

迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度。
在将迪米特法则运用到系统设计中时,要注意下面的几点:在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;在类的设计上,只要有可能,一个类型应当设计成不变类;在对其他类的引用上,一个对象对其他对象的引用应当降到最低。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容