如何才能真正的提高自己,成为一名出色的架构师?

想成为一个出色的架构师,但是学得知识不是很系统。 目前属于自学,设计模式,算法导论,编译原理,UML2.0等都在看。 自学可想而知,肯定不够系统,不够…
关注者
2,958
被浏览
281,465

68 个回答

架构师是一个充满挑战的职业,知识面的宽窄往往决定着一个架构师的架构能力,所以在这一点上我比较赞成你的学习方式,就是要阅读大量的技术书籍,但我希望你不要仅限于软件相关的书籍,经常泡技术论坛,一方面可以结交朋友,一方面可以增加自己的知识面。

公司的大小往往决定了所做的项目规模,一般的大项目不太可能直接总包给小公司去做,但这并不妨碍小公司可以分包到大项目的一部分。在做小项目的同时也可以积累丰富的经验,我自己就是一个这样的例子。

我在小公司混迹了5年多,其中也偶尔有1两个大公司,比如大唐电信,但是基本上都是小公司,从基层的程序要到公司的开发总监都做过,甚至自己还设计过包括LED显示屏,密码键盘在内的收费系统,自己联系厂家OEM,当然这些今天已经广泛应用了,当时我们的客户用上之后还是非常震撼的。

知识面的宽广对于一名出色的架构师来说是必不可少的技能,也许很多人对架构的理解还停留在设计模式,重构,SOA等等的软件层面,然而这仅仅是非常基本的东西,架构师的脑子里不光需要知道让软件如何高效的运行,还需要知道如何去结合网络,存储,甚至一些文件系统的特性,比如GFS,NFS,XFS,NTFS等等,而且架构师还需要知道一些编程语言的特性,C,C++,Java,PHP,Python,Lisp,JS等等,现在是一个混合编程的时代,只了解一种语言,即使再精通也会使你在架构系统的时候受到很大的局限性。

再有一点,架构师需要对数据库技术有深刻的认识,因为现今是一个信息时代,大量的信息都是需要存储并检索的,数据库设计的不好,将会严重影响系统的性能,而这一点往往会被我们的设计人员忽略,他们只知道遵守那些范式而不会结合数据的特性去设计数据库。

看你的编程情况,你好像做PHP开发比较多,PHP比较适合B/S结构的应用开发,这会限制一个架构师的思路,我建议你再学习一门适合做C/S开发的语言,拓宽自己的视野。

从一个程序员到架构师是一个很大的变化,架构师需要从大的方面考虑,而不只是考虑这个模块该用哪种设计模式去开发。不能急于求成,也许是我自己变化的比较慢,我用了10年的时间,这10年里,我使用超过一年的编程语言包括了delphi,C++,Java,python,使用的数据库包括了oracle,infomix,sybase,sqlserver,mysql,javadb,sqlite等等,使用过大型机,小型机,服务器。unix,linux,windows都至少做过两年以上的开发,这些使用和开发的经历会大大增强一个人在做架构师这个职业时的技术素养。

总之,想要成为架构师,需要有耐心,不断学习,拓宽自己的视野,不仅仅局限于自己眼前的项目,关注开源技术,关注热门技术社区的新动向。

06年写的如何循序渐进向dotnet架构师发展,可参考:


微软的DotNet开发绝对是属于那种入门容易提高难的技术。而要能够成为DotNet架构师没有三年或更长时间的编码积累基本上是不可能的。特别是在大 型软件项目中,架构师是项目核心成员,承上启下,因此RUP方法论也认同以架构为核心,体现4+1视图在整个软件开发过程中的重要作用。架构人员既要精通 技术,又要熟悉业务,而且基本对软件生命周期各阶段的相关技术都需要有相关的积累和知识储备,而这些不经过多年的磨练是很难达到这个高度的。

要成为一个合格的架构师首先必须是一个合格或优秀的编码人员,对于开发来讲编码始终都是最重要的一项技能,在编码过程中只要自己善于去思考和分析问题,就 可以多学到很多相关的知识和技术。所以我们在开发过程中一定要注意新知识和新技术的学习,前人经验和成果的学习。编码过程中应该去思考的一些问题有:

1.在编码过程中自己是否做单元测试,是否使用相关工具做单元测试,如果没有的话是什么原因无法把单元测试做起来?

2.自己编码的泄露率情况,编码泄露的BUG的原因分析

