架构设计系列文章,请参见连接。
想成为架构师或者已经是架构师的同学有没有问过自己一个问题:为什么你是架构师?其实就是问问自己为什么想成为架构师,是不是真的是一个架构师?架构师只是一个称呼,并不是你拥有了这个称呼就是架构师了。最主要的问题还是架构师和其他岗位同事的思维模式是有质的区别的。
很多公司为了职级的完整性而定义的架构师,技术专家到底是不是同一个概念?在某些时候授予了一些人,做了一些事可以认为他们就是架构师了吗?我们这里讨论和追逐的真理是你自己本身认为你是个架构师,而不是外部的授予。
本文主要从几个方面为什么你是架构师:
架构师不是框架师、不是算法工程师、不是高级程序员、不是项目经理。架构师与这些岗位的同事有着很多共同点,导致很多在软件行业从业多年的人都分不清他们之间的区别。本文从不同点出发说明架构师的特点。
框架和架构的区别大家都是知道的,可以说框架也是有架构的。并且框架的问题域中有一个问题是怎么解决业务软件开发过程中的架构问题。所以说,框架影响着架构但框架并不是架构。因为架构中除了框架外还有中间件、组件需要由架构师来处理,描述框架、中间件、组件等之间的关系是架构设计过程中技术选型内的一部分。
对框架的架构进行设计与演进也是架构师的工作,就现在来说软件开发基础设施的开发团队很少,并且软件框架的架构设计技术了解的人也很少。所以,可以认为框架只不过是一种特殊的软件,它解决的是软件开发与运行阶段的问题。
可以说对于架构师来说,框架只不过是一种特殊的软件,就看要实现的软件是框架、中间件、组件还是业务软件根据软件所处领域的不同进行针对这个领域中的问题进行分析和解决即可。
随着软件系统规模的增加,计算相关的算法和数据结构不再构成主要的设计问题;当系统由许多部分组成时,整个系统的组织,也就是所说的“软件架构”,导致了一系列新的设计问题。
--《An Introduction to Software Architecture》卡内基·梅隆大学的 Mary Shaw 和 David Garlan,1994 年
在我之前的文章中架构设计00-架构师知识体系10-对软件认知层次的思考中有详细的说明代码是由数据结构和算法组成的,在代码之上还有程序、软件、系统、平台、企业架构这几个层次。所以,算法是组成软件系统不可或缺的内容,但算法在软件系统中绝对不是主角。
根据上面mary和david所描述的由于软件规模在不断的扩大,架构更多的工作用来解决规模问题。而不是算法和数据结构问题。
架构设计的关键思维是判断和取舍, 程序设计的关键思维是逻辑和实现。很多程序员在转变为架构师后,很难一开始就意识到这个差异,还是按照写代码的方式去思考架构,这样会导致很多困惑。--李运华《从零开始学架构:照着做,你也能成为架构师》
架构设计与软件编程一样,有很多中模式、方法。具体使用那种模式、方法进行实施工作并不是确定的,这样就会有优化的架构和粗陋的架构,优秀的代码和低劣的代码之分。而对于架构师来说设计模式、架构模式、架构风格在实践中的运用就成为了判断架构师能力的最基本方法。优秀的架构师可以让这些有机的结合并高效的解决问题。而高级开发能写清楚设计模式已经很不错了。造成这个的区别就在于决策方式与过程的不同。
项目经理的职责是让软件能够在有限的资源与时间的情况下保质保量的交付。而架构师为这个过程提供技术支持让软件能够平顺的落地。所以架构师必须懂软件过程过程管理,但并不是实际操作这部分内容。
很多架构师都是运维出身的,这是不争的事实。不过像架构师不是高级开发一样,运维工程师成为架构师之后也需要思维上的转变。需要从原先的以系统稳定、系统性能、系统安全而努力,转变为整个系统支撑、提供可行的解决方案。
明确了哪些不是架构师,这里再说明哪些是架构师应该持有的理念。作为架构师实际的、落地的工作是很重要的,但应该要想清楚在实际的设计与落地过程中我们为什么这样做。应该抱着怎样的理念去推进我们的工作。
软件架构设计的最终目标就是跨越业务需求与软件实现之间的鸿沟,而在跨域这个鸿沟需要做的就很多。需要想尽一切办法满足业务与非功能需求的同时,还要让实现团队能够接受设计中的复杂度,以实际可行的方式设计出架构实现路径才能有益的沟通业务团队与技术团队。
就像之前评价一个公司的层次一样:有理想、有目标、有原则、有方法,理解清楚通过具体化的目标来实现定位中的内容这样层次递进的方式来逐步的细化来提高可行性。
通过适度设计来制定更加贴近实施过程的设计,并尽量的做到以推迟决策,快速决策的方式推进实施工作。以控制复杂度来理清业务与技术的复杂度,并以合理有效的方式解决实现过程中的复杂度。做软件研发只有一个目标就是提供有价值的软件,而有价值的软件就必须从架构的角度服务软件研发过程。
只有细节没有整体,只有整体没有细节的。并不能很好的说明你是一个架构师的思维方式。以《金字塔原理》的方式来系统的认识一个软件需求才能做出有效的决策。
解决问题必须要明确问题,批判思维中有很多深入挖掘问题并分析问题的方法。在定义好问题空间之后,对于问题空间的解决办法就如《恰如其分的软件架构》中所给出的解决方案:
技术人员对于新技术的都有着一种与身俱来的激情,总是乐于去学习新技术,同时也更有激情去使用新技术。但是这也同样容易导致一个通病,就是“当我们有一个锤子的时候看什么都是钉子”,使用一些不适合的技术去解决手边的问题,常常会导致简单问题复杂化。
技术只是解决域中的解决工具而已,在针对不同的业务问题选择不同解决工具是架构师的基本能力。很多时候这个问题都会被导致,有什么样的技术可以解决我现在与到的问题,如果解决不了业务问题就不实现了。这其实是一个知识陷阱,从开发转为架构师时一个很重要的问题就是超越这个问题并解决这个问题。
作为中层来说并不是简单的执行命令就可以成为一个好的架构师,需要有自己的决策过程与决策方法。并在决策和解决问题这两个能力上保持有有效可实现的方法。
使用金字塔原理 + DDD + 分解/抽象/知识可以解决问题,再配合例如:SMART、PDCA、SWOT、5W2H等方法来分析问题就可以将分析到解决了。但是决策并不是一件容易的事,我在做决策是一般的流程如下:
这个过程就需要根据团队的情况、业务的情况、技术的情况等进行问题list的制定并解答。来进行决策,问题例如:
做了架构设计之后要能将架构落地,落地了才是好架构。所以,在落地过程中需要保证实现的内容是按照设计走,并且能够很好的按照实现路径进行实现。在这里经常与到的两个问题:
对上要有目标与过程,对下要有逻辑与实现。这样才可以落地软件目标。沟通的一般原则是坦诚,不带任何歧视,有逻辑性,分优先级,对事不对人。在逻辑通顺,保持简单,可用很难的情况下需要说明情况并让团队达成共识。
君子和而不同。认识到一件事不同的侧面理解出来的内容是不同的,但以落地实现就为目标既可以达到我们最终目标即可。所以,可以容下别人的意见与建议并推动实现的发展才是好的实现。
真正优秀的架构都是在企业当前人力、条件、业务等各种约束下设计出来的,能够合理地将资源整合在一起井发挥出最大功效,井且能够快速落地。这也是很多 BATJH (百度、阿里巴巴、腾讯、京东、华为)出来的架构师到了小公司或创业团队反而做不出成绩的原因,因为没有了大公 司的平台、资源、积累,只是生搬硬套大公司的做法,必然会失败。
如何从架构图开始让架构设计平滑落地
为什么需要关注软件架构
上班第一周,怒怼CTO
微服务架构及设计模式
开发者需要知道的有关软件架构的五件事
你是个软件架构师吗?
一位架构师的感悟:过度忙碌使你落后
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or