阅读更多

3顶
0踩

非技术

原创新闻 小故事:架构师需要做什么?

2016-02-15 16:05 by 副主编 mengyidan1988 评论(7) 有6723人浏览
本文是一篇模仿问答的小故事,作者用幽默的风格简单分析了架构师要做的工作:
我想要成为一名软件架构师。
引用
这是年轻软件开发者很好的选择。

我想要带领团队,并在数据库与框架、webserver等方面作出重要的决策。
引用
噢,那你根本就不想成为软件架构师。

我当然想了,我想要成为重要决策的制定者。
引用
那很好,不过你列出的内容中并不包含重要的决策,这些都是不相关的决策。

什么意思?你是说数据库并不是重要的决策,你知道我们在上面花了多少钱吗?
引用
也许花的太多了。但是,数据库并不是重要的决策之一。

你怎么能这样讲?数据库是系统的核心,是进行所有数据系统化、分类、编入索引和存取工作的地方;没有数据库的话,就不会有系统。
引用
数据库只是一个IO设备,它恰巧为分类、查询与信息报告提供了一些有用的工具,但这些都只是系统架构的辅助功能而已。

辅助?这太离谱了。
引用
没错,就是辅助。系统的业务规则也许能够利用其中的一些工具,不过那些工具却并非相应业务规则所固有的。需要的话,可以用不同的工具来替换现有的这些;而业务规则不会改变。

嗯,没错,不过必须重新进行编码,因为在原本的数据库中这些工具都用到了。
引用
那是你的问题。

什么意思?
引用
你的问题在于,你以为业务规则是依赖数据库工具的,实际上并不是。或者说至少,在提供优秀架构前并不应当是这样的。

这简直是疯了。如何创建不使用那些工具的业务规则呢?

引用
我不是说它们没使用数据库的工具,而是说它们并不依赖于此。业务规则无需知道你使用哪个数据库。

那么如何在不了解使用什么工具的情况下,获得业务规则呢?
引用
让依赖倒置过来,使得数据库依赖业务规则。确保业务规则不依赖于数据库。

你在胡言乱语。
引用
恰恰相反,我在使用软件架构的语言。这是依赖倒置原则:低层准则应当依赖高层准则。

一派胡言!高层准则(假设指的是业务规则)调用低层准则(假设指的是数据库)。因此高层准则会根据调用方依赖被调用方的原则,而依赖低层准则。这个谁都知道!
引用
在运行时的确如此。不过在编译时,我们想要的是依赖倒置。高层准则的源代码应当不提及低层准则的源代码。

得了吧!怎么能在不提及的情况下进行调用呢?
引用
当然没问题。这就是面向对象的所涉及的内容。

面向对象是关于真实世界的模型创建,将数据、功能与有凝聚力的对象相结合。是关于将代码组织成直观的结构。
引用
他们是这么说的?

大家都知道,这是显而易见的真相。
引用
没错,确实如此,然而,在使用面向对象准则时,的确可以在不提及的情况下进行调用。

好吧,那要怎么做?
引用
在面向对象设计中,各个对象会彼此发送消息。

没错,这是当然的。
引用
而sender在发送消息时,并不知道receiver的类型。

这取决于所使用的语言。在Java中,sender至少知道receiver的基础类型。在Ruby中,sender至少知道receiver能够处理所收到的消息。
引用
没错。不过在任何情况下,sender都不知道receiver的具体类型。

是这样,好吧,确实如此。
引用
因此,sender可以在不提及receiver具体类型的情况下,设计receiver执行某个功能。

是这样,没错。我了解了。不过sender仍旧依赖于receiver。

引用
在运行时的确如此。不过编译时则不同。sender的源代码并不会提及或者依赖receiver的源代码。事实上receiver的源代码依赖于sender的源代码。

不会吧!sender仍依赖于它所发送的类。
引用
也许从某些源代码来看,会更清楚一些。下面这段是Java写的。首先是sender:

package sender;
public class Sender {
      private Receiver receiver;
  public Sender(Receiver r) {
    receiver = r;
  }
  public void doSomething() {
    receiver.receiveThis();
  }
  public interface Receiver {
    void receiveThis();
  }
}

下面是receiver:
package receiver;
import sender.Sender;
public class SpecificReceiver implements Sender.Receiver {
  public void receiveThis() {
    //do something interesting.
  }
}

