共计 2698 个字符,预计需要花费 7 分钟才能阅读完成。
面向对象设计准则的作用
能够进步软件的可维护性于可复用性,其中可维护性是指代码可能被了解、改过、适应扩大的难易水平,可复用性是指代码可能被重用的难易水平,可维护性和可复用性是用于掂量软件品质的两个十分重要的属性。
7 个面向对象设计准则
设计准则名称 | 定义 |
---|---|
繁多职责准则 | 一个对象只应该蕴含繁多的职责,并且该职责被残缺地封装在一个类中 |
开闭准则 | 软件实体应该对扩大凋谢,对批改敞开 |
里氏代换准则 | 所有援用基类的中央必须都能应用基类的子类替换 |
依赖倒转准则 | 高层模块不应该依赖底层模块,它们都应该依赖形象。形象不应该依赖细节,细节应该依赖形象 |
接口隔离准则 | 接口细分,不应该依赖不须要的接口 |
合成复用准则 | 优先应用对象组合,而不是应用继承来达到复用的目标 |
迪米特法令 | 每一个对象对其它的对象都只有起码的信息,而且局限于那些与本对象密切相关的信息 |
繁多职责准则
繁多职责准则是实现高内聚、低耦合的指导方针,对一个类来说,应该仅有一个引起它变动的起因。在软件系统中,一个类承当的职责越多,它被复用的可能性就越小,并且当承当过多的职责后,就相当于将这些职责耦合在一起,当其中一个职责发生变化时,极有可能会影响到其它职责的失常工作。因而要将这些职责进行拆散,将不同的职责封装在不同的类中(将不同的变动起因封装在不同的类外面),如果多个职责总是会同时产生扭转,那么则能够将它们封装在一个类中。
开闭准则
开闭准则是极其重要的设计准则,对扩大开发,对批改敞开,即尽量在不批改原有代码的状况下进行扩大。
当软件系统面临新的需要时,应该尽量保证系统的设计框架是稳固的,如果一个软件设计合乎开闭准则,那么能够十分不便的对系统进行扩大,而且在扩大时无需批改现有代码,使零碎同时具备适应性、灵活性和较好的稳定性以及延续性。
为了满足开闭准则,须要对系统进行抽象化设计,抽象化是开闭准则的要害。在 C#、JAVA 等编程语言中能够定义一个绝对稳固的形象层,而将不同的实现放在具体的实现层中实现。能够通过接口、抽象类等机制进行抽象化设计,定义零碎形象层,再通过具体类进行扩大,如果未来需要变动须要批改零碎的行为,毋庸对形象层进行改变,只有减少新的具体类来实现新的业务需要,在不批改原有代码的前提下扩大零碎性能,即是开闭准则。
里氏代换准则
该准则示意,在软件中将一个基类对象替换成它的子类对象,程序能够失常运行,不会产生任何谬误,反之则不成立。里氏代换准则是实现开闭准则的根底,因为应用基类的中央都能够应用子类代替,因而在程序中尽量应用基类类型定义对象,在运行时再确定其子类的具体类型,用子类对象替换父类对象。
在应用里氏代换准则时应将父类设计成抽象类或者接口,让子类继承父类或实现父类接口,并实现父类中申明的办法。运行时子类实例替换父类实例,能够很不便地扩大零碎性能,无需批改原有子类代码,减少新的性能能够通过减少一个新的子类来实现。
依赖倒转准则
依赖倒转准则是面向对象设计的次要实现机制之一,它是零碎抽象化的具体实现。依赖倒转准则要求:面向接口编程,不要针对实现编程。
在传递参数时或者在关联关系中尽量援用形象层,即应用接口和抽象类进行变量类型申明、参数类型申明、办法返回类型申明和数据类型转换等,而不要用具体类来做这些事件。为了确保该准则的利用,一个具体类该当只实现接口或抽象类中申明过的办法,而不要给出多余的其它办法,否则基类将无奈调用到子类中减少的新办法。
在引入形象层后,零碎将会具备很好的灵活性,在程序中应该尽量应用形象层进行编程,而将具体类写在配置文件中,这样做的益处在于,如果未来需要发生变化,只须要对形象层进行扩大,并批改配置文件,而无须批改原有的代码,满足开闭准则。
实现依赖倒转准则,须要针对形象层进行编程,将具体类的对象通过依赖注入的形式注入其它对象中。依赖注入指的是:当一个对象须要与其它对象产生依赖关系时,通过办法参数来注入所依赖的对象。罕用的注入形式:结构注入 (通过构造函数传入具体类的对象)、设置注入(set 办法传入具体类的对象) 和接口注入(在接口中申明的业务办法传入具体类的对象)。
接口隔离准则
当一个接口太大时,须要将它宰割成更细小的接口,每一个接口应该承当一种绝对独立的角色,不做与之无关的事件。
接口细分是有益处的,如果提供的接口太大,蕴含的办法太多,应用起来反而不不便,因为实现接口就须要实现这个接口的所有办法,而并不是每一个办法都是所须要的。这时候为了使职责繁多,须要将接口中的办法依据其职责别离放在不同的小接口中,确保接口应用起来不便,并且都承当繁多的角色。接口应该尽量细化,每个接口中蕴含的办法应尽量的少,最好只蕴含一个模块所有要的办法即可。
合成复用准则
合成复用准则就是在一个新的对象里通过关联关系来应用一些已有的对象,使之成为新对象的一部分,复用时尽量应用组合,少用继承。
在面向对象中,能够应用组合或者继承的形式复用已有的设计和实现,但首先应该思考组合,因为这种形式能够使零碎更加灵便,升高类与类之间的耦合度,一个类的变动对其它类的影响较小。其次才思考继承,应用继承时应该恪守里氏代换准则。
继承的局限性:如果基类产生扭转,那么子类也不得不发生变化。同时继承的实现是动态的,不可能在运行时产生扭转,短少灵活性。
为什么应用组合:因为组合是将已有对象引入到新对象中,让它成为新对象的一部分,因而新对象能够调用已有对象的性能,而对象外部的实现对新对象来说并不可见。比照继承,组合的耦合度更低,成员对象的变动对新对象的影响不大,并且合成复用能够在运行时动静进行,新对象能够动静援用成员对象类型雷同的其它对象。
什么时候用继承什么时候用组合?
如果两个类之间的关系是 a -Has-b(a 对象领有 b 职责),那么应该应用组合;如果关系是 a -Is-b(a 对象属于 b 类型的某一品种),这是应该应用继承。
迪米特法令
每个模块应该尽量少地与其它模块互相援用产生关联,这样在模块变动时,对其它模块产生的影响也会最小,利用这个法令可升高类之间的耦合度。
对象只应该与本人所关怀的成员通信,如:
- 对象自身,即本人
- 以参数模式传入到以后对象中的对象
- 以后对象的成员对象
- 以后对象所创立的对象
只有数据上述的某一个类型,便可与之间接交互。在程序设计的时候,如果两个对象没有必要彼此间接通信,那么这两个对象就不应该产生任何间接关联,如果一个对象须要调用另一个对象的办法,能够通过引入一个两头者的形式来实现。
利用迪米特法令时,应尽量创立松耦合的类,耦合度越低,越利于复用;在类的结构设计上,该当升高每一个类中成员变量和成员函数的拜访权限;类型该当尽量设计成不变类;一个对象对其它对象的援用该当降到最低。