走向灵活软件之路--面向对象的六大原则

写在前面应用开发过程中,最难的不是完成应用的开发工作,而是在后续的升级、维护过程中如何让应用能够拥抱变化。拥抱变化也就意味着在满足需求且不破坏系统稳定性的前提下保持高可扩展性、高内聚、低耦合,在经历了各个版本的变更之后依然保持清晰、灵活、稳定的系统架构。最近也是终于有空能自己学点东西了,嗯,刚好手边有本放置了好久的《Android源码设计模式》,书挺不错的,可以当作工具书去查阅。而书前面部分讲到了面
摘要由CSDN通过智能技术生成
写在前面
应用开发过程中,最难的不是完成应用的开发工作,而是在后续的升级、维护过程中如何让应用能够拥抱变化。
拥抱变化也就意味着在满足需求且不破坏系统稳定性的前提下保持高可扩展性、高内聚、低耦合,在经历了各个版本的变更之后依然保持清晰、灵活、稳定的系统架构。


最近也是终于有空能自己学点东西了,嗯,刚好手边有本放置了好久的《Android源码设计模式》,书挺不错的,可以当作工具书去查阅。而书前面部分讲到了面向对象的六大原则,通过了示例讲解了六大原则的定义和作用,以及这些原则解决了什么样的问题,而正是通过这些面向对象的六大原则,让我们的软件开发的更加灵活,更健壮,更具扩展性。当然这些都是原则,也要看具体的情况,具体问题具体分析,当需求变更导致问题比较棘手时,代码耦合度高,扩展性差时,不妨尝试下看看是否违背了这些原则。
你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起。
—–Arthur J.Riel

由于篇幅限制,例子都采用的其他人总结的,有需要的可以看看。这里对这些例子的作者表示感谢!

1、单一职责原则

SRP简介(SRP–Single-Responsibility Principle):单一职责原则
说明:就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因。
也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑拆分这个类了,让各个功能独立出来。因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化。 例如,两个完全不一样的功能就不应该放在一个类中。一个类中应该是一组相关性很高的函数。数据的封装。我们可以不断地审视自己的代码,根据具体的业务。功能对类进行相应的拆分,这是我们优化代码迈出的第一步。
使用SRP要注意的地方:
1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责;
2、在没有变化征兆的情况下应用SRP或其他原则是不明智的;
3、在需求实际发生变化时就应该应用SRP等原则来重构代码;
优点:消除耦合,减小因需求变化引起代码僵化。
举个例子?点我查看

2、开闭原则

OCP简介(Open-Closed Principle):开放-封闭原则
说明:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。因为变换、升级和维护等原因需要对软件原有代码进行修改时,可能会将错误引入原本已经经过测试的旧代码中,破坏原有系统。因此,当软件需要变化时,我们应该尽量通过扩展的方式来实现变化,而不是通过修改已有的代码来实现。一句话概括就是:对扩展开放,对修改关闭。 当然在现实开发中,只通过集成的方式来进行升级,维护原有的系统只是一个理想化的愿景,因此,在实际开发中,修改原有的代码、扩展代码往往是同时存在的。
优点:按照OCP原则设计出来的系统,降低了程序各部分之间的耦合性,其适应性、灵活性、稳定性都比较好。当已有软件系统需要增加新的功能时,不需要对作为系统基础的抽象层进行修改,只需要在原有基础上附加新的模块就能实现所需要添加的功能。增加的新模块对原有的模块完全没有影响或影响很小,这样就无须为原有模块进行重新测试。
举个例子?点我查看

3、里氏替换原则