3.是否有意识的对代码进行重构,重构过程中是否引入了相关设计模式的思想?

4.是否对C#语言的一些高级特性进行学习,如反射调用,异步处理等。

5.是否对Remoting和WebService两种分布式技术做过研究和对比分析?

6.是否经常研究开源项目和开源代码,如Duwamish,PetShop,NUnit,Enterprise Library,Nant等

7.是否对对象持久化机制和O/R Mapping等相关技术做过相关的研究

8.平时在编码过程中是否注重公用组件和公用类的复用和抽取

9.自己在平时工作和学习中是否经常开发些小工具提高工作效率,巩固学习知识

设计和编码其实是密切而不可分的,对于严格将设计和编码分开的瀑布模型一般也仅仅在大型项目中应用。而及时编码和设计分离,也不是将编码人员不需要思考, 编码活动始终是一项创造性的劳动,如果否定这个观点那就代表编码过程完全不需要人员介入而可以完全自动化。因此在这里谈设计主要还是指设计人员的系统化思 维能力,设计人员应该比开发人员站高一个层次来分析和思考问题。设计人员最重要的一个技能就是现实->抽象的转换,而这个就需要谈到方法论的问题 了,技术人员需要积累面对对象分析和设计或结构化分析知识的积累,需要有较强的数据库分析和设计能力。一个设计能否成为很好的架构师关键就在这种积累的深 度和广度上面了。

因此在设计过程中应该考虑的问题有:

1.你现在分析和设计能力能否胜任大中型的应用系统还是只是独立功能分析和设计?

2.设计过程中是否有意识的考虑到组件的复用和相关接口设计准则。是否能够很自然的将分析模式,设计模式的相关内容应用到自己的设计过程中。

3.是否对XP,RUP,面向对象,结构化等方法论都有过较系统化的学习和思考。

4.是否真正理解系统功能需求和非功能需求对系统设计的不同的指导作用。

5.对自己设计的功能是否会根据后期的变更来反思自己的设计为何不能很好的适应变更?

6.是否在设计过程中经常自己开发些原型来对自己的设计思路进行验证?

7.是否专注技术的同时开始专业业务流程的分析,关注业务建模?

如果我们在设计和开发过程中经常关注这些知识和技能的话,成为一个合格的架构师是早晚的事情。平时能够胜任工作开发用到的知识和技能是微不足道的,如果自 己不是有意识的去学习这些知识的话,那技能是很难得到进一步提高的。我参加过两次微软的架构师培训,在北京的微软架构峰会上也有机会专门参加了 P&P Workshop的学习,培训老师是微软总部SmartClient Architecture and Design Guide一书的作者Edward A.Jezieski,让我感受最深是老外深刻的技术底蕴,对程序开发的执著。

对于DotNet架构经常用到的知识和技能储备有

1.RUP方法论,4+1视图。用例驱动业务建模->分析模型->设计模型

2.用例模式->分析模式->设计模式

3.常用的分布式技术

4.对安全,异常,日志,性能等非功能性需求的关注

5.对应用系统整体业务的关注

相关的一些参考书籍(微软网站和电驴都可以下载到)

微软网站提供的参考书籍

Enterprise Solution Patterns Using Microsoft .NET

.NET Data AccessArchitecture Guide

Application Architecture for .NET:Designing Applications and Services

Caching Architecture Guide for .NET Framework Applications

Designing Application-Managed Authorization

Smart Client Architecture and Design Guide

其它架构方面的参考书籍

Software Architecture In Practice

Pattern-Oriented Software Architecture

The Art Of Software Architecture

Beyond Software Architecture

模式方面的书籍

Analysis Patterns

Design Patterns - Elements of Reusable Object-Oriented Software

Applying UML and Patterns

Design Patterns Explained

===================================================

2015年8月,增加架构设计和概要设计的区别

架构设计

架构设计包括了功能性架构和技术架构设计两个部分的内容,功能性架构解决业务流程和功能问题,而技术架构解决非功能性需求等问题。两种架构都包括了动态和静态两个方面的内容,对于功能性架构中动态部分为业务流程驱动全局用例,用例驱动的用例实现等;对于技术架构中动态部分为架构运行机制,而静态部分为框架,分层等方面的内容。

