框架设计指导方针[翻译]
原文 http://www.codeplex.com/AppArchGuide
本人英语水平较差献丑了 :)
框架设计指导方针
目的
1明白软件架构的概念
2学习软件架构中的关键的设计原则
3学习软件架构中的关键特性
概述
软件体系框架经常被描述为软件系统的结构或是组织,而软件系统就是把各个功能组件整个在一起,完成特定的功能或者一套职能.换句话说,软件架构的重点是把各功能组件组织起来纳入到关注的领域中,如图1.按不同关注领域的应用系统框架。
除了将组件分组,重点考虑的是如何将各个不同部分的组件很好的在一起工作,该指导方针将在第二章告诉你在设计应用程序框架的时候因该考虑的因素。
关键设计原则
这些是当你开始对系统进行设计的时候,需要牢记的重要原则,这些原则将帮助你构建一个最佳的架构设计,最大限度地减少成本和维护要求,并且提高系统的易用性和可扩展性。关键原则如下:
-
关注分离(Separation of Concerns) 打碎你的应用程序使之重叠的功能越少也好。
-
单一责任原则(Single Responsibility Principle) 每一个组件或是模块应该只负责具体的特征或功能
-
最少了解原则(Principle of least knowledge) 一个组件或是对象应该不知道内部其他的细节部分或是对象,也称为法德墨特尔(LoD)
-
不要让自己干重复的工作(Don't Repeat Yourself) 应该只有一个组件提供一个具体的功能,功能不应该重复出现在其他组件中。
-
避免预先设计(Avoid doing a big design upfront) 如果你还没有明确的需求或是可能的设计演变,这种类型的设计通常缩写为"BDUF"
-
组成而不是继承(Prefer Composition over Inheritance) 对于那些可重用的功能更喜欢通过组合来使用而不是继承,继承会增加彼此的依赖。
设计要素
在设计一个应用程序或是系统是,软件架构师的目标是尽可能复杂的事情分开到不同的关注领域,而不应该把代码混合到其他的关注领域。例如,用户界面(UI),业务处理和数据存储都代表不同的关注领域。在每一区域内,你的组件设计应该侧重于这一特定领域,而不应该在这些区域内混合代码。话句话说,用户界面处理组件不应包括直接访问数据源的代码,相反界面处理组件应使用业务组件或是数据访问组件进行数据检索操作。
下面是一个应用程序设计应该遵循的设计准则:
-
避免你所有的预先设计(Avoid all your design upfront) 如果你没有明确需求或是如果有可能会变更,这可能是一个不完整的好主意,也可以随着项目的进行来改变你的设计。
-
切分关注的领域(Separate the areas of concern) 打碎你的应用程序使不同层叠的功能越少越好。主要的好处是,一个功能或特性能否独立于其他的功能,另外一个特点,如果某一个功能失败了,他将不会影响到其他功能,此外,他还可以帮助应用程序更容易理解,更好的管理系统间复杂的相互依赖关系。
-
每个组件或模块应具有单一的责任(Each component or module should have single responsibility) 每个部件或是模块应该只负责某一特定的功能,如果末各特定功能发生变化的时候,能够很好的解决各组件发生的关系。
-
一个组件或是对象不应该依赖其内部的细节或是其他组件对象(A component or an object should not rely on internal details of other components orobjects.) 这样有助于建立一个易于维护和适应性很强的应用程序。
-
在一个应用程序中不要有重复的功能(Do not duplicate functionality within an application) 应该只有一个组件提供一个特定的功能。重复的功能会导致应用程序难以改变,减少不一致性。
-
在应用程序标示每个组件(Identify the kinds of components you will need in your application) 对不用类型的组件进行逻辑分层(Group different types of components into logical layers) 例如,如果你使用数据网关模式,创建一个对象,作为一个数据存取的入口,你就不应该其他的模式中也有这样的数据库查询对象。
-
你不应该在相同逻辑层中混合不用类型的组件(You should not mix different types of components in the same logical layer) 例如,用户界面(UI)层不应该包含业务处理部分,代替用户界面层应该包含部分用于处理用户输入和处理用户请求的处理。
-
强制执行分层(Determine the type of layering you want to enforce) 在严格的分层系统中,A层的组件是不能调用C曾德组件,必须通过B层组件进行通讯,在一个宽松的分层系统中,组件层可以访问其他层,在所有情况下,你应该避免向上调用和依赖。
-
使用抽象实现各层之间的松耦合(Use abstraction to implement loose coupling between layers) 这可以通过定义接口类型或是抽象基类,确定一个公共的接口或是共同的抽象(依赖倒置-Dependency Inversion)
-
不要重载组件的功能(Do not overload the functionality of a component) 例如,一个用户界面处理部分不应该包含数据访问代码。反对使用一个企图提供太多功能基类,有数以百计的功能和业务逻辑混合的功能。最终的结果是一个设计,这是非常容易出错,而且很难维护
-
明白这些组件之间是如何通讯的(Understand how components will communicate with each other) 了解部署的应用程序的情况,确定是否需要跨物理边界的通讯或是在同一个进程中。
-
组合胜于继承(Prefer composition over inheritance) 重复使用的功能尽量通过组合的方式而不是继承的方式使用。
-
在一个层或是组件中保持数据格式的一致性(Keep the data format consistent within a layer or component) 混合数据格式将是应用程序难以实施,扩展和维护。每当你需要将数据从一个格式到另一个你必须进行转化。
-
在业务逻辑的交叉代码中尽可能使用抽象类(Keep cross-cutting code abstracted from the application business logic as much aspossible.)
-
使用一致的命名约定(Be consistent in the naming conventions used.) 如果没有这些标准,你应该建立一个共同的标准,提供一个一致的模式,方便团队成员评估,使应用程序更好的维护。
-
建立标准的异常处理(Establish the standards that should be used for exception handling) 例如:你应该在层的边界去捕获异常,你不应该在业务逻辑中捕获异常,标准的异常处理应该包含日志,检测的策略。