根据实际情况决定不同类间的耦合度
虽然我们总是希望类间的耦合度比较低,但是我们必须客观的评价耦合度。系统之间不可能总是松耦合的,那样肯定什么也做不了。而我们决定耦合的程度的依据何在呢?简单的说,就是根据需求的稳定性,来决定耦合的程度。对于稳定性高的需求,不容易发生变化的需求,我们完全可以把各类设计成紧耦合的(我们虽然讨论类之间的耦合度,但其实功能块、模块、包之间的耦合度也是一样的),因为这样可以提高效率,而且我们还可以使用一些更好的技术来提高效率或简化代码,例如Java中的内部类技术。可是,如果需求极有可能变化,我们就需要充分的考虑类之间的耦合问题,我们可以想出各种各样的办法来降低耦合程度,但是归纳起来,不外乎增加抽象的层次来隔离不同的类,这个抽象层次可以是具体的类,也可以是接口,或是一组的类(例如Beans)。我们可以借用Java中的一句话来概括降低耦合度的思想:"针对接口编程,而不是针对实现编程。"
设计不同的耦合度有利于实现透明和延展。对于类的客户(调用者)来说,他不需要知道过多的细节(实现),他只关心他感兴趣的(接口)。这样,目标类对客户来说就是一个黑盒子。如果接口是稳定的,那么,实现再怎么扩展,对客户来说也不会有很大的影响。以前那种牵一发而动全身的问题完全可以缓解甚至避免。
其实,我们仔细的观察GOF的23种设计模式,没有一种模式的思路不是从增加抽象层次入手来解决问题的。同样,我们去观察Java源码的时候,我们也可以发现,Java源码中存在着大量的抽象层次,初看之下,它们什么都不干,但是它们对系统的设计起着重大的作用。
够用就好
我们在上一章中就谈过敏捷方法很看重刚好够用的问题,现在我们结合架构设计来看:在同样都能够满足需要的情况下,一项复杂的设计和一项简单的设计,哪一个更好。从敏捷的观点来看,一定是后者。因为目前的需求只有10项,而你的设计能够满足100项的需求,只能说这是种浪费。你在设计时完全没有考虑成本问题,不考虑成本问题,你就是对开发组织的不负责,对客户的不负责。
应用模式
这篇文章的写作思路很多来源于对模式的研究。因此,文章中到处都可以看到模式思想的影子。模式是一种整理、传播思想的非常优秀的途径,我们可以通过模式的方式学习他人的经验。一个好的模式代表了某个问题研究的成果,因此我们把模式应用在架构设计上,能够大大增强架构的稳定性。
抽象
架构的本质在于其抽象性。它包括两个方面的抽象:业务抽象和技术抽象。架构是现实世界的一个模型,所以我们首先需要对现实世界有一个很深的了解,然后我们还要能够熟练的应用技术来实现现实世界到模型的映射。因此,我们在对业务或技术理解不够深入的情况下,就很难设计出好的架构。当然,这时候我们发现一个问题:怎样才能算是理解足够深入呢。我认为这没有一个绝对的准则。
一次,一位朋友问我:他现在做的系统有很大的变化,原先设计的工作流架构不能满足现在的要求。他很希望能够设计出足够好的工作流架构,以适应不同的变化。但是他发现这样做无异于重新开发一个lotus notes。我听了他的疑问之后觉得有两点问题:
首先,他的开发团队中并没有工作流领域的专家。他的客户虽然了解自己的工作流程,但是缺乏足够的理论知识把工作流提到抽象的地步。显然,他本身虽然有技术方面的才能,但就工作流业务本身,他也没有足够的经验。所以,设计出象notes那样的系统的前提条件并不存在。
其次,开发一个工作流系统的目的是什么。原先的工作流系统运作的不好,其原因是有变化发生。因此才有改进工作流系统的动机出现。可是,毕竟notes是为了满足世界上所有的工作流系统而开发的,他目前的应用肯定达不到这个层次。
因此,虽然做不到最优的业务抽象,但是我们完全可以在特定目的下,特定范围内做到最优的业务抽象。比如说,我们工作流可能的变化是工组流路径的变化。我们就完全可以把工作流的路径做一个抽象,设计一个可以动态改变路径的工作流架构。
有些时候,我们虽然在技术上和业务上都有所欠缺,没有办法设计出好的架构。但是我们完全可以借鉴他人的经验,看看类似的问题别人是如何解决的。这就是我们前面提到的模式。我们不要把模式看成是一个硬性的解决方法,它只是一种解决问题的思路。Martin Fowler曾说:"模式和业务组件的区别就在于模式会引发你的思考。"
在《分析模式》一书中,Martin Fowler提到了分析和设计的区别。分析并不仅仅只是用用例列出所有的需求,分析还应该深入到表面需求的的背后,以得到关于问题本质的Mental Model。然后,他引出了概念模型的概念。概念模型就类似于我们在讨论的抽象。Martin Fowler提到了一个有趣的例子,如果要开发一套软件来模拟桌球游戏,那么,用用例来描述各种的需求,可能会导致大量的运动轨迹的出现。如果你没有了解表面现象之后隐藏的运动定律的本质,你可能永远无法开发出这样一个系统。
关于架构和抽象的问题,在后面的文章中有一个测量模式的案例可以很形象的说明这个问题。
架构的一些误解
我们花了一些篇幅来介绍架构的一些知识。现在回到我们的另一个主题上来。对于一个敏捷开发过程,架构意味着什么,我们该如何面对架构。这里我们首先要澄清一些误解:
文章来源于领测软件测试网 https://www.ltesting.net/