面向对象六大原则,一大法则,这是见过最详细的一篇文章,很明白,别被别的破文章迷惑了,说了乱七八糟,而且别的都是一顿乱抄,看估计都没看就搬过去了

这篇文章是搬运过来的,在百度文库里,里面的依赖倒置原则我觉得是说得最通俗易懂的,别的文章,我真是服了,大部分都是抄的
https://wenku.baidu.com/view/7eb6e256a717866fb84ae45c3b3567ec102ddcee.html

单⼀职责,⾥⽒替换,迪⽶特法则,依赖倒转,接⼝隔离,合成/聚合原则,开放-封闭 。

  1. 开闭原则(Open-Closed Principle, OCP)
    定义:软件实体应当对扩展开放,对修改关闭。这句话说得有点专业,更通俗⼀点讲,也就是:软件系统中包含的各种组件,例如模块
    (Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,去扩展新功能。开闭原则中原有“开”,
    是指对于组件功能的扩展是开放的,是允许对其进⾏功能扩展的;开闭原则中“闭”,是指对于代码的修改是封闭的,即不应该修改原有的
    代码。
    问题由来:凡事的产⽣都有缘由。我们来看看,开闭原则的产⽣缘由。在软件的⽣命周期内,因为变化、升级和维护等原因需要对软件原有
    代码进⾏修改时,可能会给旧代码中引⼊错误,也可能会使我们不得不对整个功能进⾏重构,并且需要原有代码经过重新测试。这就对我们
    的整个系统的影响特别⼤,这也充分展现出了系统的耦合性如果太⾼,会⼤⼤的增加后期的扩展,维护。为了解决这个问题,故⼈们总结出
    了开闭原则。解决开闭原则的根本其实还是在解耦合。所以,我们⾯向对象的开发,我们最根本的任务就是解耦合。
    解决⽅法:当软件需要变化时,尽量通过扩展软件实体的⾏为来实现变化,⽽不是通过修改已有的代码来实现变化。
    ⼩结:开闭原则具有理想主义的⾊彩,说的很抽象,它是⾯向对象设计的终极⽬标。其他⼏条原则,则可以看做是开闭原则的实现。我们要
    ⽤抽象构建框架,⽤实现扩展细节。
  2. 单⼀职责原则(Single Responsibility Principle)
    定义:⼀个类,只有⼀个引起它变化的原因。即:应该只有⼀个职责。
    每⼀个职责都是变化的⼀个轴线,如果⼀个类有⼀个以上的职责,这些职责就耦合在了⼀起。这会导致脆弱的设计。当⼀个职责发⽣变化
    时,可能会影响其它的职责。另外,多个职责耦合在⼀起,会影响复⽤性。例如:要实现逻辑和界⾯的分离。需要说明的⼀点是单⼀职责原
    则不只是⾯向对象编程思想所特有的,只要是模块化的程序设计,都需要遵循这⼀重要原则。
    问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发⽣改变⽽需要修改类T时,有可能会导致原本运⾏正常的职
    责P2功能发⽣故障。
    解决⽅法:分别建⽴两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发⽣故障风险;
    同理,当修改T2时,也不会使职责P1发⽣故障风险。
  3. ⾥⽒替换原则(Liskov Substitution Principle)
    定义:⼦类型必须能够替换掉它们的⽗类型。注意这⾥的能够两字。有⼈也戏称⽼⿏的⼉⼦会打洞原则。
    问题由来:有⼀功能P1,由类A完成。现需要将功能P1进⾏扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由
    类A的⼦类B来完成,则⼦类B在完成新功能P2的同时,有可能会导致原有功能P1发⽣故障。
    解决⽅法:类B继承类A时,除添加新的⽅法完成新增功能P2外,尽量不要重写⽗类A的⽅法,也尽量不要重载⽗类A的⽅法
    ⼩结:所有引⽤⽗类的地⽅必须能透明地使⽤其⼦类的对象。⼦类可以扩展⽗类的功能,但不能改变⽗类原有的功能,即:⼦类可以实现⽗
    类的抽象⽅法,⼦类也中可以增加⾃⼰特有的⽅法,但不能覆盖⽗类的⾮抽象⽅法。当⼦类的⽅法重载⽗类的⽅法时,⽅法的前置条件(即
    ⽅法的形参)要⽐⽗类⽅法的输⼊参数更宽松。当⼦类的⽅法实现⽗类的抽象⽅法时,⽅法的后置条件(即⽅法的返回值)要⽐⽗类更严
    格。
  4. 迪⽶特法则(Law Of Demeter)(也是唯一的法则,其他都为原则)
    定义:迪⽶特法则⼜叫最少知道原则,即:⼀个对象应该对其他对象保持最少的了解。如果两个类不必彼此直接通信,那么这两个类就不
    应当发⽣直接的相互作⽤。如果其中⼀个类需要调⽤另⼀个类的某⼀个⽅法的话,可以通过第三者转发这个调⽤。简单定义为只与直接的朋
    友通信。⾸先来解释⼀下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之
    间是朋友关系。耦合的⽅式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、⽅法参数、⽅法返回值中的类为直接的朋友,
    ⽽出现在局部变量中的类则不是直接的朋友。也就是说,陌⽣的类最好不要作为局部变量的形式出现在类的内部。
    问题由来:类与类之间的关系越密切,耦合度越⼤,当⼀个类发⽣改变时,对另⼀个类的影响也越⼤。
    最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是⼀个类对⾃⼰依赖的类知道的越少越好。也就是
    说,对于被依赖的类来说,⽆论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public⽅法,不对外泄漏任何信息。迪
    ⽶特法则还有⼀个更简单的定义:只与直接的朋友通信。
    解决⽅法:尽量降低类与类之间的耦合。 ⾃从我们接触编程开始,就知道了软件编程的总的原则:低耦合,⾼内聚。⽆论是⾯向过程编程
    还是⾯向对象编程,只有使各个模块之间的耦合尽量的低,才能提⾼代码的复⽤率。
    迪⽶特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免
    与⾮直接的类通信,但是要通信,必然会通过⼀个“中介”来发⽣联系。故过分的使⽤迪⽶特原则,会产⽣⼤量这样的中介和传递类,导致
    系统复杂度变⼤。所以在采⽤迪⽶特法则时要反复权衡,既做到结构清晰,⼜要⾼内聚低耦合。
  5. 依赖倒置原则(Dependence Inversion Principle)
    定义:⾼层模块不应该依赖低层模块,⼆者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。中⼼思想是⾯向接⼝编程
    问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A⼀般是⾼层模块,负责复
    杂的业务逻辑;类B和类C是低层模块,负责基本的原⼦操作;假如修改类A,会给程序带来不必要的风险。
    解决⽅法:将类A修改为依赖接⼝I,类B和类C各⾃实现接⼝I,类A通过接⼝I间接与类B或者类C发⽣联系,则会⼤⼤降低修改类A的⼏率。
    在实际编程中,我们⼀般需要做到如下3点:
    1). 低层模块尽量都要有抽象类或接⼝,或者两者都有。
    2). 变量的声明类型尽量是抽象类或接⼝。
    3). 使⽤继承时遵循⾥⽒替换原则。
    采⽤依赖倒置原则尤其给多⼈合作开发带来了极⼤的便利,参与协作开发的⼈越多、项⽬越庞⼤,采⽤依赖导致原则的意义就越重⼤。
    ⼩结:依赖倒置原则就是要我们⾯向接⼝编程,理解了⾯向接⼝编程,也就理解了依赖倒置。
  6. 接⼝隔离原则(Interface Segregation Principle)
    定义:客户端不应该依赖它不需要的接⼝;⼀个类对另⼀个类的依赖应该建⽴在最⼩的接⼝上。
    问题由来:类A通过接⼝I依赖类B,类C通过接⼝I依赖类D,如果接⼝I对于类A和类B来说不是最⼩接⼝,则类B和类D必须去实现他们不需
    要的⽅法
    解决⽅法:1、 使⽤委托分离接⼝。2、 使⽤多重继承分离接⼝。3.将臃肿的接⼝I拆分为独⽴的⼏个接⼝,类A和类C分别与他们需要的接
    ⼝建⽴依赖关系。也就是采⽤接⼝隔离原则。
    举例说明:
    下⾯我们来看张图,⼀切就⼀⽬了然了。
    这个图的意思是:类A依赖接⼝I中的⽅法1、⽅法2、⽅法3,类B是对类A依赖的实现。类C依赖接⼝I中的⽅法1、⽅法4、⽅法5,类D是
    对类C依赖的实现。对于类B和类D来说,虽然他们都存在着⽤不到的⽅法(也就是图中红⾊字体标记的⽅法),但由于实现了接⼝I,所以
    也必须要实现这些⽤不到的⽅法
    修改后:
    如果接⼝过于臃肿,只要接⼝中出现的⽅法,不管对依赖于它的类有没有⽤处,实现类中都必须去实现这些⽅法,这显然不是好的设计。如
    果将这个设计修改为符合接⼝隔离原则,就必须对接⼝I进⾏拆分。在这⾥我们将原有的接⼝I拆分为三个接⼝
    ⼩结:我们在代码编写过程中,运⽤接⼝隔离原则,⼀定要适度,接⼝设计的过⼤或过⼩都不好。对接⼝进⾏细化可以提⾼程序设计灵活性
    是不挣的事实,但是如果过⼩,则会造成接⼝数量过多,使设计复杂化。所以⼀定要适度。设计接⼝的时候,只有多花些时间去思考和筹
    划,就能准确地实践这⼀原则。
  7. 合成/聚合原则(Composite/Aggregate Reuse Principle,CARP)
    定义:也有⼈叫做合成复⽤原则,及尽量使⽤合成/聚合,尽量不要使⽤类继承。换句话说,就是能⽤合成/聚合的地⽅,绝不⽤继承。
    为什么要尽量使⽤合成/聚合⽽不使⽤类继承?
    1. 对象的继承关系在编译时就定义好了,所以⽆法在运⾏时改变从⽗类继承的⼦类的实现
    2. ⼦类的实现和它的⽗类有⾮常紧密的依赖关系,以⾄于⽗类实现中的任何变化必然会导致⼦类发⽣变化
    3. 当你复⽤⼦类的时候,如果继承下来的实现不适合解决新的问题,则⽗类必须重写或者被其它更适合的类所替换,这种依赖关系限制了灵
    活性,并最终限制了复⽤性。
    4. 为什么聚合就比继承好?在聚合中,一个类整体上是不持有其父类的属性和方法的,我们只是通过其父对象的引用去调用父类的某个方法和属性(聚合的实现就是让父类对象成为子类的属性字段),就算父类将功能和属性进行了扩展了,不符合了当前子类使用,但是子类可以不用啊,因为子类是通过父类对象引用调用父类某个属性方法的,遇到不实用的不进行调用就可以了.而如果使用继承,扩展而来的属性和方法子类是一定也会拥有的.
    总结:这些原则在设计模式中体现的淋淋尽致,设计模式就是实现了这些原则,从⽽达到了代码复⽤、增强了系统的扩展性。所以设计模式
    被很多⼈奉为经典。我们可以通过好好的研究设计模式,来慢慢的体会这些设计原则。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值