草庐IT

软件架构的30条原则

轻风博客 2023-03-28 原文

作者介绍

Srinath,科学家,软件架构师。Apache Axis2项目的联合创始人,Apache Software基金会的成员,WSO2流处理器(wso2.com/analytics)的联席架构师。 

 

Srinath通过不懈的努力最终总结出了30条架构原则,他主张架构师的角色应该由开发团队本身去扮演,而不是专门有个架构师团队或部门。Srinath认为架构师应该扮演的角色是一个引导者,讨论发起者,花草修建者,而不是定义者和构建者。Srinath为了解决团队内部的架构纷争和抉择,制定了以下30条原则,这些原则被成员们广泛认可,也成为了新手架构师的学习途径。

 

一、基本原则

 

原则1

KISS(Keep it simple,sutpid) 和保持每件事情都尽可能的简单。用最简单的解决方案来解决问题。

 

原则2

YAGNI(You aren’t gonna need it),不要去搞一些不需要的东西,需要的时候再搞吧。

 

原则3

爬,走,跑。换句话说就是先保证跑通,然后再优化变得更好,然后继续优化让其变得伟大。迭代着去做事情,敏捷开发的思路。对于每个功能点,创建里程碑(最大两周),然后去迭代。

 

原则4

创建稳定、高质量的产品的唯一方法就是自动化测试。所有的都可以自动化,当你设计时,不妨想想这一点。

 

原则5

时刻要想投入产出比(ROI),即是否划得来。

 

原则6

了解你的用户,然后基于此来平衡你需要做哪些事情。不要花了几个月时间做了一个devops用户界面,最后你发现那些人只喜欢命令行。此原则是原则5的一个具体表现。

 

原则7

设计和测试一个功能得尽可能的独立。当你做设计时,应该想想这一条。从长远来看这能给你解决很多问题,否则你的功能只能等待系统其他所有的功能都就绪了才能测试,这显然很不好。有了这个原则, 你的版本将会更加的顺畅。

 

原则8

不要搞花哨的。我们都喜欢高端炫酷的设计。最后我们搞了很多功能和解决方案到我们的架构中,然后这些东西根本不会被用到。

 

二、功能选择

 

原则9

不可能预测到用户将会如何使用我们的产品。所以要拥抱MVP(Minimal Viable Product),最小可运行版本。这个观点主要思想就是你挑几个很少的使用场景,然后把它搞出来,然后发布上线让用户使用,然后基于体验和用户反馈再决定下一步要做什么。

 

原则10

尽可能的做较少的功能。当有疑问的时候,就不要去做,甚至干掉。很多功能从来不会被使用。最多留个扩展点就够了。

 

原则11

等到有人提出再说(除非是影响核心流程,否则就等到需要的时候再去做)。

 

原则12

有时候你要有勇气和客户说不。这时候你需要找到一个更好的解决方案来去解决。记住亨利福特曾经说过的 :”如果我问人们他们需要什么,他们会说我需要一匹速度更快的马”。记住:你是那个专家,你要去引导和领导。要去做正确的事情,而不是流行的事情。最终用户会感谢你为他们提供了汽车。

 

三、服务端设计和并发

 

原则13

要知道一个server是如何运行的,从硬件到操作系统,直到编程语言。优化IO调用的数量是你通往最好架构的首选之路。

 

原则14

要了解Amdhal同步定律。在线程之间共享可变数据会让你的程序变慢。只在必要的时候才去使用并发的数据结构,只在必须使用同步(synchronization)的时候才去使用同步。如果要用锁,也要确保尽可能少的时间去hold住锁。如果要在加锁后做一些事情,要确保自己在锁内会做哪些事情。

 

原则15

如果你的设计是一个无阻塞且事件驱动的架构,那么千万不要阻塞线程或者在这些线程中做一些IO操作,如果你做了,你的系统会慢的像骡子一样。

 

四、分布式系统

 

原则16

无状态的系统的是可扩展的和直接的。任何时候都要考虑这一点,不要搞个不可扩展的,有状态的东东出来,这是起码的。

 

原则17

保证消息只被传递一次,不管失败,这很难,除非你要在客户端和服务端都做控制。试着让你的系统更轻便(使用原则18)。你要知道大部分的承诺exactly-once-delivery的系统都是做了精简的。

 

原则18

实现一个操作尽可能的幂等。这样的话就比较好恢复,而且你还处于至少一次传递(at least once delivery)的状态。

 

原则19

知道CAP理论。可扩展的事务(分布式事务)是很难的。如果可能的的话,尽可能的使用补偿机制。RDBMS事务是无法扩展的。

 

原则20

分布式一致性无法扩展,也无法进行组通信,也无法进行集群范围内的可靠通信。理想情况下最大的节点限制为8个节点。

 

原则21

在分布式系统中,你永远无法避免延迟和失败。

 

五、用户体验

 

原则22

要了解你的用户和清楚他们的目标。他们是新手、专家还是偶然的用户?他们了解计算机科学的程度。极客喜欢扩展点,开发者喜欢示例和脚本,而普通人则喜欢UI。

 

原则23

最好的产品是不需要产品手册的。

 

原则24

当你无法在两个选择中做决定的时候,请不要直接把这个问题通过提供配置选项的方式传递给用户。这样只能让用户更加的发懵。如果连你这个专家都无法选择的情况下,交给一个比你了解的还少的人这样合适吗?最好的做法的是每次都找到一个可行的选项;次好的做法是自动的给出选项,第三好的做法是增加一个配置参数,然后设置一个合理的默认值。

 

原则25

总是要为配置设置一个合理的默认值。

 

原则26

设计不良的配置会造成一些困扰。应该总是为配置提供一些示例值。

 

原则27

配置值必须是用户能够理解和直接填写的。比如:不能让用户填写最大缓存条目的数量,而是应该让用户填写可被用于缓存的最大内存。

 

原则28

如果输入了未知的配置要抛出错误。永远不要悄悄的忽略。悄悄的忽略配置错误往往是找bug花了数小时的罪魁祸首。

 

六、艰难的问题

原则29

梦想着新的编程语言就会变得简单和明了,但往往要想真正掌握会很难。不要轻易的去换编程语言。

 

原则30

复杂的拖拉拽的界面是艰难的,不要去尝试这样的效果,除非你准备好了10人年的团队。

 

最后,说一个我的感受。在一个理想的世界里,一个平台应该是有多个正交组件组成-每个组件都负责一个方面(比如,security,messaging,registry,mdidation,analytics)。好像一个系统构建成这样才是完美的。但不幸的是,现实中我们很难达到这样的状态。因为在项目初始状态时,很多事情是不确定的,你无法做到这样的独立性,现在我更倾向于在开始的时候适当的重复是必要的,当你尝试铲除他们的时候,你会发现引入了新的复杂性,分布本身就意味着复杂。有时候治愈的过程要比疾病本身更加的糟糕。

 

七、总结

作为一个架构师,应该像园丁一般,更多的是修剪花草,除草而不是去定义和构建,你应该策划而不是指挥,你应该去修剪而不是去定义,应该是讨论而不是贴标签。虽然在短期内可能会觉得也没什么,但从长远看,指导团队找到自己的方式会带来好处。如果你稍不留神,就很容易让架构成为一个空洞的词汇。比如设计者会说他的架构是错误的,但不知道为什么是错误的。一个避免这种情况的好办法就是有一个原则列表,这个原则列表是被广泛接受的,这个列表是人们讨论问题的锚点,也是新手架构师学习的路径。

 

作者丨Srinath

来源丨网址:https://dzone.com/articles/30-shared-principles-for-discussing-software-archi-1