引用
注意:receiver依赖于sender,SpecificReceiver依赖于Sender,在sender中并没有receiver相关的信息。

是啊,不过你在撒谎,你把receiver的接口放在sender类中了。
引用
你开始懂了。

懂什么?
引用
当然是架构的原则。Sender拥有receiver必须实现的接口。

如果这意味着我必须使用嵌套类,那么……
引用
嵌套类只是实现目的的手段之一,还有其他办法。

好吧,等一下。这又跟数据库有什么关系?我们最开始讨论的可是数据库。
引用
再看一点代码吧。首先是一个简单的业务规则:

package businessRules;
import entities.Something;
public class BusinessRule {
  private BusinessRuleGateway gateway;
  public BusinessRule(BusinessRuleGateway gateway) {
    this.gateway = gateway;
  }
  public void execute(String id) {
    gateway.startTransaction();
    Something thing = gateway.getSomething(id);
    thing.makeChanges();
    gateway.saveSomething(thing);
    gateway.endTransaction();
  }
}

业务规则没占多大份量。
引用
这只是个例子。还能有更多这样的类,实现很多不同的业务规则。

好的,那么Gateway到底是什么?
引用
它通过业务规则提供了所有数据存取方法。按以下方式实现:

package businessRules;
import entities.Something;
public interface BusinessRuleGateway {
  Something getSomething(String id);
  void startTransaction();
  void saveSomething(Something thing);
  void endTransaction();
}

注意:这是在businessRules之中。

ok,Something类又是什么?
引用
它代表着简单的业务对象。我将它放在entities之中。

package entities;
public class Something {
  public void makeChanges() {
    //...
  }
}

引用
最终BusinessRuleGateway实现,这个类知道真正的数据库:

package database;
import businessRules.BusinessRuleGateway;
import entities.Something;
public class MySqlBusinessRuleGateway implements BusinessRuleGateway {
  public Something getSomething(String id) {
    // use MySql to get a thing.
  }
  public void startTransaction() {
    // start MySql transaction
  }
  public void saveSomething(Something thing) {
    // save thing in MySql
  }
  public void endTransaction() {
    // end MySql transaction
  }
}

引用

另外,注意业务规则在运行时调用数据库;不过在编译时,数据库会涉及并依赖于businessRules。

好吧,我想我明白了。你只是在利用多态性来隐藏从业务规则实现数据库的事实。不过仍需要一个接口,向业务规则提供所有的数据库工具。
引用

不,完全不是这样。我们没有尝试向业务规则提供数据库工具。而是通过业务规则,为它们所需要的内容创建接口。实现这些接口就能调用合适的工具。

是啊,不过如果所有业务规则需要用到每个工具,那么只需把工具放在gateway接口中。
引用

啊,我看你还是没明白。

明白什么?这已经很清楚了。
引用
每个业务规则只为自己所需的数据访问工具定义一个接口。

等一下,你说什么?
引用
这就是接口隔离原则(Interface Segregation Principle)。每个业务规则类只用到数据库的某些设施。因此,每个业务规则提供的接口只能访问相应的设施。

不过,这意味着需要很多接口,以及很多的小型实现类,它们又会调用其他的数据库类。
引用
很好,你开始理解了。

不过这太乱了,浪费时间。为什么要这样做呢?
引用
这样做能够条理分明,节省时间。

得了吧,为了代码,弄出来一大堆代码。
引用
恰恰相反,通过重要的架构决策,可以延缓不相关的决策。

这是什么意思?
引用
记得最开始,你说想做软件架构师不是吗?你想要作出所有真正重要的决策。

是啊,我是这样想的。
引用
你想要决策的是数据库、webserver和框架相关的方面,对吗?

是啊,你说那些都不重要。只是不相关的内容。
引用
没错。就是这样。软件架构师所作出的重要决策指的是,让你不对数据库、webserver和框架进行决策。

不过必须得先决定那些吧!
引用
不用的。事实上,在开发周期中,这些都可以稍后再决定,在信息更充足的时候再决定。

如果架构师提前确定框架,却发现框架无法提供所需的性能,或者带来了无法忍受的约束,这就成了灾难。

