在我们的周围存在着很多的全栈工程师,极客达人,他们热爱技术,善于使用各种工具,甚至可以熟练使用多种开发语言,解决各种技术上的问题,但是却无法成为掌控全局的架构师,无法做出最优的架构决策,这是为什么呢?



架构中的哲学



在《道德经》中提到四个字,叫“道、法、术、器”。“道”是天道,“法”是人定的,就是说你该怎么跟着“天道”去做。“法”也有善恶之分。顺应天道的“法”就是善法,相反,违背天道的“法”就是恶法。“术”是指技术层面上的操作方法。“器”是指有型的物质或是有形的工具。



无独有偶,在学习阳明心学的时候,其核心教义也和道家思想一脉相承。

无善无恶是自然之道,有善有恶是人性之法,知善知恶需判别之术,为善去恶用合法之器。他们不是含义上的等价,却是哲学思想层次的完美统一。从道出发,以法为界,以道御术,善于用器。这是一个循序渐进的过程,是解决问题的步骤和方法论。

对于大部分程序员来说,不论是我们参与的工作,还是接受的培训,基本都属于“器”、“术”的范畴。而架构师具备能力:理解业务,全局把控(道),选择合适技术(法),解决关键问题(术),指导研发落地实施(器)。可见成为一名合格的架构师,不仅仅只是具备技术能力就可以完全胜任的,还需要领悟架构之道,架构之法并合理的应用。



何为架构的道、法、术、器呢?

:架构设计的方向,大道至简。

:架构设计的原则,有据可依。

:架构设计的技巧,有题可解。

:架构设计的工具,有器可用。



王阳明的思想最核心的是“知行合一”,对于程序员来说,我们从从事的工作中可以逐步的向上升华,从而建立起知的过程。我们也应该去学习架构的思想和方法,来不断的应用到自己的工作中,让我们做的更好。



回顾架构之“道”

软件架构之道最核心的问题是解决复杂性的问题,并且在解决问题的过程中找到最佳的平衡点,既要简单又能满足发展。在前面的文章里,我分享了四种解决复杂性问题的四种最最重要的武器,首先先回顾一下:

  • 抽象思维--《无抽象不架构》:抽象思维是架构思维最最核心的思维能力,不具备抽象思维就无法化繁为简,复用和扩展也就无从谈起。

  • 分层思维--《想解耦必分层》:架构的核心是解耦和复用,而分层是基于调用链来划分职责的一种方式,只有职责单一清晰,才能真正解耦。

  • 分治思维--《凡架构必拆分,分则有度》:复杂的问题需要分解成一个个的小问题才能更容易的解决,架构其中一个目的就是管理系统的复杂性,而分治思维是管理复杂性必不可少的手段,微服务架构是分治思维的一种体现。

  • 演化思维--《架构设计过度有时比设计不足更可怕》:架构是设计出来的,更是演化出来的,设计不足会使后续升级成本提高,而过度设计则会让现在为期望提前买单,都是得不偿失的。适可而止的架构加时刻保持演进的变化是最合理的做法。



之所以花了那么多篇幅去讨论架构之道,因为“道”是方向,没有方向的努力也许是徒劳的。一个好的架构师或者成为一个好的架构师的潜力的程序员都应该去学习并领悟架构之道。



聊聊架构之“法”



“道”是抽象的,是形而上的,对它的认知每个人因为能力和悟性均有差异,这也是决定我们能否在这条道路上走多远的先决条件。软件架构之道在于找到设计的平衡点,使得架构足够简单,又能够满足需要,同时还要兼顾发展,这句话说起来简单,但是做起来特别的难。每个人对于平衡点的把握都是有差异的,因为修道有深浅,而且很容易被外界的因素干扰,最终造成的差异也是巨大的。有没有可以依据的原则让抽象的“道”更加具体,让个体的差异不再那么明显呢?这就是道家所说的“法”,即根据自然发展规律人为制定的原则和法则。



