您现在的位置:甲沟炎专科治疗医院 >> 甲沟炎医院 >> 软件复杂性简洁之道设计原则篇

软件复杂性简洁之道设计原则篇

 

治疗白癜风医院哪家好 http://m.39.net/disease/yldt/bjzkbdfyy/

作者:聂晓龙

前言

软件之所以这么有魔力这么繁荣,在于软件的灵活性,也正因为软件的灵活性导致了软件的复杂性。绳子灵活而方便,它能度无死角花样系东西,但有时为了解开它,相信也没少让你烦心过。

Wecallit‘soft’becausewecanchangeitandreshapeiteasily.---MichaelJ.Hicks

从我们学会什么是int什么是long时,老师就教会我们什么时候该用int什么时候适合用long。当我们知道什么是面向对象时,我们就一并了解到了抽象、封装、继承和多态。似乎我们在学习如何编写软件的同时,我们就一直伴随着如何设计软件。

那为什么我们要设计软件?软件设计的最大目标,就是降低复杂性。那什么又叫复杂性?

"Complexityisanythingthatmakessoftwarehardtounderstandortomodify."

---JohnOusterhout《APhilosophyofSoftwareDesign》

译:所谓复杂性,就是任何使得软件难于理解和修改的因素。

面向过程就可以实现所有的软件需求,但我们依然又衍生出了面向对象。软件设计囊括很多,命名、函数、规范、建模、设计模式、设计原则等等,这里我们重点聊一聊设计原则在降低复杂性上是如何表现的。

复杂性来源

斯坦福的Ousterhout教授指出,复杂性的来源主要有两个:代码的含义模糊和互相依赖。

或者我们可以用这2个词来表示Ousterhout教授的理念,那就是createdspread。

复杂性不仅在于它本身复杂,并且还会递增。如果做错了一个决定,导致后面的代码都基于前面的错误实现,只会越来越复杂。

复杂性治理

找出易变化的部分,合理抽象。用抽象构建框架、用实现扩展细节。

SRP单一职责

单一职责原则基于康威定律推论,核心思想是每个软件模块有且只有一个被更改的理由。职责过多,引起它变化的原因就越多,将导致责任依赖增加耦合性

用户信息需要新增“爱好”,UserInfomation负责处理。

数据的信息转换与拼装逻辑,UserAssembler职责所在。

当我们需要调整用户的隐私数据,Privacy能帮到我们。

单一职责让我们在应对变化时更从容,将复杂进行拆解,修改一个功能时,也可以显著降低对其他功能的影响。

但“单一”其实也有着各种各样的争议,何谓“单一”?Privacy.clear叫单一吗,它专门负责隐私数据的去除,但或许隐私数据的去除又分很多种:个人信息、公司信息、行为信息。那我们再分为Privacy.Personal.clear?如同抽象一样,极度抽象=没有抽象。“单一”也要按我们所面临的需求与场景来看,软件工程没有银弹。

OCP开闭原则

对扩展开放,对修改关闭。如果有新的需求和变化可以对现有代码进行扩展,以适应新的情况.而不是对原有代码进行修改。

记得老师给我们上的第一堂课就这么讲过,“软件工程的世界里,不存在没有bug的程序。修复旧bug的同时,就有引入新bug的可能”。“为什么这个会有问题,我这几天都没怎么动它”,我们在日常生活中就有这样的概念,没碰的东西,出问题的概率应该会很小。开闭原则也是如此。

在软件的生命周期内,因为变化,升级和维护等原因需要对软件原有代码进行修改,可能会给旧代码引入错误,也有可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。解决方案就是:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现。

装饰者模式,策略模式等都很好的遵循了开闭原则。开闭原则的核心是通过合理的抽象,利用面向对象的多态特性,来完成对扩展开放,对修改关闭。而何时进行抽象、何时不需要抽象、如何抽象也是一个见仁见智的过程,不存在绝对的方法论。

LSP里氏替换原则

所有引用基类的地方必须能透明地使用其子类的对象。由BarbaraLiskov在年在一次会议上名为“数据的抽象与层次”的演说中首先提出。

有了抽象就一定对应着具象,抽象与具象则是继承与派生的关系。我们知道继承有很多好处,它帮我们提高了代码的复用性,但继承也是侵入的,继承意味着必须拥有父类的所有属性和方法,降低了代码的灵活性,有时会形成对子类的一种约束。不合理的继承与派生关系,不仅没有解决复杂性,反而可能会无端增加新的复杂性。

现在有一个方法birdLetGo,统一处理鸟儿去北京的行为

很明显,这里birdLetGo的代码违反了开闭原则,代码中会充斥着各种instanceof。开闭原则的核心是基于多态、基于抽象,而里氏替换原则保障了这一点“所有引用基类的地方必须能透明地使用其子类的对象”。如果我们不能基于多态来构建我们的架构,那我们将没有架构,而父类此时如果不能安全放心的替换起子类,那我们的多态也将毫无意义。LSP是使OCP成为可能的主要原则之一,正是因为子类的可替换性,才使得父类模块无须修改的情况就得以扩展。

复杂性隔离

说完复杂性治理,我们再谈谈复杂性隔离。既然我们都将复杂性治理了,为什么还存在隔离一说?用户在使用


转载请注明:http://www.ddnhj.com/wazz/10547.html
  • 上一篇文章:
  • 下一篇文章: 没有了
  • 当前时间: