.Net企业级应用架构设计之设计原则和模式

基本设计原则

写出可以正常工作的代码是一回事,写出可以正常工作的良好代码则是另外一回事。一个设计精良的系统并不是一系列指令和修补的堆砌,里面还有很多与设计直接或间接相关的东西。与国际化标准中定义的其他质量特性相比,需要更加重视代码的可维护性,之所以选择这个特性,并不是因为其他特性(例如可扩展性、可伸缩性)和可维护性相比不重要,而是保持代码的可维护性的代价比较高,而且容易让开发者忽视,可维护是系统最关键的问题。

对于可维护性分为两点解析。结构化设计是第一要素,这可以通过一系列的编码技术来保证。代码的可读性是另外一个重要因素,若代码附带了很多内部文档以及适当的变化跟踪系统,那么也不难实现。实际上一个完美系统只会出现在完美的世界中。

对于较差的设计还有需求的不完备。所以很自然的,敏捷开发是提高交流,完备需求最好的方法,敏捷方法可以带来团队内部以及团队和客户之间的持续交流。但是,你也应该小心,敏捷开发方法也会不自觉的增加开发成本,并造成需求的不断增加。在敏捷的过程中,你必须保证流程中的每个人都能理解这么做的原因,项目干系人不了解角色和不配合,或不能在迭代之间总结,敏捷方法是不会成功的。

在设计的过程中,避免把软件设计的过于坚硬。所谓坚硬,就是指对那些修改有较大的抵触的软件。抵触是通过复原能力来衡量的,若某个模块进行了修改,这又引发了你不得不对其依赖模块的修改,就很难预料某个修改所带来的代价。很多时候,我们对于Bug都只是临时的修改,通常而言临时的修改并不会比彻底的解决快速很多,临时的修补也不会给整个设计带来太多难以纠正的不良影响。不过积少成多,这就成了一个不好的信号。这样的设计通常叫高粘度,高粘度不是一件好事,因为意味着软件难以修改,就像黏度高的液体不容易流动。

结构化设计

结构化设计从理念诞生开始,内部隐藏的结构化设计核心原则一直是今天的指导思想,高内聚和低耦合这两个原则在面向对象世界风光无限。内聚的衡量标准从低至高,内聚越高越说明软件设计的越好。高内聚的模块意味着可维护性和可重用性,因为这些模块的外部依赖很少。低内聚的模块容易在其他模块留下依赖,让软件变得顽固坚硬且高粘度。耦合的衡量标准从低到高,耦合越低说明软件设计得越好。高内聚和低耦合唇齿相依,若系统满足了这两个条件,那么通常来说该系统已经基本满足了高可读性,高可维护性,易于测试和易于重用的要求。

分离关注点

我们在设计系统需要考虑内聚和耦合两个因素的时候,分离关注点有助于我们实现这个目标。分离关注点的核心在于将系统拆分成各不相同且最好没有重叠的功能,分离关注点原则建议我们一次只处理一个关注点。这并不代表此时要将所有的其他关注点都抛在脑后,而是说当你决定用某个模块来实现这个关注点之后,只需要全神贯注于实现该模块即可。从这个角度考虑,其他关注点都是不相关的。具体来说,分离关注点是通过模块化代码以及大量运用信息隐藏来实现。模块化编程鼓励我们使用不同的模块来实现不同的功能。模块拥有自己的公开接口,可以和其他模块通信,模块同时也包含大量的内部信息,供自身使用。信息隐藏是一条通用的设计选择,固定的公开接口隐藏软件模块的实现细节,以降低未来修改造成的影响。

其实分离关注点第一种支持的编程理念是过程式编程,在过程式编程中,分离关注点依靠函数和过程来实现。不过分离关注点的概念不仅限于编程语言,它超越了纯粹编程的领域,还应用到了软件架构的很多方面。在面向服务架构SOA中,服务用来表示关注点。分层架构也基于分离关注点的原则构造。

面向对象设计

面向对象的设计可以说是一座里程碑,面向对象设计中的一个重要的步骤就是为问题领域找到一个干净灵活的抽象。若要很好的完成这一步,那么应该考虑的是事情而不是流程。应该关注的于“什么”而不是“如何”。

可重用性是面向对象理念中一个非常重要的方面,也是面向对象广泛使用的根本原因。《设计模式》一书作者总结出了两种实现重用的方式:白盒重用和黑盒重用。前者基于继承,后者基于对象组合。在实际设计中,尽量使用对象组合,而不是类型继承。在现实世界项目中,对象组合更加安全,易于维护和测试,在组合中,修改组合对象并不会影响到内部对象。

除了组合之外,另一种方法也常用来与类型继承比较,就是聚合。组合和聚合之间的区别在于,组合关系中容器和内部类存在静态关联,销毁了容器内部类也会被销毁。而在聚合中,二者关联较弱,即使容器销毁,关键类仍可以使用。

高级原则

在最近几年,上面提到的内聚、低耦、分离关注点等原则有了进一步的演化和增强。下面列举出3条高级原则。

开放封闭原则。能帮助软件中的单元(包括类型、函数或模块)更容易适应变化。每次发生变化时,要通过添加新代码来增强现有类型的行为,而不是修改原有的代码。当前这个原则最好的方式是提供一个固定的接口,然后让可能发生变化的类实现该接口。随后调用者基于该接口操作。

