萍聚社区-德国热线-德国实用信息网

 找回密码
 注册

微信登录

微信扫一扫,快速登录

萍聚头条

查看: 30615|回复: 2

分享自己关于面向对象编程的理解, 原创来自penghuang.de

[复制链接]
发表于 2015-8-23 14:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册 微信登录

x
所有学过面向对象的人,一定都听说过solid设计原则, 可是要想真正的理解,尽可能的正确执行这些原则, 确不是一件简单的事情, 我经常会重复思考这些原则的内容,在工作中,我会尽量的让自己的编码符合这些原则, 在这里,我记录一下,我个人对这些原则的理解。

SOLID 每个字母都是一个原则的首字母, 他的英语意思却正好是坚固, 牢固的意思,预示着, 如果想程序变得坚不可摧,就要坚持这些原则,  不知道这是巧合,还是提出这些原则的人有意如此安排。

1 Single Responsibility Principle 单一职能原则

这个原则,理解很简单, 但是执行起来却似乎有些困难, 简单来说,在我们设计类或者方法的时候, 我们应该尽可能的将复杂的逻辑拆分成简单的职能, 每个方法只能做一件事情,每个类只代表一类事物, 在真实的工作中,我们往往为了实现客户要求的功能,而尽快的实现具体的业务逻辑,但是在codereview的时候,我们就会发现,有很多代码过于沉长, 如果在一个方法中需要用注释来解释一段代码,那么就有必要将其拆分出来,成为单独的方法,并用正确的方法名来解释代码,尽量减少代码中的注释, 其实这也是执行这个原则的过程之一,如果一个类的职能多样, 如果发现其不同的职能在不同的维度有着各自的变化,我们就应该将其拆分成更多的类。

2 Open-Closed Principle 开闭原则

这个原则应该是最常被提起一个原则,说起来简单,却是最难实现的一个,原则的意思就是说,软件实体对扩展是开放的,而对修改是封闭的,软件实体可以是一个完整的软件,也可以是一个模块, 或者是一个具体的类, 用最简单的话来解释,也就是说, 当我们要拓展一个软件实体的功能时, 我们最好可以不修改原来的代码, 而是直接为新的功能撰写新的代码, 显然要想实现这一目的,在软件的设计阶段,我们就必须考虑到拓展的问题,所以开闭原则可以说是软件架构设计的最终目的, 可以说,所有的设计模式都是为了实现开闭原则这一目的而产生的,要想实现开闭原则,那么软件架构的抽象化设计就是关键所在, 同过经典设计模式的学习,再加上工作中的实际应用,就能慢慢揭开系统抽象化设计的面纱。

3 Liskov Substitution Principle 里氏替换原则

这个原则体现了我们对女性的尊重,或者是体现了女程序员的宝贵,因为在著名的五大原则里, 这是唯一一个用人名来命名的原则,也是唯一一个通过名字不能有效阐述原则精神的一个。这个原则,可以这样简单理解,所有的基类(父类)都可以被子类替换, 而不会使系统发生任何异常。  在具体的使用中, 我们应该将父类设计为抽象类或者接口,而具体功能要在子类中实现, 而不同的类之间应该只引用抽象的父类, 然后再运行时,以注入的方式,注入具体的子类,从而实现里氏替换原则, 其实在这我已经提到了另一个原则,依赖倒转原则。 所以在这儿, 我们可以看出,其实里氏替换原则是一个标尺, 当我们实现了一个系统后, 我们可以用里氏替换原则来检查我们的设计是否满足里氏替换原则的要求, 如果满足,那么我们基本上也实现了开闭原则这个目的。

4 Interface segregation principle 接口隔离原则

客户端不应该依赖那些和它无关的接口,也就是说,如果有个别客户端只需要一个接口(Interface)中的部分功能(methods), 那么我们就要考虑, 是否能够将该接口拆分成两个或多个,这个原则很容易理解, 但是在实际工作中,却是最容易被忽略的一个, 我见过很多精英团队设计的接口都存在接口沉余的问题,因为在设计之初,我们肯定不可能看清在今后工作中所有未知的变化, 再加上大型开发团队在管理上存在诸多问题,为了减少变动, 那么那些有沉余的接口就会被保留下来, 而我们作为一个员工能做的就是,尽可能的在我们的职责范围内,勇于重构我们的代码, 让他符合原则, 保持清洁, 仅此而已。

5 Dependency inversion principle 依赖倒转原则

前面提到过实现开闭原则是设计的目标, 而里氏替换原则是具体衡量设计的标尺,那么现在我们则需要一个具体的手段来实现上面两个原则, 依赖倒转原则就是这个具体是实现手段。

高层模块不应该依赖于低层模块,他们都应该依赖于抽象, 抽象不应该依赖于细节,细节应该依赖于抽象。

乍一看,玄之又玄,其实,这个一个非常有操作性的原则,什么是高层模块什么是低层模块, 在程序和程序库的引用链中,是不可以相互引用的, 引用一定是单向的, 那么在两个程序或程序库之间, 被引用的那个就是低层模块, 引用者本身就是高层模块, 高层模块不应该可以直接使用低层模块中的类,而是应该同过引用其基类或是接口(这里可以返回去在看一下里氏替换原则的解释),在实际设计中,我们应该将接口(Interface)和实现(Implementation)分别放在不同的程序库中,高层模块引用接口库用来使用低层模块的功能, 低层模块引用接口库,来实现接口库中定义的功能,  这就是 高层模块不应该依赖于低层模块,他们都应该依赖于抽象。

在接口库中我们不应该引用任何其他类的具体实现,应该只引用其他接口或者抽象的基类, 这就是抽象不应该依赖于细节,细节应该依赖于抽象。

当然在实际工作中,我们经常会使用系统或者语言自带的库类或者购买的第三方库类, 这个时候这些库类的一些类作为基础数据类型是可以在接口中直接使用的, 不过每当发生这种情况的时候,我们都该多问自己一便, 是否有相应的接口可以使用, 这样就能避免很多不必要的错误。

以上就是我的一些粗浅认识,除了以上五大原则,还有合成复用原则(Composition/Aggregate Reuse principle) 和最少知识原则(Least Knowledge principle), 以后再慢慢写吧。
下面是我的个人博客,希望能和大家交流
penghuang.de
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2015-9-1 22:18 | 显示全部楼层
同分享相关视频 https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B315
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2015-9-2 17:15 | 显示全部楼层
好奇lz用的神马输入法, 冗长写成沉长,这是五笔呢还是abc呢
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

手机版|Archiver|AGB|Impressum|Datenschutzerklärung|萍聚社区-德国热线-德国实用信息网 |网站地图

GMT+2, 2024-4-19 17:53 , Processed in 0.618840 second(s), 15 queries , MemCached On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表