面向对象设计中的要素与原则有哪些?
代码小侠客
2024-04-17 23:59
面向对象是基于万物皆对象这个哲学观点. 把一个对象抽象成类,具体上就是把一个对象的静态特征和动态特征抽象成属性和方法,也就是把一类事物的数据结构知识库" href="http://lib.csdn.net/base/datastructure" rel="nofollow" rel="nofollow" target="_blank">算法和数据结构封装在一个类之中,程序就是多个对象和互相之间的通信组成的.面向对象设计原则是我们用于评价一个设计模式的使用效果的重要标准之一。下面我给大家介绍一下面向对象设计的三个基本要素和七种设计原则各是什么,以及其定义:
一、面向对象设计的三个基本要素
面向对象的三个基本特征是:封装、继承、多态。
1·封装性
封装性是一种信息隐蔽技术,他体现于类的说明,是对象重要的特性。封装使得数据和操作数据的方法封装为一个整体,想成独立性很强的模块,使得用户只能看到对象的外部特性(对象可以接受拿些信息,可以进行何种处理),而对象的内部特性(内部私有属性和实现处理能力的算法)用户是看不到的。简而言之就是说,封装使对象的设计者与对象的使用者分开,使用者只要知道对象可以做什么就可以了,无需知道具体是怎么实现的。借助封装有助于提高类和系统的安全性。
2·多态性
同一个信息被不同的对象接收到时可能产生不同的行为,这就是多态性。有继承(接口)有重写,父类引用指向子类对象,就会产生多态。多态可以改善程序的组织架构,提高程序的可扩展性。
3·继承性
继承是一种由已有类创建子类的机制,利用继承,可以先创建一个共有属性的一般类,根据这个类再创建具有特殊属性的子类,被继承的类成为父类,当然子类也可以成为父类来继续向下扩展。
二、面向对象设计的五个基本设计原则
面向对象设计的七个基本设计原则是:单一职责原则(SRP)、开放封闭原则(OCP)、Liskov替换原则(LSP)、依赖倒置原则(DIP)、接口隔离原则(ISP)、“迪米特”法则、组合/聚合原则。
1·单一职责原则
单一职责原则又称单一功能原则,其核心思想为:解耦和增强内聚性(高内聚,低耦合)。单一职责原则可以看做是低耦合,高内聚在面向对象原则上的隐身,将职责定义为引起变化的原因,以提高内举行来减少引起变化的原因。职责过多可能引起他变化的原因也就越多,这将导致职责依赖,相互之间产生影响,从而大大损伤内聚性和耦合度。单一职责就是指,只有一种单一的功能,不要为类实现过多的功能点,有些功能可以定义为接口来实现,以保证只有一个引起他变化的原因。
专注是一个人优良的品质。同样的,单一也是一个类的优良设计,杂交不清的职责将使得代码看起来特别别扭,牵一发动全身,有失没敢和必然导致丑陋的系统错误风险。
2·里氏替换原则
核心思想:
①.在任何父类出现的地方都可以用他的子类来替代(子类应当可以替换父类并出现在父类能够出现的任何地方)。子类必须完全实现父类的方法。在类中调用其他类是务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则。这一思想体现为对继承机制的约束规范,只有子类能够替换父类时才能保证系统在运行期内识别子类,这是保证继承复用的基础。在父类和子类的具体行为中,必须严格把握继承层次中的关系和特征,将父类替换为子类,程序的行为不会发生任何变化。同时,这一约束反过来则是不成立的,子类可以替换父类,但是父类不一定能替换子类。
②.子类可以有自己的个性。子类当然可以有自己的行为和外观了,也就是方法和属性
③.覆盖或实现父类的方法时输入参数可以被放大。即子类可以重载父类的方法,但输入参数应比父类方法中的大,这样在子类代替父类的时候,调用的仍然是父类的方法。即以子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松。
④.覆盖或实现父类的方法时输出结果可以被缩小。
里氏替换原则,主要着眼于对抽象和多态建立在继承的基础上,因此只有遵循了里氏替换原则,才能保证继承复用是可靠地。实现的方法是面向接口编程:将公共部分抽象为基类接口或抽象类,通过ExtractAbstractClass,在子类中通过覆写父类的方法实现新的方式支持同样的职责。
里氏替换原则是关于继承机制的设计原则,违反了里氏替换原则就必然导致违反开放封闭原则。
里氏替换原则能够保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余,避免运行期的类型判别。
3·依赖倒置原则
又称依赖倒转原则或依赖反转原则。其核心思想是:要依赖于抽象,不要依赖于具体的实现。具体而言,又分为以下三种情况:
1.高层模块不应该依赖低层模块,两者都应该依赖其抽象(抽象类或接口)
2.抽象不应该依赖细节(具体实现)
3.细节(具体实现)应该依赖抽象。
除此之外,它还有三种实现方式,具体如下:
1.通过构造函数传递依赖对象
2.通过setter方法传递依赖对象
3.接口声明实现依赖对象
我们知道,依赖一定会存在于类与类、模块与模块之间。当两个模块之间存在紧密的耦合关系时,最好的方法就是分离接口和实现:在依赖之间定义一个抽象的接口使得高层模块调用接口,而底层模块实现接口的定义,以此来有效控制耦合关系,达到依赖于抽象的设计目标。
抽象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。
依赖于抽象是一个通用的原则,而某些时候依赖于细节则是在所难免的,必须权衡在抽象和具体之间的取舍,方法不是不变的。依赖于抽象,就是对接口编程,不要对实现编程。
4·开放封闭原则
其核心思想是:软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭。即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。开放封闭原则主要体现在两个方面
1、扩展开放:某模块的功能是可扩展的,则该模块是扩展开放的。软件系统的功能上的可扩展性要求模块是扩展开放的。
2、修改封闭:某模块被其他模块调用,如果该模块的源代码不允许修改,则该模块修改关闭的。软件系统的功能上的稳定性,持续性要求是修改关的。
实现开放封闭原则的核心思想就是对抽象编程,而不是具体编程,因为抽象相对稳定。让类依赖于固定的抽象类或者接口,所以修改就是封闭的。而通多面向对象的继承和多态机制,又可以继承抽象类或者实现接口,通过重写其方法来改变固有的行为,实现方法新的拓展,所以就是开放的。根据开闭原则,在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)的基础上,能扩展其功能(扩展开放)。
需求总是变化的,没有不变的软件,所以就需要用OCP来封闭变化,满足需求,同时还能保持软件内部的封装体系的稳定,不被需求的变化影响。
5·接口隔离原则
其核心思想是:使用多个小的专门的接口,而不要使用一个大的总接口。一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中.。
具体而言,接口隔离原则体现在:接口应该是内聚的,应该避免“胖”接口。一个类对另外一个类的依赖应该建立在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。
接口有效地将细节和抽象隔离,体现了对抽象编程的一切好处,接口隔离强调接口的单一性。而胖接口存在明显的弊端,会导致实现的类型必须完全实现接口的所有方法、属性等;而某些时候,实现类型并非需要所有的接口定义,在设计上这是“浪费”,而且在实施上这会带来潜在的问题,对胖接口的修改将导致一连串的客户端程序需要修改,有时候这是一种灾难。在这种情况下,将胖接口分解为多个特点的定制化方法,使得客户端仅仅依赖于它们的实际调用的方法,从而解除了客户端不会依赖于它们不用的方法。
分离接口主要有以下两种实现方法:
①、使用委托分离接口:通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,但是会增加系统的开销。
②、.使用多重继承分离接口:通过接口多继承来实现客户的需求,这种方式是较好的。
6.“迪米特”法则
又称最少知识原则,其核心思想:一个软件实体应当尽可能少的与其它实体发生相互作用。(类间解耦,低耦合)意思就是降低各个对象之间的耦合,提高系统的可维护性;在模块之间只通过接口来通信,而不理会模块的内部工作原理,可以使各个模块的耦合成都降到最低,促进软件的复用。
但是,我们需要注意以下这些内容:
①.在类的划分上,应该创建有弱耦合的类;
②.在类的结构设计上,每一个类都应当尽量降低成员的访问权限;
③在类的设计上,只要有可能,一个类应当设计成不变;
④.在对其他类的引用上,一个对象对其它对象的引用应当降到最低;
⑤尽量降低类的访问权限;
⑥.谨慎使用序列化功能;
⑦.不要暴露类成员,而应该提供相应的访问器(属性)
7.组合/聚合原则
其核心思想是:尽量使用对象组合,而不是继承来达到复用的目的。该原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
复用的种类:
1.继承
2.合成聚合
在使用这个原则时,我们需要注意一点就是:在复用时应优先考虑使用合成聚合而不是继承。
小编结语:
以上就是7个基本的面向对象设计原则和三个基本要素,它们就像面向对象程序设计中的金科玉律,遵守它们可以使我们的代码更加鲜活,易于复用,易于拓展,灵活优雅。不同的设计模式对应不同的需求,而设计原则则代表永恒的灵魂,需要在践中时时刻刻地遵守。实际开发中也不是每种设计模式都会经常用到。因为归根结底,设计模式也好,架构也好,都是为需求服务的,没有需求业务模型,不能生搬硬套模式。
以上就是小编今天要跟大家分享的内容,更多精彩内容尽在编程学习网教育,欢迎咨询哟~~
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341