《设计模式》六大设计原则篇

一、单一职责原则

       就一个类而言,应该仅有一个引起它变化的原因。如果有多余一个的动机去改变一个类,那么这个类就具有多于一个的职责,需要对这些职责进行分离。

       例如你去中餐厅吃盖浇饭这件事(整个代码放在一个类中的话),如果你忽然想换到小吃街吃盖浇饭,你就需要改变这个类。然后等你到了小吃街,你忽然很想吃麻辣烫,那么你还要再次改变这个类。此时,引起这个类的变化的因素已经有两个了(地点、饭),那么就需要对你的代码进行拆分。分为一个地点类,一个饭类,如此,你想换什么地方,就直接修改地点这个类即可,如果你想换饭食种类,那么修改饭类即可。

二、开放-封闭原则

       是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。该原则有两个特征,一个是对于扩展是开放的(open for extension),另一个是对于更改是封闭的(closed for modification)。该原则可以让我们在设计时面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不断推出新的版本。

       例如你要设计一个简单的计算器,里面包含了加减运算法则,那么你可以对着两个法则进行抽象,得到一个抽象的运算类,然后由两个具体子类(加法类、减法类)来继承该抽象类。如此,当你再次对该计算器的运算法则进行扩充,添加乘除运算法则时,不必再改变全部的代码,而是直接添加两个具体的子类来集成抽象的运算类即可。

       开放-封闭原则是面向对象设计的核心所在。开发人员应该仅对程序中呈现出频繁变化的那些部分进行抽象,以达到面向对象所带来的可维护、可扩展、可复用、灵活性好的特点。

 

三、依赖倒转原则

       A.高层模块不应该依赖底层模块。两个都应该依赖抽象。B.抽象不应该依赖细节,细节应该依赖抽象

       例如你的PC里如果CPU、内存、硬盘都需要依赖具体的主板,主板一坏,所有的部件就都没用了,这显然不合理。反过来,如果内存坏了,也不应该造成其他部件不能用才对。如果不管高层模块还是底层模块,它们都依赖于抽象,具体一点就是接口或抽象类,只要接口是稳定的,那么任何一个的更改都不用担心其他受到影响,这就使得无论高层模块还是底层模块都很容易地被复用。

       依赖倒转其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节变成,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象设计,反之那就是过程化的设计了。

 

四、里式转换原则

       子类型必须能够替换掉它们的父类型。在面向对象设计中,子类拥有父类所有非private的行为和属性。如:鸟是可以飞的,企鹅不会飞,那么企鹅是鸟么?企鹅可以继承鸟这个类么?答案是不能,因为鸟会飞而企鹅不会!

       因为有了里式转换原则,使得继承复用成为了可能,只有当子类可以替换掉父类,软件单位的功能不受印象时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。正是由于子类型的可替换性才使得使用父类型的模块在无需修改的情况下就可以扩展

 

五、迪米特法则

   如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

       经典讲解,观察者模式。如果老板回来了,那么前台会直接告诉小王,然后由小王通知正在打游戏的小李、炒股票的小刘关闭网络,开始工作。同理,当除了打游戏的小李、炒股票的小刘以外,又增加了一个追NBA球赛的小马时,小王需要通知的人就多了一个,进而从前台那里间接知道老板是否回来这一具体通知的人,又多了一个。在这上面,老板是否回来这一通知,和小李、小刘、小马是否关闭网络之间,不是直接关联的,而是层层传达,做出动作的。

 

六、合成/聚合复用

       尽量使用合成/聚合,尽量不要使用类继承。

       在这里需要了解的一点就是UML四大关系中的耦合度的强弱。两个类的耦合度越强,则在发生变动时引起的变动范围越大。其中继承是一种“强耦合”关系,父类变,子类就一定跟着变。而关联关系,则相对松散很多。尽量使用合成/聚合关系,则是在一定程度上降低耦合度的体现。最佳例子体现:桥接模式。


                           <<<从弱到强的耦合关系<<<

                依赖---关联---聚合---组合---继承

猜你喜欢

转载自blog.csdn.net/sevengirl2017/article/details/79437399