小故事:架構師需要做什么?
2016-02-15 18:17:18 來源: mengyidan1988 評論:0 點擊:
本文是一篇模仿問答的小故事,作者用幽默的風格簡單分析了架構師要做的工作: 我想要成為一名軟件架構師。 引用這是年輕軟件開發者很好的選擇。 我想要帶領團隊,并在數據庫與框架、webserver等方面作出重要的決策。 引用噢,那你根本就不想成為軟件架構師。 我當然想了,我想要成為重要決策的制定者。 引用那很好,不過你列出的內容中并不包含重要的決
本文是一篇模仿問答的小故事,作者用幽默的風格簡單分析了架構師要做的工作:
我想要成為一名軟件架構師。
我想要帶領團隊,并在數據庫與框架、webserver等方面作出重要的決策。
我當然想了,我想要成為重要決策的制定者。
什么意思?你是說數據庫并不是重要的決策,你知道我們在上面花了多少錢嗎?
你怎么能這樣講?數據庫是系統的核心,是進行所有數據系統化、分類、編入索引和存取工作的地方;沒有數據庫的話,就不會有系統。
輔助?這太離譜了。
嗯,沒錯,不過必須重新進行編碼,因為在原本的數據庫中這些工具都用到了。
什么意思?
這簡直是瘋了。如何創建不使用那些工具的業務規則呢?
那么如何在不了解使用什么工具的情況下,獲得業務規則呢?
你在胡言亂語。
一派胡言!高層準則(假設指的是業務規則)調用低層準則(假設指的是數據庫)。因此高層準則會根據調用方依賴被調用方的原則,而依賴低層準則。這個誰都知道!
得了吧!怎么能在不提及的情況下進行調用呢?
面向對象是關于真實世界的模型創建,將數據、功能與有凝聚力的對象相結合。是關于將代碼組織成直觀的結構。
大家都知道,這是顯而易見的真相。
好吧,那要怎么做?
沒錯,這是當然的。
這取決于所使用的語言。在Java中,sender至少知道receiver的基礎類型。在Ruby中,sender至少知道receiver能夠處理所收到的消息。
是這樣,好吧,確實如此。
是這樣,沒錯。我了解了。不過sender仍舊依賴于receiver。
不會吧!sender仍依賴于它所發送的類。
下面是receiver:
是啊,不過你在撒謊,你把receiver的接口放在sender類中了。
懂什么?
如果這意味著我必須使用嵌套類,那么……
好吧,等一下。這又跟數據庫有什么關系?我們最開始討論的可是數據庫。
業務規則沒占多大份量。
好的,那么Gateway到底是什么?
注意:這是在businessRules之中。
ok,Something類又是什么?
另外,注意業務規則在運行時調用數據庫;不過在編譯時,數據庫會涉及并依賴于businessRules。
好吧,我想我明白了。你只是在利用多態性來隱藏從業務規則實現數據庫的事實。不過仍需要一個接口,向業務規則提供所有的數據庫工具。
不,完全不是這樣。我們沒有嘗試向業務規則提供數據庫工具。而是通過業務規則,為它們所需要的內容創建接口。實現這些接口就能調用合適的工具。
是啊,不過如果所有業務規則需要用到每個工具,那么只需把工具放在gateway接口中。
啊,我看你還是沒明白。
明白什么?這已經很清楚了。
等一下,你說什么?
不過,這意味著需要很多接口,以及很多的小型實現類,它們又會調用其他的數據庫類。
不過這太亂了,浪費時間。為什么要這樣做呢?
得了吧,為了代碼,弄出來一大堆代碼。
這是什么意思?
是啊,我是這樣想的。
是啊,你說那些都不重要。只是不相關的內容。
不過必須得先決定那些吧!
胡說,我完全不明白你的意思。
作者:Robert C. Martin?
原文:A Little Architecture?
譯者:孫薇
我想要成為一名軟件架構師。
引用
這是年輕軟件開發者很好的選擇。
我想要帶領團隊,并在數據庫與框架、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設備和框架的團隊,才能創建快速、輕量級的測試環境;只有其架構師關心真正重要的東西,延緩那些不重要的,這樣的團隊才是幸運的團隊。
如果架構師提前確定框架,卻發現框架無法提供所需的性能,或者帶來了無法忍受的約束,這就成了災難。
只有架構師決定推遲決策,待信息足夠時才作出決策;在架構師的決策下,不使用緩慢而過于耗費資源的IO設備和框架的團隊,才能創建快速、輕量級的測試環境;只有其架構師關心真正重要的東西,延緩那些不重要的,這樣的團隊才是幸運的團隊。
胡說,我完全不明白你的意思。
引用
好吧,還是好好看一下本文,不然只能再等10年你才能明白了。
作者:Robert C. Martin?
原文:A Little Architecture?
譯者:孫薇
上一篇:Apache Ignite(四):基于Ignite的分布式ID生成器
下一篇:通過利用“業務映射”來構建敏捷組織
分享到:
收藏
