设计原则

面向对象软件设计原则是一组指导面向对象软件设计的经验法则,它们有助于开发人员编写更易于维护和扩展的代码。

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

定义:
一个类应该只有一个引起它变化的原因。

说明:
SRP指导我们如何将类的职责分解,使得每个类都只负责一项职责。
每个类都应该具有清晰、明确的职责,不应该承担过多的职责。如果一个类承担了过多的职责,那么它就会变得复杂、难以维护,而且一旦发生变化,可能会影响到其他的功能模块。
遵守SRP原则可以使得程序更加灵活、易于扩展和维护,同时也可以提高代码的复用性和可读性。在软件设计中,SRP原则应该被视为一个基本的设计原则,尽可能地遵守。

要点:

  • 一个类只负责一项职责,即只有一个原因引起它的变化。
  • 类中的方法和属性都应该围绕着该职责而设计,不应该包含不相关的行为。
  • 如果需要扩展功能,应该向类中添加新的职责,而不是修改原有的职责。

优点:

  • 降低类的复杂度,使其更容易理解和维护。
  • 提高代码的可读性和可维护性,因为每个类都只有一个责任,代码结构更加清晰。
  • 降低了代码之间的耦合性,因为每个类都专注于一个责任,不会出现一个类的修改导致其他类的变化的情况。
  • 提高了代码的可测试性,因为每个类都可以更容易地进行单元测试。

缺点:

  • 可能会导致类的数量增加,增加代码的复杂度和管理难度。
  • 可能会导致重复代码的出现,因为不同的类可能需要相同的代码来完成其责任。
  • 需要更多的设计和分析工作来确定每个类的职责,增加了设计和开发的成本。

开放封闭原则(The Open Close Principle)OCP

定义:
软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。

说明:
OCP指导我们如何设计一个稳定、灵活的软件系统,使得系统可以方便地扩展新功能,同时又不影响原有的功能。
这意味着当需要增加新的功能时,应该通过添加新的代码来实现,而不是通过修改原有的代码来实现。
遵守OCP原则可以使得系统更加稳定、灵活、易于扩展和维护。在软件设计中,OCP原则应该被视为一个重要的设计原则,尽可能地遵守。

要点:

  • 系统中的每个模块应该有清晰、明确的职责,不应该包含不相关的行为。
  • 当需要增加新的功能时,应该向系统中添加新的模块或类,而不是修改原有的模块或类。
  • 模块或类之间的接口应该是稳定的,不应该随意更改,以保证原有的功能不受影响。

优点:

  • OCP遵循了面向对象设计的核心原则,通过抽象和多态来实现对软件系统的可扩展性和灵活性。
  • 可以降低软件维护的成本和风险,因为当需要添加新的功能时,只需要扩展现有的代码而不需要修改现有的代码,从而避免了不必要的风险和代价。

缺点:

  • 实现OCP需要进行适当的抽象和设计,这可能需要更多的时间和精力。
  • 遵循OCP原则可能会导致代码过度抽象和过度设计,从而使代码变得复杂和难以理解。
  • 如果不合理地应用OCP,可能会增加系统的复杂性,导致不必要的开销和维护困难。

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

定义:
子类必须能替换掉他们的基本类型。

说明:
LSP指导着如何定义子类型,以确保程序中使用父类型的地方都可以使用子类型,而不会产生错误或异常。
简单来说,如果对于一个类型T的对象o1,都有类型S的对象o2,使得程序在使用o2的任意地方都可以使用o1,而不会影响程序的正确性,则类型S是类型T的子类型。LSP原则的核心在于“行为的保持”,即子类型必须保证父类型的行为不会被破坏或改变。
遵守LSP原则可以避免程序中出现难以预料的错误或异常,提高程序的稳定性和可靠性。因此,在软件设计中,LSP原则应该被视为一个重要的设计原则,尽可能地遵守。

要点:

  • 子类型必须能够完全替换掉其父类型,也就是说子类型不能有比父类型更严格的限制条件。
  • 子类型必须保持父类型的行为,也就是说子类型不能破坏父类型的约定或契约。
  • 子类型可以增加新的行为,但不能覆盖或修改父类型已有的行为。

优点:

  • 提高代码的可维护性:符合LSP的程序架构更加稳定和可靠,使得程序的维护更加容易。
  • 降低耦合度:LSP保证了子类的可替换性,使得程序的耦合度更低。
  • 有利于代码重用:子类能够替换父类,使得代码的重用更加容易。

缺点:

  • 实现成本较高:要满足LSP原则需要对程序的设计进行深入的考虑,实现成本相对较高。
  • 程序执行效率下降:有时候为了满足LSP原则而需要增加额外的逻辑,会导致程序执行效率下降。

依赖倒置原则(The Dependency Inversion Principle)DIP

定义:
抽象不应该依赖于细节。细节应该依赖于抽象。

说明:
DIP指导着如何设计代码,使得代码更加灵活、易于扩展和维护。
设计系统时,应该使用抽象类或接口来描述系统中的对象,而不是使用具体的实现类。
遵守DIP原则可以使得代码更加灵活、易于扩展和维护。在软件设计中,DIP原则应该被视为一个重要的设计原则,尽可能地遵守。