有关软件架构的30条原则的更多相关文章

  1. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  2. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

  3. ruby - 最佳原则中的原则 - 2

    我似乎经常遇到一些设计问题,但我不知道是什么是真的很合适。一方面我经常听到我应该限制耦合和坚持单一职责,但当我这样做时,我常常发现它很困难到在需要时将信息获取到程序的一部分。为了例如,classSingerdefinitialize(name)@name=nameendattr:nameend那么Song应该是:classSongdefnew(singer)@singer=singerendend或classSongdefnew(singer_name)@singer_name=singer_nameendend后者耦合性小,按道理应该用。但如果我以后发现宋有什么需要了解更多歌手,我的

  4. ruby - Ruby 和 Ruby on Rails 中的三层架构 - 2

    我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby​​1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails

  5. 网站日志分析软件--让网站日志分析工作变得更简单 - 2

    网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.

  6. ruby-on-rails - 具有六边形架构和 DCI 模式的框架和数据库适配器 - 2

    我尝试用Ruby设计一个基于Web的应用程序。我开发了一个简单的核心应用程序,在没有框架和数据库的情况下在六边形架构中实现DCI范例。核心六边形中有小六边形和网络,数据库,日志等适配器。每个六边形都在没有数据库和框架的情况下自行运行。在这种方法中,我如何提供与数据库模型和实体类的关系作为独立于数据库的关系。我想在将来将框架从Rails更改为Sinatra或数据库。事实上,我如何在这个核心Hexagon中实现完全隔离的rails和mongodb的数据库适配器或框架适配器。有什么想法吗? 最佳答案 ROM呢?(Ruby对象映射器)。还有

  7. ruby - 为什么方法调用在原则上可以是常量时需要消除歧义? - 2

    方法调用通常可以省略接收者和参数的括号:deffoo;"foo"endfoo#=>"foo"在上面的例子中,foo在方法调用和对潜在局部变量的引用之间是不明确的。在没有后者的情况下,它被解释为方法调用。但是,当方法名原则上可以是常量名时(即,当它以大写字母开头,并且仅由字母组成时),似乎需要消歧。defFoo;"Foo"endFoo#=>NameError:uninitializedconstantFooFoo()#=>"Foo"self.Foo#=>"Foo"为什么会这样?为什么即使在没有同名常量的情况下,也需要明确区分方法调用和对常量的引用? 最佳答案

  8. 【血泪建议】软件测试岗位现状,可惜之前没人告诉我,肠子都晦青了.... - 2

    谈到现状,国内的软件测试行情目前呈现了两极分化的极端情况。一个是早期的手工测试人员吐槽工作不好做,即使有工作也是外包,而且薪资太低;一方面是很多互联网企业感叹自动化测试人才难找,有技术的自动化测试工程师,高薪难聘。这两者其实并不矛盾。手工测试工作难找也确实是目前真实的行情早期从事功能测试的手工测试人员,在测试方面大多采用手动、人工执行的方式查找软件缺陷和BUG,用行业术语来描述就是“点点点”。这种测试方式耗费大量人力和资源,工作效率却十分低下。在早期软件复杂和迭代程度不高的情况下,有资本的企业会“供养”一批这样的手工测试人员。但对测试员本身来讲,毫无技术难度的工作,和几乎没有保障的薪资水平,直

  9. 设计一个亿级高并发系统架构 - 12306火车票核心场景DDD领域建模 - 2

    “架设一个亿级高并发系统,是多数程序员、架构师的工作目标。许多的技术从业人员甚至有时会降薪去寻找这样的机会。但并不是所有人都有机会主导,甚至参与这样一个系统。今天我们用12306火车票购票这样一个业务场景来做DDD领域建模。”开篇要实现软件设计、软件开发在一个统一的思想、统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束。虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍然是必要的,为了开发一个支持DDD的框架,首先需要理解DDD的基本概念和核心的组件。一.什么是领域驱动设计(DDD)首先要知道DDD是一种开发理念,核心是维护一个反应领域概

  10. ruby-on-rails - 30.seconds.ago 之类的东西是如何实现的? - 2

    我发现了这个问题here.并且非常想知道如何在Rails中实现类似30.seconds.ago的技术解释。方法链?Numeric用法如下:http://api.rubyonrails.org/classes/Numeric.html#method-i-seconds.还有什么? 最佳答案 Here是seconds的实现:defsecondsActiveSupport::Duration.new(self,[[:seconds,self]])end并且,here是ago的实现:#CalculatesanewTimeorDatethat

随机推荐