功能性架构包括了全局用例设计,这个本身是用例分析和设计的一个延续,而全局用例分析建议的思路仍然是业务流程,业务用例建模到系统用例建模的过程。全局用例分析清楚后可以开始考虑子系统和模块的划分,形成系统的功能架构图,当然在划分过程中一定要考虑到通过CRUD矩阵等分析方法来分析模块如何划分合理,如何保证模块本身高内聚和松耦合。

在全局用例分析完成后涉及到数据模型的设计,数据建模仍然从业务驱动,从最初的业务对象和单据入手,到最终的数据概念模型和逻辑模型等。架构设计中全局数据模型不一定覆盖所有的数据对象和数据表;但是核心的主数据,核心业务单据数据一定要覆盖到,模型到的层次到逻辑模型即可。如果用面向对象的分析方法,这里需要出的是UML建模中的概念模型和逻辑模型,体现核心对象和类,核心对象和类之间的关系。

将全局用例分析和数据模型建立融合在一起,可以看到这两者结合起来会形成一个系统完成的领域模型层。一直认为领域模型思路应该引入架构设计,只有领域模型才是真正关注功能性架构,而不用马上关注到具体的技术分层和技术实现。

前面两者做完后可以看到一个大系统被分解为了多个子系统或模块,那么接着要考虑的就是模块间的集成架构,分析完集成架构模块间的接口基本就出来了。接口设计应该是架构设计的另外一个核心内容。要明白架构设计一个重要作用就是架构设计完成后各个模块可以并行开始概要设计,详细设计和开发工作。只要大家都遵循架构设计约定的接口规则即可以了。

集成架构考虑完另外一个核心内容就是公共可复用组件的抽取和识别,包括了功能组件和技术组件,需要识别出来哪些是可复用的,如何进行复用。对于复用层次本身又包括了数据层复用,逻辑层组件复用,界面层UI组件的复用等。复用是架构价值体现的的另外一个关键点。

这些都做完后,接着一个步骤应该在架构设计阶段做的就是对架构输出成功进行模拟验证,前面完成了分解动作,必须通过模拟验证来看看后续分解内容能否很好的集成和组装。很多时候我们做架构设计的时候往往不做这块内容,导致架构设计一些内容变成空中楼阁,无法落地。

再回来看技术架构设计,首先谈下静态部分的内容。这里面就包括了软件开发的分层架构,开发框架等内容,包括开发规范约定,技术平台和语言的选择,使用的规约等都需要考虑。很多时候我们看到谈架构的时候说到的三层或多层架构,仅仅是完整架构设计里面很小的一部分内容。

除了分层架构外,接着考虑的就是各种非功能性需要,我们在架构上需要如何设计。这里面包括了事务,缓存,异常,日志,安全,性能,可用性,容错能力等。这些逐个点都要在架构设计中说清楚如何考虑,由于这些本身就属于一个应用系统中技术平台要考虑的内容,因此应该设计为较为公用的技术组件供上层的业务组件使用。要明白很多时候为何谈到AOP或可插拔架构,只有这样去考虑问题,才会考虑真正的功能性架构设计和功能实现和非功能性技术架构这块充分解耦,实现进一步的灵活装配。

再回到架构设计视图层面,还需要考虑的就是整个应用系统的部署架构,部署架构本身也包括了逻辑视图和物理视图,应用最终开发出来了如何进行部署,这涉及到了IT基础架构方面的细化,也需要考虑清楚。

概要设计

概要设计首先要明白的是根据架构设计的内容进一步对某个模块的设计进一步细化。架构设计在系统级,而概要设计在子系统或模块级。拿建筑来比喻,架构设计是把一个建筑的框架结构全部定清楚,包括地基要挖多深,核心框架和承重结构如何,每一层的结构图如何,应该分为几个大套间这些内容都应该定下来。每个大套间的水,电,气等管道接入点在哪里等。而概要设计要做的是拿着一个套间,来考虑这个套间内部该如何设计,如何划分功能区域,如何将水电气接入点进一步在房间内延伸,哪些地方需要进一步增加非承重的隔断等。

基于以上思路我们看到在架构设计的时候,除了很少部分的核心用例我们会谈到具体的用例实现完,大多数功能我们都不会谈到具体的用例实现层面。而到了概要设计则需要进一步的分解我这块模块究竟需要实现哪些功能点,具体的每个功能点究竟如何实现都必须要考虑到。

