面向对象三大特征及代码优化七大原则

  面向对象(Object Oriented,OO)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。

  一.面向对象的三大基本特性

  1.封装
  封装,就是把客观事物封装成抽象的类,并且类可以使自己的数据和方法只让可信的类或者对象操作,对不可信的则进行信息隐藏。一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
  2.继承
  继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过 “继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承(又称接口实现)。实现继承是指直接使用 基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。

组合是has a的关系 
继承是is a的关系
为扩展而继承,为复用而组合

  3.多态
  多态,是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

  二.OOP编程的七个基本原则

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

  类的功能要单一,体积不要过于庞大。
     SRP是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
  2.开放封闭原则OCP(Open-Close Principle)

  对扩展开放,对修改关闭。
     一个模块在扩展性方面应该是开放的,而在更改性方面应该是封闭的。比如:一个网络模块,原来只提供服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
  3.里式替换原则LSP(the Liskov Substitution Principle)

  父类出现的地方,子类都可以替换。
     子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,也不管是总部员工还是外派员工,都应当可以参加抽奖,否则公司就不和谐了。
  4.依赖倒置原则DIP(the Dependency Inversion Principle)

  具体依赖抽象。面向对象、抽象编程,不要面向细节、过程编程。

High level modules should not depend upon low level modules.Both should depend upon abstractions.
Abstractions should not depend upon details.
Details should depend upon abstracts.

   可以翻译为:

  • 高层模块不应该依赖低层模块,两者都应该依赖抽象
  • 抽象不应该依赖细节
  • 细节应该依赖抽象

  每一个逻辑的实现都是由颗粒原子逻辑组成的,颗粒原子逻辑就是低层模块,而颗粒原子逻辑组成的模块就是高层模块。在java语言中,抽象就是接口或抽象类,两都都是不能直接被实例化的,细节就是实现类,实现接口或继承抽象类而产生的类就是细节,两者都可以直接被实例化。

  依赖倒置原则在java语言中的表现是:

  • 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
  • 接口或抽象类不依赖实现类
  • 实现类依赖接口或抽象类

  依赖倒置原则可以引申出OOD(Object-Oriented Design,面向对象设计)和OOP(Object-Oriented Programing,面向对象编程)。

  采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定,降低并行开发引起的风险,提高代码的可读性和可维护性。  

对象的依赖关系有三种方式来传递:
    ①构造函数传递依赖对象
    在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入。
    ②Setter方法传递依赖对象
    在类中通过Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入。
    ③接口声明依赖
    在接口的方法中声明依赖对象,该方法也叫做接口注入。

   5.接口分离原则ISP(the Interface Segregation Principle)
  接口定义的标准尽可能单一,致力于对接口的多实现。接口规模不要臃肿。

  6.迪米特法则---最少知识原则。类与类之间尽量减少不必要的访问。降低耦合。

  7.合成复用原则。多用组合/聚合,少用继承,降低耦合度。

  最后,我们再谈下内聚与耦合。

  内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽和局部化概念的自然扩展。内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系。
  耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。 程序讲究的是低耦合,高内聚。就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却要不那么紧密。
  内聚和耦合是密切相关的,同其他模块存在高耦合的模块意味着低内聚,而高内聚的模块意味着该模块同其他模块之间是低耦合。在进行软件设计时,应力争做到高内聚,低耦合。

  

  简单地说,软件工程中对象之间的耦合度就是对象之间的依赖性。指导使用和维护对象的主要问题是对象之间的多重依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。有软硬件之间的耦合,还有软件各模块之间的耦合。  

  耦合可以分为以下几种,它们之间的耦合度由高到低排列如下:

    内容耦合。当一个模块直接修改或操作另一个模块的数据时,或一个模块不通过正常入口而转入另一个模块时,这样的耦合被称为内容耦合。内容耦合是最高程度的耦合,应该避免使用之。
    公共耦合。两个或两个以上的模块共同引用一个全局数据项,这种耦合被称为公共耦合。在具有大量公共耦合的结构中,确定究竟是哪个模块给全局变量赋了一个特定的值是十分困难的。
    外部耦合。一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息,则称之为外部耦合。
    控制耦合。一个模块通过接口向另一个模块传递一个控制信号,接受信号的模块根据信号值而进行适当的动作,这种耦合被称为控制耦合。
    标记耦合。若一个模块A通过接口向两个模块B和C传递一个公共参数,那么称模块B和C之间存在一个标记耦合。
    数据耦合。模块之间通过参数来传递数据,那么被称为数据耦合。数据耦合是最低的一种耦合形式,系统中一般都存在这种类型的耦合,因为为了完成一些有意义的功能,往往需要将某些模块的输出数据作为另一些模块的输入数据。
    非直接耦合。两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。 

  总的来说,耦合是影响软件复杂程度和设计质量的一个重要因素,在设计上我们应采用以下原则:

  如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,尽量避免使用内容耦合。

posted @ 2018-04-22 17:04  奔跑在梦想的道路上  阅读(2525)  评论(0编辑  收藏  举报