LSP简介(Liskov Substitution Principle) 里氏代换原则
说明:子类型必须能够替换它们的基类型。一个软件实体如果使用的是一个基类,那么当把这个基类替换成继承该基类的子类,程序的行为不会发生任何变化。软件实体察觉不出基类对象和子类对象的区别。
里氏替换原则通俗的去讲就是:子类可以去扩展父类的功能,但是不能改变父类原有的功能。他包含以下几层意思:
1、子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
2、子类可以增加自己独有的方法。
3、当子类的方法重载父类的方法时候,方法的形参要比父类的方法的输入参数更加宽松。
4、当子类的方法实现父类的抽象方法时,方法的返回值要比父类更严格。
优点:可以很容易的实现同一父类下各个子类的互换,而客户端可以毫不察觉。
确保程序遵循里氏替换原则可以要求我们的程序建立抽象,通过抽象去建立规范,然后用实现去扩展细节,这个是不是很耳熟,对,里氏替换原则和开闭原则往往是相互依存的。
举个例子?点我查看

4、依赖倒置原则

DIP(Dependence Inversion Principle)依赖倒置原则
说明:依赖倒置原则指的是一种特殊的解耦方式,使得高层次的模块不应该依赖于低层次的模块的实现细节的目的,依赖模块被颠倒了。
可以简单来说就是
1、高层模块不应该依赖底层模块,两者都应该依赖其抽象
2、抽象不应该依赖细节
3、细节应该依赖抽象
在Java 中抽象指的是接口或者抽象类,两者皆不能实例化。而细节就是实现类,也就是实现了接口或者继承了抽象类的类。他是可以被实例化的。高层模块指的是调用端,底层模块是具体的实现类。在Java中,依赖倒置原则是指模块间的依赖是通过抽象来发生的,实现类之间不发生直接的依赖关系,其依赖关系是通过接口是来实现的。这就是俗称的面向接口编程。
优点:使用传统过程化程序设计所创建的依赖关系,策略依赖于细节,这是糟糕的,因为策略受到细节改变的影响。依赖倒置原则使细节和策略都依赖于抽象,抽象的稳定性决定了系统的稳定性。
举个例子?点我查看

5、接口隔离原则

ISP(Interface Segregation Principle) 接口隔离原则
说明:使用多个专一功能的接口比使用一个的总接口总要好。从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。过于臃肿的接口是对接口的污染,不应该强迫客户依赖于它们不用的方法。 接口隔离原则的目的是让系统解开耦合,从而容易重构、更改和重新部署。
接口隔离原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
采用接口隔离原则对接口进行约束时,要注意以下几点:
1、接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
2、为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3、提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
优点:会使一个软件系统功能扩展时,修改的压力不会传到别的对象那里。
举个例子?点我查看

6、迪米特原则

LOD(Law of Demeter) 迪米特原则 或者LKP(Least Knowledge Principle)最少知识原则
说明:对象与对象之间应该使用尽可能少的方法来关联;一个对象应该对其他对象保持最小的了解。
即一个对象应该对其他对象有最少的了解,通俗的讲,一个类应该对自己需要耦合或调用的类知道的方法知道的越少越好,类的内部如何实现与调用者或者依赖者没关系,调用者或者依赖者只需要知道它需要的方法即可,其他一概不用管。类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
优点:降低类与类之间的耦合。
举个例子?点我查看

总结

到这里,面向对象的六大原则,就写完了。我们看出来,这些原则其实都是应对不断改变的需求。每当需求变化的时候,我们利用这些原则来使我们的代码改动量最小,而且所造成的影响也是最小的。但是我们在看这些原则的时候,我们会发现很多原则并没有提供一种公式化的结论,而即使提供了公式化的结论的原则也只是建议去这样做。这是因为,这些设计原则本来就是从很多实际的代码中提取出来的,他是一个经验化的结论。怎么去用它,用好他,就要依靠设计者的经验。否则一味者去使用设计原则可能会使代码出现过度设计的情况。大多数的原则都是通过提取出抽象和接口来实现,如果发生过度的设计,就会出现很多抽象类和接口,增加了系统的复杂度。让本来很小的项目变得很庞大,当然这也是Java的特性(任何的小项目都会做成中型的项目)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值