㈠ 设计的分寸
对于设计,还有很多看似"惯常"的法则与经验广泛存在于软件系统中,例如除了经典的23种设计设计模式.还有很多模式之外的模式,按照粒度的大小,系统的特点,规模的大小,而形成的架构规则.
设计的哲学就是对关系的处理,就像人类的复杂关系一样,如何简单明了的处理类与类,模块与模块,层次与层次的关系是设计的精髓所在.
对于设计来说,或许永远没有唯一的答案,你只能无限地接近最好
设计原则是系统设计的灵魂,而设计模式是系统开发的模版,灵活自如的应用才是设计以不变应万变的准则.
设计能力的提升绝非一朝一夕之功,软件开发中的设计大师,往往必须具备多年的修行方可称之"架构师".在设计的广义概念里,几个必需的概念是应该首先被了解和认知的,以排名不分先后的原则罗列,他们大概包括:
⑴面向对象关于面向对象没有必要重复嚼舌.
⑵面向服务.SO至少是个时髦的话题,WCF至少是个时髦的话题,WCF伴着.NET3.5的发布,一个一统江湖的面向服务的基础框架横空出世.可以想象的是,未来的分布式系统架构将变得更加柔性和统一,简单而有效
⑶框架.所谓框架就是应用系统构建所需的基础设施.应用程序是变化万千,而基础架构则是相对稳定.这正是我们基于.NET Framework来实施数以万计的.NET应用:Winforms Form Application ,Web Form Application,XML Web Service等,都体现了框架和应用的关系. .NET Framwork本身就是一个基础性架构,正如经典的MFC一样,提供了.NET应用赖以生存的基础性支持.对于框架的探索和实践,是每个有意提高设计能力的开发者的必经之路.选择一个或者几个经典的框架进行梳理与实践,才能有效地了解软件世界的庞大体系是如何和谐统一的运作.从经典框架设计中,寻找灵感,锻炼体验,例如分享经典案例Petshop三层架构的实践体验,通过真正的需求,设计,开发和测试,而在这个旅程中我们就能完成从概念到实践,从表面到思想的体验.
⑷设计原则.是面向对象设计程序开发的思想大成,了解面向对象,深入设计模式,则有必要深入设计原则之精髓.可以完全不了解全部的设计模式,但必须深入每一个设计原则.一个是内功,一个是招式设计的第一项修炼就从内功开始:面向对象设计原则
⑸设计模式.23个设计模式,23个智慧经典,了解和掌握几个重要的设计模式,是修炼面向对象招式的必经之路.无论如何,作为设计者你应该在自己心中知道什么是Abstract Factory.Iterator.Signleton.Adapter,Decoraor.Observer.Facade.Template.Command.
⑹模式之外,除了23个经典的设计模式,其实还存在很多模式之外的模式,按照粒度的不同而广泛应用在实际的项目系统中.例如,在SOA系统中的Event driven Architecture,Message Bus以及分布式Broker模式:数据持久层的Repository,Active Record还有Identity Map模式;可伸缩系统下的Map/Reduce.Load Balancer以及Result Cache模式;更高架构层面的MVC,MVP以及Pipeline/Filter模式.在某种意义上而言,模式是一种经验的积累和总结,对于系统设计与架构考量,架构师要完成的不仅仅是对功能性需求的把握,还包括非功能的积累和总结,对于系统设计与架构考量,架构师要完成的不仅仅是对功能性需求的把握,还包括非功能性需求,平台与框架的平衡,性能与安全的考量.
其实每个人都是食神,其实开发者都是设计师.关键在于掌勺的你,是否能让做饭的家伙油光锃亮
作为学习者,可能我们还不具备在宏观上把握如何将上述模糊的概念进行统筹和消化,那么作为预备设计师,首先要做好的工作就是逐个认识SOA,Mapper,Pieline,DTO,Message Bus这些概念,有了这些基本功之后再看着唱本骑驴走远.
㈡依赖的哲学
要了解依赖倒置,首先应该回答以下问题:
1.控制反转,依赖导致,依赖注入这些概念,你认识但是否熟悉?
2.Uinity,ObjectBuilder,Cache这些容器,你相识是否相知?
3.面向接口,面向抽象,开放封闭这些思想,你了解但是否了然?
带着以上的问题,重新认识依赖.
什么是依赖和耦合:依赖阐释了耦合本质,而耦合量化了依赖程度
从依赖的角度:
①无依赖,代表没有发生任何联系,所以二者相互独立,互不影响,没有耦合关系.
②单向依赖,关系双方的依赖是单向的,代表了影响的方向也是单向的,其中一个实体发生改变,会对另外的实体产生影响,反之则不然,耦合度不高.
③双向依赖,关系双方的依赖是相互的,影响也是相互的,耦合读较高.
从耦合的角度:
①零耦合:表示两个类没有依赖.
②具体耦合,如果一个类持有另一个类的引用,那么这两个类就发生了具体耦合关系.所以具体耦合发生在具体类之间的依赖,因此具有类的变更将引起对其关联类的影响.
③抽象耦合,发生在具体类和抽象类的依赖,其最大的作用就是通过对抽象的依赖,应用面向对象的多态机制,实现了灵活的扩展性和稳定性.
不同的耦合,代表了依赖程度的差别,以"粒度"为概念来分析其耦合程度.引用中间层来分离耦合,可以使设计更优雅,架构更加富有柔性,但直接的依赖也存在其市场,过度的设计也并非可取之道.因为,效率与性能同样是设计需要考量的因素,过多的不必要分离会增加调用的次数,造成效率浪费.
耦合的分类
1.继承
2.聚合
3.接口
4.方法调用和引用
5.服务调用
知道以上耦合之后,就要知道设计的目标:高内聚,低耦合
低耦合
:代表了实现最简单的依赖关系,尽可能地减少类与类,模块与模块,层次与层次,系统与系统之间的联系.低耦合,体现了人类追求简单操作的理想状态,按照软件开发的基本实现技巧追求软件实体之间的简单化,正是大部分设计模式力图追求的目标;低耦合,降低了一个类或一个模块发生修改对其他类或模块造成的影响,将影响范围简单化.在这里,实现单向的依赖,实现抽象的耦合,都是实现低耦合的基础条件.
高内聚
:一方面代表了职责的统一管理,一方面体现了关系的有效隔离.例如单一职责原则其实归根结底是对功能性的一种指导性体现,将功能紧密联系的职责封装为一个类(或模块),而判断的准则正是基于引起类变化的原因.所以,封装离不开依赖,而抽象离不开变化,二者的概念和本质都是相对而言.因此,高内聚的目标体现了以隔离为目标进行统一管理的思想
因此在设计软件时:
⑴尽可能实现单向依赖
⑵不需要进行数据交换的双方,不要实现多此一举的关联,人们将此形象成为"不要和陌生人说话"
⑶保持内部的封装性,关联的双方不要深入实现细节进行通信,这是保证高内聚的必须条件.
关联应该终止于抽象而不是具体,具体类发生修改,不会影响到其他模块或者关系
如何抽象:简要概括以下几点:
⒈层次清晰化,清晰的层次划分,进而形成的模块话,是实现系统抽象的必经之路.
⒉分散集中化,是一个梳理需求到形成设计的过程,因此对于把握系统中的抽象和具体而言,是一个重要的分析过程和手段.现代软件工程已经对此形成了科学的标准化流程处理逻辑,例如可以借助UML更加清晰地设计流程,分析设计要素,进行标准化沟通和交流.
⒊具体抽象化,将具体问题抽象化,是本节的要点,但怎么处理呢?答案就是在设计模式中.作为软件设计话题中最重量级的话题,关注模式和实践模式是成长的记录.
⒋封装变化点.在变化的地方寻找抽象是面对抽象对理想的方式.