面向对象的原则:
1.单一职责原则(SRP)
RP说的其实是类设计时的职责划分和粒度问题。
在软件开发中使用SRP原则时,一个类承担一个职责,过多互不相关的职责集中在一个类中会导致高耦合性。
但要根据具体的情况设计,避免因过度追求单一职责而将类的结构设计的过度复杂,过犹不及。
定义:
每一个类应该只专注于做一件事
解析:
也可以理解为;只有有一个引起它变化的原因,如果一个类同时做两件事情,那么这两件事情都有可能引起它的变化。同样的道理,
如果仅有一个引起它变化的原因,那么这个类也就只能做一件事情。这就是单一职责原则
使用法则:
单一职责原则把相同的职责进行聚合,避免把相同的职责分散到不同的类之中,这样就可以控制变化,把变化限制在一个地方,防止因为一个地方的变动,引起更多地方的变动的“涟漪效应”。单一职责原则实际上消除了对象之间的耦合,避免一个类承担过多的职责。单一职责不是说一个类就只有一个方法,而是单一功能
缺点:造成源文件增多,给管理带来不便,所以在实际应用中,可以对经常使用或经常需要改动的模块应用该原则,将其封装为独立的类。
使用SRP注意点:
1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责;
2、在没有变化征兆的情况下应用SRP或其他原则是不明智的;
3、在需求实际发生变化时就应该应用SRP等原则来重构代码;
4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码;
5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构;
2.开放-封闭原则(OCP)
定义:每一个类应该是对扩展开放(Open for extension),对修改关闭(Close for modification)
解析:
不修改原有代码即可完成对系统的扩展。
开放-封闭原则的关键在于:抽象,也就是可变性的封装,抽象的目的是创建一个固定却能够描述一组任意个可能行为的基类。
而这一组可能的行为则表现为该基类的子类。对于基类的更改是封闭的,所以它里边的方法一旦确定就不能更改(对接口里的方法进
行更改将带来灾难性的后果)。模块通过抽象基类进行引用,所以子类的扩展并不影响整个模块,所以它是开放的
使用法则:只对程序中频繁变化的部分进行抽象
缺点:创建正确的抽象是要花费开发时间和精力的,同时抽象也增加了软件设计的复杂性
使用OCP注意点:
1、实现OCP原则的关键是抽象;
2、两种安全的实现开闭原则的设计模式是:Strategy pattern(策略模式),
Template Methord(模版方法模式);
3、依据开闭原则,我们尽量不要修改类,只扩展类,但在有些情况下会出现一些比较怪异的状况,这时可以采用几个类进行组合来完成;
4、将可能发生变化的部分封装成一个对象,如: 状态, 消息,,算法,数据结构等等,封装变化是实现"开闭原则"的一个重要手段,如经常发生变化的状态值,如温度,气压,颜色,积分,排名等等,可以将这些作为独立的属性,如果参数之间有关系,有必要进行抽象。对于行为,如果是基本不变的,则可以直接作为对象的方法,否则考虑抽象或者封装这些行为;
5、在许多方面,OCP是面向对象设计的核心所在。遵循这个原则可带来面向对象技术所声称的巨大好处灵活性、可重用性以及可维护性)。然而,对于应用程序的每个部分都肆意地进行抽象并不是一个好主意。应该仅仅对程序中呈现出频繁变化的那部分作出抽象。拒绝不成熟的抽象和抽象本身一样重要;
3.里氏(Liskov)替换原则(LSP)
定义:任何基类可以出现的地方,子类一定可以出现,
解析:所有的父类类型的对象都替换为子类类型时,程序的行为没有变化,反过来就不成立,如果一个软件实体使用的是子类类型的话,那么它不一定适用于基类
LSP优点:
1、保证系统或子系统有良好的扩展性。只有子类能够完全替换父类,才能保证系统或子系统在运行期内识别子类就可以了,因而使得系统或子系统有了良好的扩展性。
2、实现运行期内绑定,即保证了面向对象多态性的顺利进行。这节省了大量的代码重复或冗余。避免了类似instanceof这样的语句,或者getClass()这样的语句,这些语句是面向对象所忌讳的。
3、有利于实现契约式编程。契约式编程有利于系统的分析和设计,指我们在分析和设计的时候,定义好系统的接口,然后再编码的时候实现这些接口即可。在父类里定义好子类需要实现的功能,而子类只要实现这些功能即可。
使用LSP注意点:
1、此原则和OCP的作用有点类似,其实这些面向对象的基本原则就2条:
(1)面向接口编程,而不是面向实现;
(2)用组合而不主张用继承
2、LSP是保证OCP的重要原则
3、这些基本的原则在实现方法上也有个共同层次,就是使用中间接口层,以此来达到类对象的低偶合,也就是抽象偶合!
4、派生类的退化函数:派生类的某些函数退化(变得没有用处),Base的使用者不知道不能调用f,会导致替换违规。在派生类中存在退化函数并不总是表示违反了LSP,但是当存在这种情况时,应该引起注意。
5、从派生类抛出异常:如果在派生类的方法中添加了其基类不会抛出的异常。如果基类的使用者不期望这些异常,那么把他们添加到派生类的方法中就可以能会导致不可替换性。
附A:
基于契约设计(DBC:Design By Contract)
使用DBC,类的编写者能够显式的规定针对该类的契约。客户代码的编写者可以通过该契约获悉可以依赖的行为方式。
契约是通过为每个方法声明的前置条件(preconditions)和后置条件(postconditions)来指定的。
要使一个方法得以执行,前置条件必须要为真。执行完毕后,该方法要保证后置条件为真。
附B:
use-a 依赖 A与B use-a关系 A中持有B的实例,B实例是在A之外创建,通过传参被A使用,可以调用B的方法或属性。
例如:我使用电脑。
has-a 组合 A与B has-a关系 A持有B的实例,A负责B的创建。
1.静态Has-A关系。这在UML中叫做组合(composition)
例如:我有一双手
2.动态Has-A关系。这在UML中叫做聚合(aggregation)
例如:Ant-Team拥有5名成员。
is-a 继承 A与B is-a 关系 B是A的父类
4.依赖倒置原则(DIP)
定义:依赖倒转原则就是要依赖于抽象,不要依赖于细节。要针对接口编程,不要针对实现编程对程序中频繁变化的部分进行依赖倒置。
解析:应当使用高层的接口和抽象类作为变量的声明类型、参数的声明类型, 方法的返还类型声明,以及数据类型的转换等
缺点:因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用将导致大量的类文件。给维护带来不必要的麻烦
5.接口隔离原则(ISP):
描述:不要强迫客户依赖于它们不用的方法。
应用:一个类对另外一个类的依赖性应当是建立在最小的接口上的。如果客户端只需要某一些方法的话,那么就应当向客户端提供这些需要的方法,而不要提供不需要的方法。提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。
结论:使用多个专门的接口比使用单一的接口要好。
其中:适配器模式是接口隔离原则的一个应用。
6.迪米特法则(Law of Demeter):
又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。或者说是不和陌生人说话。
好处是:提高内聚、降低耦合。
缺点是:在系统里造出大量的小方法,这些方法仅仅是传递间接的调用,与系统的商务逻辑无关,还能造成系统的不同模块之间的的通信效率,使这些模块不容易协调。门面模式和调停者模式实际上就是迪米特法则的应用。
用迪米特法则到系统的设计中时,要注意以下几点:
* 在类的划分上,应当创建有弱耦合的类.类之间的耦合越弱,就越有利于复用.
* 在类的结构设计上,每一个类都应当尽量降低成员的访问权限.
* 在类的设计上,只要可能,一个类应当设计成不变类.
* 在对其他类的引用上,一个对象对其他对象的引用应降到最低.
* 尽量限制局部变量的有效范围.
分享到:
相关推荐
1面向对象6大原则--单一职责原则 2面向对象6大原则--里氏代换原则 3面向对象6大原则--开闭原则 4面向对象6大原则--依赖倒转原则 5面向对象6大原则--合成复用原则 6面向对象6大原则--接口隔离原则
面向对象设计原则概述 单一职责原则 开闭原则 里氏代换原则 依赖倒转原则 接口隔离原则 合成复用原则 迪米特法则
23种设计模式,C#面向对象设计模式与原则, Webcast课程
北大青鸟佳音旗舰教学内容在开发过程中用的一些原则
Java设计模式02面向对象设计原则
面向对象七大原则
会继续上载,可以帮助大家理解设计模式的使用,不错的东西
面向对象设计原则,介绍在面向对象设计中遇到的相关问题。
面向对象基本原则 面向对象基本原则 面向对象基本原则面向对象基本原则面向对象基本原则
描述面向对象的设计模式及其子模式,一篇比较经典的论文,大家可以看看
面向对象分析设计原则 面向对象分析设计原则
面向对象设计原则解析,简练地介绍面向对象的原则,让你透彻理解
设计模式面向对象七大原则
面向对象设计原则概述 单一职责 开闭原则 里氏代换原则 依赖倒转原则 接口隔离原则 合成复用原则 迪米特法则
面向对象的11个设计原则 SOLID原则 单一职责原则(The Single Responsibility Principle) 开放/关闭原则(The Open Closed Principle) 里氏替换原则(The Liskov Substitution Principle) 依赖倒置原则(The Dependency ...
面向对象设计原则单一责任原则SRP开放封闭原则OCP
02 第2章 面向对象设计原则02 第2章 面向对象设计原则02 第2章 面向对象设计原则
c#面向对象三原则
对面向对象设计原则的总结,设计模式:“开-闭”原则,里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法则、接口隔离原则