里氏替换原则。当某个类型派生于某个现有类型时,派生类应该能够用于任何可以使用父类的地方,这就是多态。开放封闭原则和里氏替换原则有紧密的关系,任何使用了违反里氏替换原则的类型的方法都无法满足开放封闭原则。

依赖倒置原则。原则名中的"倒置"表示在实现过程中应采用自顶向下的方式,且应该关注于高层次此模块的工作流,而不是低层次的模块具体的实现。从这点考虑,低层次模块可以直接插入到高层次模块中。

从原则到模式

从高处着眼,业界普遍认同的两种软件模式:设计模式和架构模式。在设计、编码时,我们会使用设计模式。而在概括的规划系统的整体设计时,我们会使用架构模式。还有一个值得介绍的模式是重构模式,常见的重构模式包括“抽取接口”和“封装字段”等。

  他们每个模式都描述了一个问题,这个问题在我们的环境中一遍一遍的出现。且模式还给出了这个问题的核心解决方案,这个方案一次次的重用,而无需每次重头开始。一种设计模式就是一个一直且被广泛关注的核心解决方案,适用于解决一类实现过程中可能出现的专门的问题。

但是设计模式不是万能的,不能教条的使用。设计模式也不是超人,不能拯救一个陷入泥潭的项目。设计模式也许会伴你左右,但并不会给你带来额外的能力。设计模式只不过是种有用的东西,仅此而已。使用设计模式最常见的错误是逐一查看每条模式,然后生搬硬套的应用到某个问题上。相反,模式应该反过来使用,针对现有问题,尝试选择一种来解决。使用设计模式并不能在本质上让你的解决方案更有价值,真正的价值在于,在交付的时候你的解决方案是否能正常工作并满足需求。

在得到完整解决方案的过程中,对设计原则的系统化应用会让你或早或晚的来到某个已知的设计模式身边。之所以如此确定,是因为模式就是其他人已经遇到过并加以分类的问题的解决方案。模式并不能为解决方案增加价值,价值在于为架构师或者开发者提供解决方案。

反模式

在物理学中有物质和反物质之分,类似地,在软件中我们用模式组成解决方案,用反模式来组成反解决方案。两者区别在于,模式能让我们得到好的解决方案,反模式则带来不好的解决方案。反模式是一种介绍如何从问题演化到不好的解决方案的模式。反模式的基本原则在于,这些刚开始模式看上去像个不错的设计,能为你的类型添加新的功能或提高效率。而实际上,反模式会让你逐渐走入歧途,带来的麻烦远比好处要多。

设计者和反模式在某种程度上会互相吸引,不过老练的设计者会认出这糖衣炮弹并尽力避免。反模式有很多,下面列举两个。

“将架构作为需求”反模式是指,设计团队中的某个具有影响力的成员执意在项目中使用某个不成熟的技术或者产品,即使尚没有证据表明其作用或其是否适用于上下文。

“将发布作为测试”反模式是指,软件产品发布时并没有太过考虑那些无聊耗时的单元测试或集成测试。用户是产品的最终使用者,因此软件质量就由他们来把关吧。

安全性作为需求

重视安全性是一个远比你想象中更复杂的过程。若工程师不了解基本的安全原则、常见的安全缺陷、基本的安全设计或者安全性测试,那么他们绝对没有可能写出安全的软件。安全性必须从一开始就小心把握,安全的设计始于架构,而不是以后可以补充的东西。安全是由设计决定的,若想处理好安全性问题,应该选用一种关注安全性的开发方法,从而让你在设计系统的时候也时刻牢记安全性。

SDL,安全开发生命周期是微软公司内部使用的一种通过减少安全Bug,从而提高软件安全性的开发流程。SDL实际上是一个迭代的过程,关注于软件过程中的安全方面。 SDL的基石分为3层:分层、组件化和角色。例如,分层会给数据服务器带来好处,将安全性检查放在业务层,让唯一用户数据层访问数据库,在业务组件中使用代码访问安全来阻止非信任代码执行的需要权限的操作。组件化意味着区分需要安全保护的组件,并不代表逻辑上的架构分成一个程序集,对于每个组件,我们都需要确定他们正常运行的最小权限集合。角色是指派给用户一个逻辑属性,角色代表用户在应用程序上下文中的位置,在基于角色的安全模型中,使用伪装用户或委托执行造成的风险可被有效的降低。

一般情况下,我们需要建立一个威胁模型来简化风险。威胁模型一般包含从多个角度检查组件所受的威胁,STRIDE就是威胁模型的实践,其中包含六种类型的威胁。用户身份欺诈;篡改;抵赖;信息泄露;拒绝服务;权限提升。

总的来说,若具体的实现不够强壮安全,那么内建了安全性考虑的设计、良好的安全威胁模型的风险分析就都没有任何意义。

从对象到方面

面向对象理念擅长于将系统分解成组件并且用组件来描述流程,也擅长于处理组件的关注点。不过那些横切的关注点,面向对象却不行。横切关注点是指那些会影响系统多个组件的关注点,例如日志、安全、异常处理等。AOP面向方面主要目的是将横切关注点与核心关注点的实现拆分开。具体面向方面不做太多描述。

相关博客:


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值