面向对象设计原则

一,导学:

面向对象软件系统设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件的系统可维护性和可复用性是面向对象设计的需要解决的核心问题之一。

二,知识要点

单一职责原则
开闭原则
里氏替换原则
依赖倒转原则
接口隔离原则
合成复用原则
迪米特法则

三,面向对象设计原则概述

面向对象设计原则是学习设计模式的基础,每一个设计模式都符合一个或者多个面向对象设计原则,面向对象设计原则是用于评价一个设计模式的使用效果的重要指标之一。

3.1:单一职责原则

单一职责原则是最简单的面向对象的设计原则,用于控制类的粒度大小。单一原则的另一种定义是:就一个类而言,应该仅有一个引起它变化的原因。在软件系统中,一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小而且一个类承担的职责过多,就相当于将这些职责 耦合在一起,当其中的一个职责变化时,可能影响到其他职责的运行。因此,要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变可以将它们封装在同一个类中。

单一原则是实现高内聚、低耦合的指导方针。是最简单最难运用的原则,需要设计人员发现不同职责并将其分离。而发现类的多重职责需要设计人员具有较强的 分析 设计能力和相关实践经验。

3.2:开闭原则

开闭原则是面向对象的可复用设计的第一块基石,是最重要的面向对象的设计原则:开闭原则软件实体应该对扩展开放,对修改封闭。

在定义中软件实体可以是一个软件模块,一个由多个类组成的局部结构或一个独立的类。开闭原则是指软件实体应尽量不修改原有代码的情况下进行扩展。任何软件都需要面临一个重要的问题,即它们的需求会对时间的推移而发生变化。当软件需要面对新的需求时,应该尽量保证系统设计框架的稳定性。

为了满足开闭原则,需要对系统进行抽象化设计,抽象化设计时开闭原则的关键。可以为系统定义一个相对稳定的抽象层,而将不同实现的行为移至具体实现层中完成。在很多的面向对象的语言中都提供了接口,抽象类等机制,可以通过他们定义系统的抽象层,再通过具体类来进行扩展。如果需要修改系统的行为无需抽象层进行任何的修改,只需增加新的具体类来实现新的业务,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的需求。

3.3:里氏替换原则

所有引用基类的地方必须能够透明的使用其子类的对象。历史替换原则表明在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何的错误和异常,反过来则不成立。里氏替换原则是实现开闭原则的基础,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量只用基类类型对对象进行定义,而在运行时再确定其子类类型,用子类对象类替换基类对象。

运用里氏替换原则时,应该将父类设计为抽象类或者接口,让子类继承父类或实现父类接口,并实现父类中申明的方法。运行时,子类实例替换父类实例,可以很方便的扩展系统的功能,无需修改原有子类代码,增加新的功能可以增加一个新的子类来实现。

3.4:依赖倒转原则

如果开闭原则是面向对象设计原则的目的,那么依赖倒转原则就是面向对象设计的只要实现机制之一。它是系统抽象化的具体实现。

简单来说依赖倒转原则要求:要针对接口编程,不要针对实现编程。在程序代码中传递参数时或者在关联关系中尽量引用层次高的抽象层类。即使用接口和抽象类进行变量类型申明,参数类型申明,方法返回类型申明,以及数据类型的转换等。而不要用具体类来做这些事情。为确保该原则的应用,一个具体的类型应当只实现接口或抽象类中申明过的方法,而不要给出多余的方法,否则将无法调用到之类新增的方法。

在引入抽象层后系统将具有较好的灵活性在程序中应该尽量使用抽象层进行编程,而将具体类写在配置文件中。这样一来,如果系统行为发生变化,只需对抽象层进行扩展,并修改配置文件,而无需修改原有系统的源代码,在不修改的情况下来进行扩展系统的功能,满足开闭原则的要求。

在实现依赖倒转原则时,需要针对抽象层进行编程,而将具体类的对象通过依赖注入的方式注入其他对象中。依赖注入是指当一个对象要与其他对象发生依赖关系时,通过方法参数来注入所依赖的对象。常用的注入方式有:构造注入、设值注入和接口注入三种方式。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过Setter 方法类传入具体类对象,而接口注入是指通过接口中申明的业务方法来传入具体类的对象。

3.5接口隔离原则

每一个接口应该承担相对独立的角色不干不该干的事,该干的事情都要干。这里的接口有两种不同的含义:1一个类型所具有方法特征的集合,仅仅是逻辑上的抽象。将直接带来类型的划分。2是指某种语言具体的接口有严格的定义和结构。如C#语言中interface.在面向对象中需要实现该接口中定义的所有的方法,因此大的总接口用起来不一定很方便,为了使接口的职责单一需要将大接口中的方法根据职责分别放在小的接口中,以确保每个接口使用起来都较为方便

3.6合成复用原则

就是在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新的对象的一部分,新的对象通过委托调用已有对象的方法达到复用功能的目的。简而言之复用时应尽量使用组合聚合关系,少用继承。

在面向对象设计中,可以通过两种不同的方法在不同的环境中复用已有的设计和实现即通过组合聚合关系和继承。首先应该 考虑使用组合聚合,因为组合聚合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类的影响很少。其次才考虑继承,在使用继承时需要严格遵循里氏替换原则,有效使用继承有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统的构件和维护的难度以及系统 的复杂度。通过继承来实现复用的主要问题是继承复用会破坏系统的封装性,因此继承会将基类的实现细节暴露给子类,由于基类的内部某些细节对子类来说是可见的,所以这种复用称之为“白箱复用”,如果基类发生变化,那么子类的实现也不得不发生改变;从基类继承而来的实现时静态的,不可能在运行时发生改变,没有足够的灵活性。而组合聚合关系可以将对象(新对象)纳入到新的对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能,这样做可以使成员对象的内部实现细节对于新对象不可见,所以这种复用称之为“黑箱复用”。相对继承而言其耦合度低,成员对象的变化对新对象的影响不大,可以再新的对象中根据实际需要有选择性的调用成员对象的操作。合成复用可以在运行时动态进行,新的对象可以动态的引用与成员对象类型形同的其他对象。

3.7迪米特原则

迪米特法则要求一个软件实体应尽可能少的与其他实体相互作用。如果两个对象之间不必彼此直接通信,那么这两个对象就不应该发生任何的相互作用,如果其中一个对象需要调用两一个对象的方法,可以通过第三者转发这个调用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值