系统架构师的工作是复杂设计总体解决方案以及领域对象的逻辑和物理布局,这是一项在复杂环境中高风险、高影响力的活动。
1、软件架构的定义:软件架构(SoftwareArchitecture)也称之为软件体系结构,它是一组有关如下要素的重要决策:软件系统的组织,构成系统的结构化元素,接口和它们相互协作的行为的选择,结构化元素和行为元素组合成粒度更大的子系统方式的选择,以及指导这一组织(元素及其接口、协作和组合方式)的架构风格的选择。换句话说,软件架构实际上是对系统整体结构设计的刻划,系统架构师是做全局的、整体的把握工作。架构的组成与决策是架构设计的两个基本概念。架构=>蓝图+规则+解决方案
软件架构是一个认识事物的过程:原型、发现、改进、再发现、再改进,这是软件开发的必由螺旋。
要看到自身的弱点,思路要宽,多思考
架构师并不是一个普通的技术人员,他对设计站的角度更高,需要的知识和能力结构更复杂,他需要具有其他人所没有的思想、眼光和感知世界的方法,必须突破已有的思维模式和行为模式,突破长期束缚自己的思维瓶颈,才可能达到自己从未达到过的高度。
架构师要养成每项工作都记录并分析的好习惯,以形成更扎实的工作风格。在每个项目完成都需要进行总结。
知识就是力量==>信息就是力量
架构并不完全是概要设计。概要设计还是停留在图纸上,而架构必须证明这个技术路线可行,并且能够证明大多数质量风险已经得到了解决。
7、抵制前期进行庞大设计的诱惑:(1)、架构应该具备易演化特征;(2)、项目开发周期不要超过6个月;(3)、分而治之:抓住真正的需求、分而治之(把大项目分成小项目)、设置优先级、尽快交付;(4)、增量式开发与交付:如果前期需求比较清楚,可以把一个大项目分成若干相对独立能够持续交付的部分,这样就可以把大问题分成若干小问题;(5)、迭代式开发与交付:如果前期需求不是太清楚,项目带有强烈的创新成分,可以使用具有强迭代的逐步求精的模型。
8、重构:在不影响整体外部行为的前提下,不断地对软件进行细微的设计改进,这种渐进式的实践叫做重构。通过重构不仅能够降低维护成本,而且也为我们提供了改进代码质量的通用标准,并使我们能迅速添加新功能。从本质上说,重构根本上就是一个态度问题,而不全是技术问题。
在集中精力完成了代码逻辑以后,就需要集中精力做第二件事情,那就是重构。在对代码进行重构时,我们不会增加新功能,甚至也不会去修复bug。相反,我们会通过将代码变得更易于理解来提升代码的可读性。
重构要坚持不懈:(1)重构可以加快进度;(2)、重构应该是小步骤地进行;(3)、技术债务积累越多,重构的难度就越大。
9、对结构进行优化的基本原则:在完成了功能逻辑之后,除了代码重构以外,很多情况下还需要重新审视一下软件结构,对结构进行重构。良好的结构设计需要遵循一些原则,而原则本身就是经验的总结。依据这些原则,我们就可以在设计中有良好的设计指向。如需求不变则不需结构。
软件复用(SoftwareReuse):是将已有软件的各种有关知识用于建立新的软件,以缩减软件开发和维护的花费。软件复用是提高软件生产力和质量的一种重要技术。早期的软件复用主要是代码级复用,被复用的知识专指程序,后来扩大到包括领域知识、开发经验、设计决定、体系结构、需求、设计、代码和文档等一切有关方面。
软件重用,是指在两次或多次不同的软件开发过程中重复使用相同或相似软件元素的过程。软件元素包括程序代码、测试用例、设计文档、设计过程、需要分析文档甚至领域知识。通常,可重用的元素也称作软构件,可重用的软构件越大,重用的粒度越大。
11、面向服务的架构(Service-OrientedArchitecture,SOA):面向服务的架构成功的要点是服务识别。服务识别的基本过程:(1)、了解项目的性质;(2)、业务牵头,一定不是技术牵头;(3)、明确产品的战略目标;(4)、研究企业业务流程;(5)、重用行业制品;(6)、建立契约基线;(7)、完善服务属性等级矩阵(ARMS);(8)、使用业务敏捷场景仿真(BASS)进行测试;(9)、拥抱变更。
12、架构与框架的区别:框架是一个软件,但架构不是软件,而是关于软件如何设计的重要决策。但是在引入软件框架以后,软件架构决策往往会体现在框架设计之中。不论是架构技术还是框架技术,都是为了解决软件日益复杂所带来的困难,而采取的“分而治之”的结果。架构的思维是先大局后局部,这是一种问题在抽象层面地解决方案,首先考虑大局而忽略细节。框架的思维是先通用后专用,这是一种半成品,还需要通过后期的定制才能成为具体的软件。
框架和架构的关系可以总结为两个方面:(1)、为了尽早验证架构设计,或者出于支持产品线开发的目的,可以把通用机制甚至整个架构以框架方式实现;(2)、企业可能存在大量可重用框架,这些框架可能已经实现了架构所需的重要机制,或者对某个子系统提供了可扩展的半成品,最终软件架构可以借助这些框架来构造。
框架设计最重要的部分,其实并不在于采用何种技术方案来实现,而是对已经存在的业务过程进行深入思考,寻找它们的共性,探究其中的规律,建立恰当的模式,然后选择恰当的技术实现方案。
带团队关键因素:决心、手段(方法)、激情、信心,技术不是关键因素。
13、把经验归纳总结成理论:总结是两方面的,(1)总结过程:归纳出良好设计必须遵循的步骤,以及每一步骤的目标、解决什么问题、应该有什么样的思考点和思考方向。(2)总结模式(设计模式):模式是一种实践经验的总结,通过总结每个思考点的各种解决方案,并且和过程的节点装配在一起,形成能够指导他人的模式语言。
目前大约有110多种设计模式,模式不是教条,模式仅仅是经验的总结
模式是一种经过命名的对于解决方案的格式化经验总结,它能有效地帮助我们归纳和使用经验。
14、在软件设计中,宏观上看自上而下大致上可以分成三个大的过程域,它包括:顶层架构设计过程域;领域对象设计过程域;资源应用设计过程域,图1。
图1
顶层架构设计过程域的目标是:建立一个系统的概念性架构,为系统描绘一个初始的轮廓,并且对涉及全局的问题进行决策。
领域对象设计过程域的目标是:根据细化的领域对象模型,在细节层面对每一个领域对象进行刻画,并且对于这些细节层面的技术问题进行决策。
资源应用设计过程域的目标是:在宏观和微观两个层面,对于涉及内存、对象、数据等方面的方案和问题进行决策。
为了进一步的细化,在每个过程域内部,又可以包括一系列的过程,(用于解决一个特定的主题和问题,被称之为过程)。这样一来,宏观设计过程就可以分成11组内聚的过程(问题域)。要注意到尽管过程的描述是清晰分离的,但整个软件的设计并不仅仅是自上而下逐步求精的过程,而是相互影响、互相支持、在设计过程中不断优化的不断反馈过程,图2。
图2
设计模式汇总:
DomainModel:定义了一个应用领域结构和工作流的精确模型,其中还包括它们的变化。
Layers:解决系统合理分层的问题。
Model-View-Controller:解决对用户界面变化的支持问题。支持某一特定用户界面的变化。
Presentation-Abstraction-Control:解决相同业务具有多种表现形式问题。
Microkernel:解决业务具有多种不同业务方法的问题。
Refelection:解决需要动态改变软件系统结构和行为的问题。
PipesandFilters:解决算法的结构化并可以重新构建的问题。
SharedRepository:适用于网络管理和控制系统领域。
Blackboard:解决运行中智能化改进处理方法的问题。
DomainObject:表现为已经将自我完备的连贯功能和基础性责任封装成定义良好的实体,通过一个或多个”显示接口”提供功能,并隐藏内部结构和实现。
Messaging:由一系列相互连接的MessageChannel和MessageRouter管理着跨网络的不同服务间的消息交换。
MessageChannel:解决如何把彼此协作的客户端和服务连接起来的问题。
MessageRouter:解决如何根据条件接受”信道”消息的问题。
MessageTranslator:解决如何转换消息格式的问题。
MessageEndpoint:解决把数据转换为消息中间件能够理解的形式的问题。
Broker:通过一个代理管理器管理领域对象间远程互操作的各个关键方面。
ClientProxy:解决客户端应用与网络基础设施相互屏蔽的问题。
Requestor:解决应用代码被基础设施的代码污染而影响可移植性的问题。
Invoker:解决服务代码被基础设施的代码污染而影响可移植性的问题。
ClientRequestHandler:解决客户端应用与通信相互影响的问题,它封装了客户端在统一的接口背后进行的进程间通信的细节。
ServerRequestHandler:解决服务端应用与通信相互影响的问题,封装了服务器端在统一的接口背后进行的进程间通信的细节。
Reactor:解决在应用中避免使用多线程的问题。
Proactor:解决在多线程的背景下出现性能问题的缺陷。
Acceptor-Connector:把事件初始化与具体处理方法分离,从而提高可维护性。
AsynchronousCompletionToken:解决异步到达的事件仍然能按一定顺序处理的问题。
ExplicitInterface:解决如何正确设计接口的问题。
IntrospectiveInterface:解决公开内部信息接口的问题。
DynamicInvocationInterface:解决同一个接口允许客户端调用多种方法的问题。
Proxy:解决在同一个接口下通过代理屏蔽某些实现的问题。
BusinessDelegate:由本地业务代表来完成所有网络任务,分离了应用和网络处理的业务,减少了开发难度、提高了可理解性和可维护性。
Facade:解决屏蔽子系统的变化辐射到高层应用的问题。
CombinedMethod:解决多种相互关联的方法不合理的分布的问题。
Iterator:解决分布式元素能够方便迭代的问题。
EnumerationMethod:解决减少外部迭代方式多次对聚合中的元素进行独立访问开销的问题。
BatchMethod:解决多次访问加大网络开销的问题。
EncapsulatedImplementation:解决对象划分的基本原则和方法问题。
Composite:建立一种结构灵活的树状结构对象组织形式,形成“整体/部分”层级结构。
Half-ObjectplusProtocol:通过在分布式系统中合理布局对象,以减少不合理的网络流量和服务器压力。
ReplicatedComponentGroup:解决分布式系统容错的问题,复制的组件实现位于不同的网络节点,并组成一个组件组。
Half-Sync/Half-Async:对并发系统中的异步和同步服务处理解耦合以简化编程,但又不会过度地影响性能。
Leader/Followers:解决大批量小处理的环境下减少并发线程应用的问题。
ActiveObject:为了减少服务器并发线程应用。
MonitorObject:解决并发业务相互协调的问题。
GuardedSuspension:在并发性程序中,当某个线程对一个资源进行访问的时候,首先需要判断这个资源的警戒条件是否成立。
Future:并发调用的服务可能需要向客户端返回结果。
Thread-SafeInterface:避免自死锁和加锁开销。
ScopedLocking:解决复杂繁琐代码中的疏忽发生漏释放造成死锁的问题。
Thread-SpecificStorage:解决频繁使用对象造成反复加锁解锁造成的性能问题。
CopiedValue:解决共享的值对象必须锁定带来的性能问题。
ImmutableValue:解决共享的值对象必须锁定带来的性能问题。
Observer:定义一个特定的更新接口,通过该接口,Observer获得Subject状态变更的通知。
DoubleDispatch:根据运行时多个对象的类型确定方法调用的过程。
Mediator:封装集合中所有对象的聚合协作行为,从而将这些对象解耦合。
Command:为这些对象定义一个通用接口,来执行它们所代表的请求。
Memento:解决在不破坏封装性的前提下正确存储和读取分布式对象状态的问题。
DataTransferObject:解决细粒度调用多次访问远程对象单个属性所带来的巨大开销问题。
Message:解决网络协议只支持比特流这种最简单的数据传输形式,并不能识别服务调用和数据类型的问题。
Bridge:解决在下层稳定的业务中嵌入上次变化部分的问题。
ObjectAdapter:解决接口变化导致的不兼容问题。
ChainofResponsibility:解决对象结构和请求分发逻辑上的变化影响到客户端的问题。
Interceptor:解决构建一个可插拔的框架变化模型的问题。
Visitor:解决将服务的实现分散在定义对象结构的各个类中难以进行集中处理的问题。
Decorator:解决在稳定的核心功能外围添加扩展的问题。
TemplateMethod:解决在下层稳定的业务中嵌入上次变化部分的问题。
Strategy:解决在一个或多个方法中根据不同的情况执行不同行为的问题。
WrapperFacade:主要解决应用代码使用底层API所提供的服务但代码难以理解的问题,需要对底层API进行面向对象的封装,通过提供一个简洁的、健壮的、可移植的、内聚的面向对象的接口,来达到封装函数和数据的目的。
DeclarativeComponentConfiguration:建立需要安装各类插件的宿主基础设施,使其能够正确管理运行时环境,可靠运用系统资源和服务的问题。
Container:解决领域对象直接处理平台环境造成它与平台紧密耦合并增加实现的复杂性的问题。
ComponentConfigurator:解决在组件生命周期后期和升级时重新配置组件的问题。
ObjectManager:解决客户端依赖对象管理增加应用内部的耦合度和复杂度的问题。
VirtualProxy:解决从一个巨大数据库中把所有的对象全部加载进来消耗大量资源的问题。
ResourcePool:解决获取和释放资源(网络连接、线程或者内容)引入一定的性能开销问题。
ResourceCache:解决几个有限的资源用户频繁创建和释放资源带来不必要的性能开销问题。
AutomatedGarbageCollection:解决不能及时将不再使用的内存收回可能耗尽内存的问题。
CountingHandles:解决确保在堆上创建的共享对象能够可靠地、安全地、及时地回收的问题。
AbstractFactory:解决一批对象用统一的方法进行创建和销毁的问题。
Builder:解决对需要多步完成对象的创建时,简化创建过程的复杂性和多样性问题。
FactoryMethod:解决直接创建对象可能导致代码的混乱并影响调用端代码的独立性问题。
DisposalMethod:解决销毁对象时可能需要多个步骤而引人过度的耦合问题。
DatabaseAccessLayer:它通过在两种之间引人一个映射层将面向对象应用设计同关系型数据库分离开。
DataMapper:解决数据模型和持久化的表结构之间完全的解耦合的问题。
RowDataGateway:解决更细致的数据模型和持久化的表结构之间完全解耦的问题。
TableDataGateway:解决更细致的数据模型和持久化的表结构之间完全解耦的问题。
ActiveRecord:解决降低应用中面向对象数据模型与数据库中表结构之间的耦合的问题。