严格的概要设计,我们希望是到了概要设计的某个功能模块,模块所涉及到的核心的类全部会出来,类关系图全部会出来。数据库设计也进一步细化到该模块的数据库物理模型。对于用例进行用例实现分析,在实现分析过程中可以看到每个类核心的public方法全部会分析识别出来。

拿着架构设计的接口,概要设计也需要进一步细化,细化出接口具体的输入输出和使用方法,包括模块应该使用哪些外部接口,模块本身又提供哪些接口出去都必须细化清楚。做概要设计的时候一定要清楚当前做的这个模块在整个应用系统架构中的位置,和外部的集成和交互点。

概要设计不用到详细设计这么细化,包括类里面的私有方法,public方法的具体实现步骤和逻辑,伪代码等。但是我们要看到概要设计里面对于核心的业务逻辑必须要设计清楚如何实现,实现的机制和方法。很多时候我们到了概要设计画uml的时序图,很多时候一看没有任何意义,全是跨层的简单的交互和调用。这个应该在架构设计的架构运行机制说清楚即可。设计到多个业务类间的交互调用才是重点,一个简单的功能增删改查,完全没有必要画什么时序图。

其次架构设计中给出了各种安全,性能,缓存的设计。那么在概要设计中出来另外一个问题,即架构给出的各种实现方案和技术,我们在概要设计中如何选择,如何使用。不是所有功能都需要缓存,那就要说清楚哪些功能根据分析需要缓存,需要缓存哪些对象,缓存本身的时效性如何设置等问题。

概要设计作为我们要达到一个目的,就是不论是谁拿走概要设计来做,最终实现出来的功能模块不会走样,功能模块最终实现出来可能有性能,易用性等方面的问题,但是整个功能实现的大框架一定是定了的。

============================================================

2015-10月更新,架构思考

组件划分和服务接口

组件化开发思路在很早以前就已经提出,只是当时的组件间交互更多的谈接口而非服务,同时也没太关心单个组件本身的全生命周期管理。谈组件的时候一定不要先谈开发和技术框架,而是真正从业务架构和应用架构出发去考虑整个业务系统的组件划分,其中包括了业务组件和技术组件,各自应该暴露业务和技术服务能力。业务能力组件化和组件能力服务化也是一直强调的SOA核心思想。

在组件划分清楚后,需要优先考虑组件间的交互而需要暴露出来的服务接口,即组件之间只能通过服务进行协同以进一步实现组件间的松耦合。其次才是考虑单个组件在实现的时候,结合分层开发技术框架涉及到分层,在这里可以进一步参考领域模型驱动和设计的思路,否则很容易实现为数据库表驱动功能而不关心领域模型设计和领域逻辑的实现,即虽然技术框架分层了但是职责不清,逻辑混乱并多处实现。

组件内部的实现一个重点就是应用层和领域层之间的关系,即在应用和领域层之间增加了一个服务层,服务层重点是服务接口和服务的组合等工作,而具体业务规则和数据处理的逻辑在仓储类和规则类里面来实现。注意对于组件内部应用层和领域层交互的服务并不一定要做为分布式的Service服务,也可以直接使用内部的API服务接口即可。将服务层服务接口具体的逻辑实现分离的一个重点就是在后期很容易将服务接口发布为一个供其它组件远程调用的服务方法。

开源组件和技术

对于单一的技术往往很难满足互联网业务场景下不同的功能需求和非功能性需求,对于不同的功能或技术实现往往都需要选择大量的开源组件或技术进行集成。但是这些独立的技术组件如何集成为一个高效的整体就变得相当重要。任何技术的选择都必须为了业务需求服务,模式分析是选择技术的一个重点,即在什么样的业务场景下,面对什么问题我们究竟应该选择什么样的开源技术来实现最合适。

首先是开发技术框架层面的,即常说的基于MVC模式的多层框架,用的最多的估计还是SSH框架,其中在数据库层面又有Hibernate或iBatis多种实现,在控制层本身又有struts和spring mvc多种实现。在展现层相关的技术点更多,包括了一些前端基于javascript和jquery的框架引入,Ajax实现,包括当前互联网各种前端响应式框架,Html5技术等。技术框架的选择看似和业务无关,但是却需要进行业务场景分析,包括当前开发的应用是否需要同时支撑web端和移动app端,是否存在和外部集成和服务接口暴露,在业务交互和易用性层面有哪些要求,这些都需要考虑进去。