只有架构师决定推迟决策,待信息足够时才作出决策;在架构师的决策下,不使用缓慢而过于耗费资源的IO设备和框架的团队,才能创建快速、轻量级的测试环境;只有其架构师关心真正重要的东西,延缓那些不重要的,这样的团队才是幸运的团队。

胡说,我完全不明白你的意思。
引用
好吧,还是好好看一下本文,不然只能再等10年你才能明白了。


作者:Robert C. Martin 
原文:A Little Architecture 
译者:孙薇
3
0
评论 共 7 条 请登录后发表评论
7 楼 我会是微博 2016-02-20 15:16
面向接口编程,别乱来
6 楼 yixiandave 2016-02-18 10:10
gordon_two 写道
我觉得应该将复杂问题简单化,将简单问题保持简单。
坚持接口优先原则的,其实是僵化的思维结构,99%的领域问题是简单的,却增加了100%个接口,我觉得不妥

但是你不能保证省下99%的简单问题不会在后面某次需求变更后变成复杂问题,这是很常见的情况,这样的话重构的代价就太大了。当然交付后就不用管的项目除外
5 楼 gordon_two 2016-02-17 16:11
我觉得应该将复杂问题简单化,将简单问题保持简单。
坚持接口优先原则的,其实是僵化的思维结构,99%的领域问题是简单的,却增加了100%个接口,我觉得不妥
4 楼 白云天 2016-02-17 15:45
把简单问题复杂化,复杂问题简单化,玄之,哈哈。
3 楼 猿哥哥的成长记 2016-02-17 14:47
   