通用原则

  • KISS原则:Keep it simple and stupid.简单未必愚蠢,很多时候大智若愚。

  • 最小代价(努力)原则:程序猿的惰性与生俱来,我们总是选择最容易行走的路径。这也是为什么我们应该尽可能在一开始的时候,作出正确的选择,因为一旦这个架构设计出现,后面的人很有可能不愿意为了更好的架构而改进,而是遵循已有的设计。

  • 最小意外原则:好的设计应该避免意外,遵守通用的规范和习惯。这些意外其实是软件架构和设计中的复杂因素。最小意外也就意味着尽可能的简单。

  • DRY原则:“Dont repeat yourself” 告诉我们应该尽可能的消灭重复和冗余。重复使的软件的阅读,修改,测试变得复杂,消灭重复,是使软件变得简单的手段之一。



在架构设计的通用原则里,核心的思想是为了让系统或者其动态发展变得更加简单而不是让它更加复杂。但简单和复杂却又是形影相随的孪生兄弟,你如果要扩展简单,那么就可能封装复杂;你如果想使用简单,那么就可能实现复杂;你如果过想开发简单,那么就可能运维复杂。这看似非常矛盾,其实架构就是一种选择和平衡的艺术,你选择面对的主体是谁,你就让它更加简单。



设计模式的七大原则



23种设计模式对程序员来说想必都不陌生,它指导我们写出更优雅、更健壮、更具有扩展性的面向对象的程序。我认为设计模式的内容,更偏向架构之“术”,它教给我们具体的设计方法。但软件设计模式和面向对象的设计都基于一些常见的原则:



  1. 单一职责原则:告诉我们实现类要职责单一。其实不光是写程序,我们在做分层设计,以及微服务组件拆分时,单一职责都是指导性的原则。

  2. 里氏替换原则:告诉我们不要破坏继承体系。

  3. 依赖倒置原则:告诉我们要面向接口编程。

  4. 接口隔离原则:告诉我们在设计接口的时候要精简单一。

  5. 迪米特法则:告诉我们要降低耦合。在领域驱动设计方法中,迪米特的最小知道原则也是指导我们领域划分的重要法则。

  6. 合成复用原则:告诉我们少用继承。

  7. 开闭原则:告诉我们要对扩展开放,对修改关闭。开闭原则是面向对象中最基础的原则,抽象构建框架,用实现扩展细节。可以提高软件系统的可维护性和可复用性。这是设计模式七大原则最重要的设计原则,应用在各个地方。



专有领域的设计原则



不论是架构的通用原则还是设计模式的原则基本上都是普遍通用的原则,几乎对所有的开发者,架构师都有用。其实设计原则也是有层级或者有领域的,在不同的领域有自己特有的设计原则。比如在分布式系统开发领域,就需要遵守著名的CAP原则(指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这三个要素最多只能同时实现两点,不可能三者兼顾。),在数据库设计领域,你不得不了解ACID(ACID 为 Atomicity, Consistency, Isolation, and Durability,强制一致性,要么全做要么不做,所有用户看到的数据一致。强调数据的可靠性, 一致性和可用性。)和BASE(BASE为Basically Available, Soft-state, Eventually consistent,表示为支持可用性,牺牲一部分一致性,可以显著的提升系统的伸缩性,数据为最终一致。和ACID为相反的方向。其中事务支持不会很高.)这两种设计原则的区别和应用场景。



甚至在一个团队中也要遵从团队中特有的一些设计原则,比如每个团队都有自己的开发规范,命名规范,过去在做互联网领域的开发时,我禁止团队成员使用存储过程,这些设计原则在通用的设计原则基础上根据自身实际情况更加的细化和明确,从而更好的指导团队的协同发展。比如阿里巴巴著名的《Java开发规范》,它已经成为行业普遍的指导性开发规范。



我总结了一些架构方面的设计原则,如果有需要的朋友,可以关注我公众号,私信“设计原则”给我。



小结



所以,很多人认为我学习了那么多的技术,会各种各样的技巧,为什么还不能成为合格的架构师,其原因就是“术”与“器”都是小乘,而“道”与“法”才是架构的上乘,正如老子所说:“道法自然”,架构之道,架构之法以架构的自然规律为核心,也符合上文所说的“有据可依”,所以才能做出更好的架构决策。



但是学习设计原则,又千万不能形成强迫症。碰到业务复杂的场景,我们需要随机应变。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构,做出更加适合自己的架构决策,适合的才是最好的。