足球资料库数据/孙祥/nba五佳球/足球直播哪个平台好 - cctv5今日现场直播

首頁 > 知識庫 > 正文

小故事:架構師需要做什么?
2016-02-15 18:17:18   來源: mengyidan1988   評論:0 點擊:

本文是一篇模仿問答的小故事,作者用幽默的風格簡單分析了架構師要做的工作: 我想要成為一名軟件架構師。 引用這是年輕軟件開發者很好的選擇。 我想要帶領團隊,并在數據庫與框架、webserver等方面作出重要的決策。 引用噢,那你根本就不想成為軟件架構師。 我當然想了,我想要成為重要決策的制定者。 引用那很好,不過你列出的內容中并不包含重要的決
本文是一篇模仿問答的小故事,作者用幽默的風格簡單分析了架構師要做的工作:
我想要成為一名軟件架構師。
引用
這是年輕軟件開發者很好的選擇。

我想要帶領團隊,并在數據庫與框架、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?
譯者:孫薇

相關熱詞搜索:架構師 other 非技術

上一篇:Apache Ignite(四):基于Ignite的分布式ID生成器
下一篇:通過利用“業務映射”來構建敏捷組織

分享到: 收藏