其次是实现核心技术能力的技术组件,其中包括了缓存,消息,流程引擎,搜索,安全,任务,日志等诸多内容,这些当前往往都有现成比较成熟的开源技术来实现。如通过memcached或redis来实现缓存,通过rabbitMQ或zeroMQ来实现消息和事件管理,基于lucence的全文检索引擎,开源的ETL技术实现数据集成,开源的jbpm流程集成等。在选择这些技术的时候要注意和前面整体技术框架的集成,技术组件应该保持其高内聚和独立性,仅仅技术组件的能力通过服务暴露出去实现和上层应用的集成。要做到这一点往往就需要对开源组件进一步进行封装和定制,以和技术框架形成一个完整的整体,同时又不要把底层技术组件的复杂度暴露给业务功能的开发过程中。还有就是互联网应用还涉及到外部技术服务能力的引入,如外部的邮件通知服务能力,地图能力,支付能力,各个外部开放平台开发的各种内容提供服务能力引入等。对于外部服务能力的引入建议是要在技术平台层单独进行管理和封装,即在技术能力层有独立和统一的服务代理。

最后是数据库和持久化层,包括常见的关系数据库,半结构化和基于key-value的redis,mongoDB等数据库,还有就是完全基于hdfs的非结构化文件存储能力。对于不同的业务场景和业务对象,往往需要底层不同的数据和存储能力进行支撑,如何形成一个完整能力的数据库服务能力层是架构设计时候需要考虑的。

去IOE化

对于去IOE化是这两年互联网架构设计谈得最多的问题,即去掉小型机,集中存储和商用数据库。如果简单来说下去IOE化的核心就是基于开源的类似Mysql数据库和集群技术,通过X86服务器硬件资源来实现和原来使用IOE架构时候同样的性能和高可用性。在之前淘宝有开源的corba基于mysql数据库来实现分布式数据库和集群,现在有开源的MyCat来实现,核心就是提供一个DaaS服务层和封装,来实现高性能和高可用的数据库中间件产品。

对于去IOE的热度在当前已经有所下降,这里面有两个原因一个是本身技术成熟度和CAP原则约束,一个方面的原因就是在去IOE和引入DaaS数据库中间件后本身是增加了架构复杂度和应用开发难度。一个方面是由于DaaS层引入导入的分布式事务问题和对于跨库查询和Sql语句本身的约束增加。一个是在架构设计中就需要考虑前端业务如何进行组件化,业务对于的数据存储如何进行分区和分片,究竟如何进行水平拆分和垂直拆分。

可以讲在架构设计中的去IOE设计和前面讲到的组件化和服务化设计思路密不可分,同时在去IOE下的组件化是彻底的组件化,即组件本身对应的数据库也是独立的,组件可以拥有完全独立的硬件资源和全生命周期管理。因此如果组件没有划分,在后期业务功能实现中就可能导致大量的跨库操作和分布式事务问题。这些都应该在架构设计阶段就思考清楚并制定清晰的架构设计约束,任何架构设计都不会有普适性的通用架构存在,架构约束定义是一个架构要发挥其高效能力的关键。

去中心化

首先来看一个最简单的场景,即客户和请求端是A,服务提供端是B,对于服务提供端已经实现为了分布式集群即(B1,B2,B3...Bn),在这种场景下可以看到对于请求会转发不同的集群节点进行处理。但是对于这种分布式架构来看,集群是可以完全平滑弹性扩展的,但是问题关键点在于A的请求究竟应该转发到哪个B节点去处理,这里面就有一个控制层或管理节点,而对于大多数分布式应用来讲管理节点本身是很难集群化扩展的。及时当前很多分布式架构实现过程中已经实现了消息请求和数据传输的分离,但是仍然存在对于管理节点无法水平扩展的问题。

对于水平弹性扩展问题的解决,往往会引入集群技术和硬件负载均衡,但是这不是一个完全意义上的去中心化架构,当前我们说的去中心化架构都是没有统一的管理节点,完全分布式,只有在这种架构下才是完全的去中心化。要做到去中心化就涉及到几个关键点的引入,一个是请求通过sdk包在客户端的植入进行前移,即客户端发起请求的时候就已经判断清楚;其次是对于管理职责后移,即管理端后续重点是从各个集群节点准实时采集数据再进行分析。要实现第二点往往又涉及到高性能的消息中间件的引入。