第二十一章 架构的呐喊

想象一下,你正在看建筑的蓝图。这个由建筑师编写的文档为建筑物提供了计划。这些计划告诉你什么?

如果您正在查看的计划是单户住宅,那么你可能会看到一个正门,一个通往起居室的门厅,或许还有一间餐厅。在靠近餐厅的地方可能会有一个距离不远的厨房。厨房旁边可能有一个扇形区域,可能是靠近那个家庭的房间。当你看着这些计划时,毫无疑问你正在看一个家庭。这个架构会呐喊:“家”。

现在假设你正在看图书馆的架构。你可能会看到一个大门口,一个办理入住/出门办事员的地方,阅读区,小型会议室,以及可以容纳图书馆所有图书的书架的画廊。这个架构会呐喊:“图书馆”。

那么你的应用程序的架构尖叫什么?当您查看顶层目录结构以及最高层软件包中的源文件时,他们是否呐喊“医疗保健系统”或“会计系统”或“库存管理系统”?或者他们呐喊“Rails”,或“Spring/Hibernate”或“ASP”?

建筑的主题

回头阅读Ivar Jacobson关于软件架构的开创性工作:面向对象的软件工程。请注意本书的副标题:一种用例驱动的方法。Jacobson在本书中指出,软件架构是支持系统用例的结构。就像住宅或图书馆的计划对这些建筑的使用情况呐喊一样,软件应用程序的体系结构也应该呐喊应用程序的用例。

架构不是(或不应该是)框架。架构不应该由框架提供。框架是要使用的工具,而不是要符合的架构。如果你的架构是基于框架的,那么它就不能基于你的用例。

架构的目的

良好的架构以用例为中心,以便架构师可以安全地描述支持这些用例的结构,而不必对框架,工具和环境作出承诺。再次考虑一下房子的计划。建筑师最关心的是要确保房子是可用的,而不是确保房子是用砖做成的。事实上,建筑师需要努力确保房主可以在计划确保满足用例之后,对外部材料(砖,石头或雪松)做出决定。

一个好的软件架构可以使关于框架,数据库,Web服务器以及其他环境问题和工具的决定被推迟和延迟。框架是保持开放的选项。一个好的架构使得项目直到后期都不需要决定Rails,Spring,Hibernate,Tomcat或者MySQL。一个好的架构也可以很容易地改变你对这些决定的想法。一个好的架构强调用例,并将它们从外围问题中解耦出来。

那网络是呢?

网络是架构吗?你的系统在网上交付的事实是否决定了你系统的架构?当然不是!Web是一种交付机制,一种IO设备,你的应用程序架构应该如此对待它。你的应用程序通过网络提供的事实是一个细节,不应该主宰您的架构。事实上,你的应用程序将通过网络传递的决定是你应该推迟的。你的系统架构应该尽可能的知道如何交付。你应该能够将其作为控制台应用程序,Web应用程序或复杂客户端应用程序,甚至是Web服务应用程序提供,而不会过分复杂化或更改基础架构。

框架是工具,不是生活的方式

框架可以非常强大,非常有用。框架作者经常深信他们的框架。他们写的关于如何使用框架的例子从一个真正的信徒的角度讲述。其他撰写框架的作者也往往是其真正信仰的门徒。他们向你展示使用框架的方式。通常,它们设想框架处在一个无所不有的、无所不到的、无所不能的位置。

这不是你想要的位置。

用审视的眼睛看每个框架。怀疑地看它。是的,这可能会有所帮助,但有什么付出?问问自己如何使用它,以及如何保护自己。考虑如何保持架构的用例重心。制定一个防止框架接管架构的策略。

可测试架构

如果你的系统架构完全是关于用例的,如果你维持框架在疏远的距离(arm’s length),那么你应该能够在没有任何框架的情况下对所有这些用例进行单元测试。你不需要运行Web服务器来运行你的测试。你不需要连接数据库来运行你的测试。你的实体对象应该是简单的旧对象,它们不依赖于框架或数据库或其他复杂性。你的用例对象应该协调你的实体对象。最后,所有这些都应该在原位进行测试,而没有任何框架的复杂性。

小结

你的架构应该告诉读者这个系统,而不是你系统中使用的框架。如果你正在建立一个医疗保健系统,那么当新来的程序员看到源代码库的时候,他们的第一印象应该是“哦,这是一个健康护理系统”。那些新来的程序员应该能够学习所有的用例系统,但仍然不知道系统如何交付。他们可能会来找你说:
“我们看到一些看起来像模型的东西,但是展示层(views)和控制层(controllers)呢?”
你应该回答:
“哦,我们现在不需要关注那些细节。我们之后再决定。“

results matching ""

    No results matching ""