要点:

  • 高层模块不应该直接依赖于底层模块,它们应该通过抽象来进行通信。
  • 抽象不应该依赖于细节,细节应该依赖于抽象。
  • 底层模块应该通过实现抽象来提供服务,而不是通过被高层模块直接调用。

优点:

  • 可扩展性:通过依赖抽象接口而不是具体实现来编写代码,使得代码更加灵活和可扩展,便于将来对系统进行更改和升级。
  • 松耦合:使用依赖倒置原则可以将组件之间的依赖关系转移到抽象层面,从而降低了组件之间的耦合度,提高了代码的复用性和可维护性。
  • 可测试性:通过依赖抽象接口,我们可以很容易地进行单元测试,而不需要依赖具体的实现细节,从而提高了代码的可测试性和可靠性。

缺点:

  • 抽象的复杂性:使用依赖倒置原则需要设计和定义接口和抽象类,这会增加代码的复杂性和维护成本。
  • 代码量的增加:使用依赖倒置原则可能需要编写更多的代码,包括接口、抽象类和实现类,从而增加了代码的复杂度和开发成本。
  • 性能问题:在运行时,由于需要动态绑定抽象接口和具体实现类,因此会产生额外的开销和性能问题。

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

定义:
不应该强迫客户依赖于他们不用的方法。接口属于客户,不属于他所在的类层次结构。

说明:
ISP指导着如何设计接口,使得接口更加简洁、易于理解和使用。
在设计接口时,应该尽量避免出现冗余或不必要的接口,以减少类之间的依赖关系。
遵守ISP原则可以使得接口更加简洁、易于理解和使用,同时也可以降低类之间的耦合度,提高系统的灵活性和可扩展性。在软件设计中,ISP原则应该被视为一个重要的设计原则,尽可能地遵守。

要点:

  • 接口应该是稳定的,不应该频繁变更。
  • 接口应该是简单、易于理解的,不应该包含过多的方法。
  • 接口应该是高内聚、低耦合的,不应该依赖于其它的接口。

优点:

  • 避免了“胖接口”问题:接口隔离原则要求接口应该细化,每个接口只包含一个方法或行为,这样可以避免接口变得臃肿,让接口更加精简、易于理解和维护。
  • 降低了类之间的耦合度:接口隔离原则通过将大的接口拆分成小的接口,减少了类与接口之间的依赖关系,降低了类之间的耦合度,提高了系统的可维护性和可扩展性。
  • 提高了系统的灵活性:由于接口隔离原则将大的接口拆分成小的接口,因此系统可以根据需求灵活地组合接口,构建出符合实际需求的系统。

缺点:

  • 接口数量增加:由于接口隔离原则要求将大的接口拆分成小的接口,因此会导致接口的数量增加,增加了代码的复杂性和维护成本。
  • 接口继承关系复杂:在接口隔离原则中,一个类可能需要实现多个接口,这就会导致接口之间的继承关系变得复杂,增加了代码的理解难度。
  • 代码可读性降低:由于接口隔离原则要求将大的接口拆分成小的接口,因此代码会变得更加分散,这就会导致代码可读性降低,增加了代码的理解难度。

最少知识原则(The Least Knowledge Principle)LKP 迪米特法则(Law of Demeter,简称LoD)

定义:
一个对象应该尽可能少地了解其他对象

说明:
LKP原则指导着我们要尽量减少对象之间的相互依赖和交互,以降低系统的耦合度,提高系统的灵活性和可维护性。
在设计对象时,应限制对象之间的交互,使得一个对象只与其直接关联的对象进行通信,而不涉及其他对象的内部细节。
遵循LKP原则,可以降低对象之间的耦合度,提高系统的灵活性和可维护性,同时也能提高系统的可测试性和可扩展性。

要点:

  • 对象之间尽可能少的通信:对象之间只通过必要的接口进行通信,而不暴露不必要的细节。
  • 通过封装来降低耦合性:对象之间通过接口和实现进行通信,而不直接依赖于其他对象的具体实现。
  • 避免在对象外部访问对象内部的状态:对象之间只通过接口访问彼此,而不直接访问内部状态。
  • 使用中介对象降低耦合性:通过引入中介对象,将对象之间的依赖转移给中介对象,降低对象之间的耦合性。

优点:

  • 降低系统的耦合度,提高代码的可维护性和可扩展性。
  • 提高代码的复用性,减少重复开发的工作量。
  • 改善系统的稳定性,提高系统的健壮性。

缺点:

  • 可能会导致系统中的代码和类数量增加,增加了系统的复杂性。
  • 严格遵守 LKP 原则可能会增加开发人员的编码难度和学习成本。

综述:

我们对待设计原则的态度应该是积极的。设计原则是一种指导我们如何设计软件的方法论,通过遵循设计原则,可以使我们的软件更易于维护、扩展和重用,同时也能够提高软件的可靠性、可读性和可测试性。
但在实际项目开发中,过度追求设计原则也有可能会导致过度设计,浪费时间和资源。因此,我们在应用设计原则时应该在实际情况和需求之间寻找平衡点。在实践中,需要根据项目规模、复杂度、团队规模、人员经验、项目需求和可扩展性等因素来决定使用哪些设计原则,以及如何灵活应用这些原则。在设计软件时,应该注重代码质量、可维护性和可扩展性,但不应该让设计原则成为开发的障碍或增加不必要的复杂性。

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

推荐阅读更多精彩内容