六大设计原则

六大设计原则

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

原理:如果一个类担任的职责过多的话,这些职责就会耦合在一起,高耦合会导致脆弱的编程设计,发生变化时,这种设计就会遭到意想不到的破坏,所以要避免这种高耦合就需要遵守单一职责原则,单一职责的核心就是解耦和增加内聚性。

单一职责原则又称单一功能原则,There should never be more than one reason for a class change,表示没有多与一个原因来改变这个类,正常理解是:一个类只有一个职责,不同的类具有不同的职责,大家各施其责。发生场景:A负责两个不同的职责吧:职责1和职责2.当由于职责1需求时要改变改变A类,有可能会导致原本运行正常的职责2发生故障,也就是说职责1和职责2耦合在一起。原因:任何程序员都清楚程序设计时是低耦合和高内聚的,但是很多的耦合是常常无意间发生的,因为职责的扩散导致某一职责的细粒度更细了。解决的方法是遵守单一职责的原则,让一个类负责一个职责,将不同的职责封装在不同的类中或模块中。

2、开放封闭原则(Open Closed Principle -OCP)

核心思想:软件的实体应该是可扩展的,而不可以修改的。也就是说对扩展是开放的,而对修改是封闭的,

开放封闭原则的主要体现的方面:对扩展是开放的,因为新需求的产生或者变化,需要对现有的代码进行扩展来适应新的需求。对修改时封闭的,意味着某类一旦设计了其职责,就可以独自完成自己的职责,而不能对类进行修改。

实施开放封闭的原则的基本思路是:让类依赖与固定的抽象(现在很多讨论建议将interface替代abstract类,两者在理论上差不多,但是实际应用中不同,抽象类一般是公共的父类为子类提供基础,不但可以扩展方法行为还可以扩展到属性上,而interface只能扩展到方法上,使其子类可以通过自有的填补或者扩展接口所定义的方法,比如适配器就是很好的应用),所以对修改就是封闭的;而通过面向对象的继承和多态,可以实现对抽象体的继承,通过复写其方法来改变固有行为,实现新的扩展方法,所以对扩展就是开放的,

Software entities like classes,modules and functions should be open for extension but closed for modifications,软件实体 ,比如类、模块和函数应该对扩展是开放的但是对修改时关闭的。简而言之就是你可以去扩展类,但是不可以去修改类,应用:当软件需求有变动时,需要修改代码了,你应该尽量用继承和组合的方式来扩展类的功能,而不能直接修改类的代码,当然任何事情都不是必然的,如果修改了对整体架构不产生任何影响,那么也不需要搞得很复杂应该适当的变通下。

3、里氏替换原则(Liskov Substitution  Principle -LSP)

我们知道OCP作为OO的高层原则,主张使用抽象(abstraction)和多态(Polymorphism),抽象是语言提供的功能,多态是继承语言的实现,所以里氏替换原则说,任何的基类可以出现的地方,子类一定也可以出现,LSP是继承复用的基石,只有当衍生类替换掉基类,软件的功能不受影响,基类才算被真正的被复用,而衍生类也可以在基类的基础上增加新的行为。

一个对象是一组状态和一系列的行为组成的复合体,状态是对象的内在特性,行为是对象的外在特性,LSP就是说在同一个继承体系中的对象应该有的共同的行为特征。其中OO的继承与日常生活中的继承本质是有区别的,比如生物学上说鸵鸟是鸟,但是某个类中定义了鸟是会飞的,但是鸵鸟不会呀!,符合日常逻辑,但是违反了LSP,所以说这个“鸵鸟”只是一个类或者一个抽象,注意与实际逻辑区分。LSP只是提出了有这个问题而没有提出解决方案,但是后来一位工程师B.Meyer提出了Design by Contract(契约式设计)理论,来确保对象行为和状态的方法,它的概念是:Pre-condition(前置条件),传入参数前应该校验传入参数的正确性,Post-condition(后置条件),一旦通过前置条件,方法必须执行,执行的结果必须符合契约,invariant(不变式),对象本身有一套对自身的状态进行校验的检查条件,以确保该对象的本质不发生改变,当然这是对单个对象的约束条件,为满足LSP,子类中的方法的前置条件必须和父类中被覆盖的方法的前置条件相同或者宽松点,但是子类的方法的后置条件必须比父类中被覆盖的方法的后置条件相同或严格。也就是我们常说的,子类的修饰符(可见性)必须等于或者大于超类的方法的可见性,子类的方法所抛出的异常只能是超类方法中抛出异常的子类。

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. 使用基类的指针或者引用函数,必须在不知情的情况下,才能使用派生类的对象。也就是说父类能够替换子类,但是子类不能够一定替换父类,在代码中可以将父类全部替换成子类,但是不能将子类全部替换成父类。---》这也就是有点像Java中的上溯造型和下溯造型也有叫“向上转型”“向下转型”这是Java多态(Polymorphism)的基石(讲一个对象的引用看做其父类对象的引用叫上溯造型,或者叫向上转型,相反..),

所以在继承的时候,务必重写(Override)父类中所有的方法,但是要注意父类的protected方法(它往往让你重写),子类尽量不要使用public暴露自己的方法供外界调用。

4、最少 知识原则(Lest Knowledge Principle -LKP)

该原则也叫迪米特法则,通俗点说就是一个类对自己依赖的类知道的越少越好,也就是说,无论逻辑多么复杂,都尽量将逻辑疯转在类的内部,对外除了提供的public方法,不对外泄漏任何的方法信息,该原则还有一个更为简单的定义:只与直接的朋友通信,这句话也就说只要出现耦合关系我们就说两个对象是朋友关系,我们称成员变量、方法参数、方法返回值的类为直接朋友,而出现在局部变量中的不是直接朋友,所以陌生的;类最好不要最为局部变量的形式出现在类的内部,

Only talk to you immediate friends 只与你最直接的朋友交流。尽量减少对象之间的交互,从而减少类之间的耦合,好的设计是:低耦合,高内聚。应用:在做设计的时候,尽量不要让一个类依赖与太多的其他类,需要尽量减少依赖关系,

5、接口隔离原则(interface Segregation Principle -ISP)

The dependency of one class to another one should depend on the smallest possible interface 一个类与另一个类之间的依赖性,应该依赖于尽可能小的接口,也就说不要对外暴露没有实际意义的接口,接口是给别人用的,那就别去为难别人了,尽可能保证接口的实用性,应用:当需要对外暴露接口时,我们应该考虑是否有必要对外提供,一旦提供就意味需要多做一些事情,何苦为难自己呢。

6、依赖导致原则(Dependence inversion Principle -DIP)

高层次的模块不应该依赖低层次的模块,他们都需要依赖抽象,抽象不应该依赖具体实现,具体实现应该依赖于抽象,降低客户与实现模块间的耦合,

该原则也就是说我们应该面向接口编程,不应该面向实现类编程,面向实现类编程,相当于就是就事论事了,那是正向依赖,而面向接口编程,相当于通过事物来看本质,那是反向依赖(依赖倒置)也就是我们程序猿应该具有的思维。

 

 

转载于:https://my.oschina.net/u/3488468/blog/1422842

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值