设计模式---面向对象设计原则

一:为何提倡面向对象设计?

变化时复用的天敌!
面向对象设计的最大优点在于:抵御变化

二:从新认识面向对象

(一)理解隔离变化:

从宏观层面来看,面向对象的构建方式更能适应软件的变化,能将变化所带来的影响减为最小(隔离不是绝对的)

(二)各司其职

从微观层面来看,面向对象的方式更强调各个类的”责任“。
因为需求变化致使的新增类型不该该影响原来类型的实现。---是所谓的各负其责

(三)对象是什么:

从语言层面来看,对象封装了代码和数据。
从规格层面讲,对象是一系列可被使用的公共接口。
从概念层面讲,对象是某种拥有责任的抽象。

三:设计模式基本原则

最终目的:高内聚,低耦合

(一)依赖倒置原则(DIP)

高层模块(稳定)不该该依赖于低层模块(变化),两者都应该依赖于抽象(稳定)。 抽象(稳定)不该该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。

传统过程设计:倾向因而高层次的模块依赖于低层次的模块,抽象层依赖于具体层(高度依赖)

依赖倒置实现解耦合,将上面的依赖关系倒转过来

(二)开放封闭原则(OCP)

对扩展开放,对更改封闭 类模块应该是可拓展的,可是不可修改
类的改动是经过增长代码进行的,而不是修改源代码
父类指针指向子类对象,使用多态等来扩展功能,某一个错误不会引发全局错误
软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

原来的结构设计:将全部功能放在某一个大类中,致使业务扩展性差,修改都是在一个类模块中(易出现关联错误)

符合开发封闭原则的设计:

扩展方便

(三)单一职责原则(SRP)

类的职责要单一,对外只提供一种功能,而引发类变化的缘由只有一个
功能分开,各为一类。缺点:致使类太多
一个类应该仅有一个引发它变化的缘由。
变化的方向隐含着类的责任
若是一个类承担的职责过多,就等于把这些职责耦合在一块儿了。
一个职责的变化可能会削弱或者抑制这个类完成其余职责的能力。
这种耦合会致使脆弱的设计,当发生变化时,设计会遭受到意想不到的破坏。
而若是想要避免这种现象的发生,就要尽量的遵照单一职责原则。
此原则的核心就是解耦和加强内聚性

问题由来

T负责两个不一样的职责:职责P1,职责P2。当因为职责P1需求发生改变而须要修改类T时,有可能会致使本来运行正常的职责P2功能发生故障。也就是说职责P1和P2被耦合在了一块儿。

解决方法

职责扩散:由于某种缘由,某一职责被分化为颗粒度更细的多个职责了

遵照单一职责原则,将不一样的职责封装到不一样的类或模块中。

优势

1)下降类的复杂度;
(2)提升类的可读性,提升系统的可维护性;
(3)下降变动引发的风险(下降对其余功能的影响)

(四)里氏替换原则(LSP)(多态)

设计原则之里氏替换原则

任何抽象类出现的地方,均可以用他的实现类进行替换(多态)。实际就是虚拟机制,语言级别实现面向对象功能
子类必须可以替换它们的基类(IS-A)。
继承表达类型抽象。

原则:子类能够扩展父类的功能,但不能改变父类原有的功能。

父类能出现的地方均可以用子类来代替,并且换成子类也不会出现任何错误或异常,而使用者也无需知道是父类仍是子类,
但反过来则不成立
     1. 子类必须彻底实现父类的抽象方法,但不能覆盖父类的非抽象方法;
     2. 子类中能够增长本身特有的方法;
     3. 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数要更宽松;
     4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

优势:

     1. 提升代码的重用性,子类拥有父类的方法和属性;
     2. 提升代码的可扩展性,子类可形似于父类,但异于父类,保留自个人特性;

缺点:

     1. 继承是侵入性的,只要继承就必须拥有父类的全部方法和属性,在必定程度上约束了子类,下降了代码的灵活性;
     2. 增长了耦合,当父类的常量、变量或者方法被修改了,须要考虑子类的修改,因此一旦父类有了变更,极可能会形成
        很是糟糕的结果,要重构大量的代码。

(五)接口隔离原则(ISP)

接口隔离原则

不该该强迫客户程序依赖它们不用的方法。 接口应该小而完备。
一个接口应该只提供一种对外功能,不该该把全部操做都封装到一个接口中去

接口隔离原则和单一职责原则的区别

接口隔离原则与单一职责原则的审视角度不相同。单一职责原则要求是类和接口的职责单一,注重的是职责,这是业务逻辑上的划分。
接口隔离原则要求接口的方法尽可能少。

接口要尽可能小

这是接口隔离原则的核心定义,接口要尽可能小,不要出现臃肿的接口,可是小也是有限度的,不能违背单一职责原则。

接口要高内聚

高内聚就是提升接口,类,模块的处理能力,减小对外的交互。具体到接口隔离原则就是要求在接口中尽可能减小公布public方法,接口是对外的承诺,承诺越少对系统开发越有利,变动的风险就越少。

原则

一个接口只服务于一个子模块或业务逻辑
经过业务逻辑压缩接口中的public方法,接口要不断的精简,以达到接口不断完善
已经被污染的接口,尽可能去修改,若变动的风险较大,则采用适配器进行转化处理

(六)优先使用对象组合,而不是类继承

理解组合对象与类继承

类继承一般为“白箱复用”,对象组合一般为"黑箱复用"继承在某种程度上破坏了封装性,子类父类耦合度高。
而对象组合则只要求被组合的对象具备良好定义的接口,耦合度低。
若是使用了继承,会致使父类的任何变换均可能影响到子类的行为。
若是使用对象组合,就下降了这种依赖关系
对象组合要求被组合的对象具备良好定义的接口。

(七)封装变化点

使用封装来建立对象之间的分界层,让设计者能够在分界层的一侧进行修改,而不会对另外一侧产生不良的影响,从而实现层次间的松耦合。
例如:facade模式(外观模式)

(八)迪米特法则:针对接口编程,而不是针对实现编程

不将变量类型声明为某个特定的具体类,而是声明为某个接口。
客户程序无需获知对象的具体类型,只须要知道对象所具备的接口。
减小系统中各部分的依赖关系,从而实现”高内聚、松耦合“的类型设计方案。
一个对象应该对其余对象尽量少的了解,从而下降各个对象之间的耦合,提升系统的可维护性。
例如在一个程序中,各个模块之间相互调用时,一般会提供一个统一的接口来实现,这样其余模块不须要了解另外一个模块的内部实现细节,
这样当一个模块内部的实现发生改变时,不会影响其余模块的使用(黑盒原理)

四:面向接口设计

产业强盛的标志就是接口便准化。

五:将设计原则提高为设计经验

设计习语 Design Idioms
Design Idioms描述与特定编程语言相关的低层模式,技巧,惯用法。
设计模式 Design Patterns
Design Patterns主要描述的是”类与相互通讯的对象之间的组织关系”,包括它们的角色、职责、协做方式等方面。
架构模式 Architectural Patterns
Architectural Patterns描述系统中与基本结构组织关系密切的高层模式,包括子系统划分,职责,以及如何组织它们之间关系的规则。
相关文章
相关标签/搜索