2 楼 neo_it 2016-02-16 14:14
谁写的鬼文?思维混乱,言不达意。
整篇想说的就是:构架师要先清楚业务需求,再来决定软件框架。
就这么简单的一点,需要唧唧歪歪说这一大家通?
1 楼 snow8261 2016-02-15 16:46
写的非常好!

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 软件设计和开发规范(国标).rar

    软件设计和开发规范(国标)

  • 敏捷开发项目管理规程

    1.目的规范互联网软件产品开发项目管理过程,指导开展项目研发、管理等活动。2.适用范围本章程的作用范围为互联网软件产品开发立项至结项管理过程。1.对项目经理开展产品规划及设计活动以及项目管理手段和应遵循的开发流程提供了指导;2.对项目团队的日常管理活动及内容进行了指导;3.角色及职责定义项目经理:进行产品开发过程中的业务目标、进度、成本、质量控制。挑选项目团队并进行团队建设,激发、鼓舞和改进团队的

  • 软件开发设计规范书的撰写

     整个软件开发过程是一个相当复杂的流程,并不是简单的靠几个设计工程师自己在那边写软件就完,而是要有从头到尾,包括很多人,不同专家,不同的专业,不同的知识放在一起,最后才造成一个完善的软件产品。从决定开始,到计划、设计,最后到写程序、执行,然后还有测试、纠错、保证稳定、发行、部署、调试,整个过程是一个相当长的过程,并不是一个简单的程序。要为了保证软

  • c#程序编写规范

    C#代码开发规范     文件状态: [√] 草稿 [  ] 正式 [  ] 修改 文件标识:   当前版本: 1.1 作    者: Empty 联系电话:   最后更新: 2014-04-07   版本记录

  • 软件设计和开发规范(国标)

    包括:1-操作手册(GB8567——88).doc 2-测试分析报告(GB8567——88).doc 3-测试计划(GB8567——88).doc 4-概要设计说明书(GB8567——88).doc 5-开发进度月报(GB8567——88).doc 6-可行性研究报告(GB856...

  • 阿里巴巴开发规范

    一、编程规范 1.1、命名风格 (1)不能以下划线或者美元符号开始和结束; (2)不能使用拼音和英文混合方式,不能直接中文方式; (3)类名使用UpperCamelCase风格,但是DO/BO/DTO/VO/AO/PO/UID除外: 正解:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion 反例:macroPolo / ...

  • 软件设计原则

    软件设计原则,更好的设计我们的应用。

  • 7.3.项目开发设计流程规范与技巧

    一个项目从客户提出需求,到需求分析,再到设计、开发、测试等,经过一系列的环节后,才能达到正式使用和上线的效果。 为了标准化开发流程,提高开发效率,特将项目开发的一下规范和技巧,做一些说明。 项目开发流程,如下图所示。 这里贴一个流程图:客户提出需求、我们整理需求、设计页面原型、编写功能需求补充文档、与客户沟通核对原型和需求、调整原型与需求、确认原型与需求、数据库UML建模、UML建模确认、数...

  • 软件设计和开发规范(国标) (转)

    软件开发规范,包括:1-操作手册(GB8567——88).doc2-测试分析报告(GB8567——88).doc3-测试计划(GB8567——88).doc 4-概要设计说明书(GB8567——88).doc5-开发进度月报(GB8567——88).doc 6-可行性研究报告(GB8...

  • 项目开发文档编写规范

    在开发项目的过程中,我深刻的意识到,文档存在的意义并不是无用的报告,简洁明了的文档不光能记录你当下所做的,还能在繁重的工作中分神思考下一步该做什么时为你节约精力,并且在项目周期内,使整个项目保持一致性。所以,软件开发文档的编写是很有必要的。我参考网上的资料,结合自己项目开发时的心得,分享一些经验。

  • uni-app开发APP之开发规范和一些注意事项

    ????个人体会 开发快速。uniapp最大的优势就是整合7端开发规范在一起,配合Vue让前端开发人员可以开发出“具有基本功能”的APP(对比flutter来说,uniapp对前端更友好),可以快速开发多端应用。一次编译,多端运行。 接口丰富。DCloud有h5 app经验,同时这部分的API也开放给uniapp可以直接调用,调用的时候同样也是用js引擎调用原生API。很多东西开箱即用,微信支付,消息推送等等。 过于全面。一般项目不需要7端都需要,但是官方必须考虑7端,所以很多东西必须用条件编译区分平台来

  • MySQL 设计与开发规范

    MySQL 经典设计与编写规范, 程序员必读规范之一...

  • 程序设计规范(转载)

    程 序 设 计 规 范1. 文件夹与文件的命名规则1.1 文件夹命名① 根据系统设计所规定的结构,建立相应的文件夹,根据需要建立子文件夹② 文件夹的名称应尽量能够表达其意义,尽量使用英文命名,绝对不能汉字③ 文件夹名称的必须全部使用小写字母 (如 “ /example ” )1.2 文件命名① 文件的名称应尽量能够表达其意义,尽量使用英文命名,绝对不能汉字② 文件名称全部使用小写字母(确保平台兼容

  • 软件开发规范

    为什么 一份合格的代码不应只满足于实现功能,更应该遵循良好的规范 提升程序稳定性,减少代码隐患,降低故障率 增强可扩展性,大幅提高维护效率 统一标准,提升多人协作效率,方便新人快速上手 系统设计 不允许出现两段相同的逻辑块,必须抽出为公共方法,差异性使用参数控制,避免修改时多处修改遗漏 不允许出现两段相同的处于同一逻辑组的赋值布局,必须抽出为单独的include/merge 不允许父类中出现子类的实现方法,如果需要的话可以定义父类抽象方法,交由子类实现 不允许activity内多个fragment之间的

  • 《软件工程导论》课后习题答案

    《软件工程导论》课后习题答案第一章 软件工程概论1.什么是软件危机?软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。这些问题表现在以下几个方面:(1)用户对开发出的软件很难满意。 (2)软件产品的质量往往靠不住。 (3)一般软件很难维护。 (4)软件生产效率很低。 (5)软件开发成本越来越大。 (6)软件成本与开发进度难以估计。 (7)软件技术的发展远远满足不了计算机应用的普及与...

  • 软件环境、硬件环境、开发工具

    软件环境:Windows操作系统 硬件环境:Android手机 开发工具:MyEclipse、AndroidStudio

  • 《软件工程导论》课后习题答案 张海藩

    《软件工程导论》课后习题答案 第一章 软件工程概论 1.什么是软件危机?   软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。这些问题表现在以下几个方面:    (1)用户对开发出的软件很难满意。    (2)软件产品的质量往往靠不住。    (3)一般软件很难维护。    (4)软件生产效率很低。    (5)软件开发成本越来越大。    (6)软件成本与开发

  • 软件系统设计准则规范说明书模板

    软件系统设计准则规范说明书模板

  • 软件设计的编程规范和技术文档

    软件设计软件设计软件设计软件设计软件设计

Global site tag (gtag.js) - Google Analytics