SOA重新詮釋

雖然寫了不少AOP的文章了,也沒少關注SOA,不過最近才發現自己以前的認識多少有些狹隘,不,應該說非常狹隘纔是。在這裏,我要結合自己最近的感悟,重新詮釋一下什麼是SOA,什麼是AOP。本文原出處爲我的MSN SPACE,原文標題是重新詮釋SOA和AOP,因爲實在寫得太長了點,這裏分成兩篇來寫,這是第一篇:重新詮釋SOA。之後還會有下一篇,重新詮釋AOP,敬請期待!

-

什麼是SOA呢?
 
一直以來,個人就認爲SOA有些奇怪,有點回到原始的過程化設計的味道,一度懷疑是不是web service的興起,因爲web service沒有狀態,又是粗顆粒的,所以,出現了這樣一個不倫不類的SOA。雖然也一直認爲自己理解是有偏差的,但到現在才知道錯得很遠。
 
那麼,到底什麼是SOA呢,所謂Service Oriented自然肯定是突出Service,可是爲什麼要突出Service,甚至Web Service(Web Service)呢?
 
首先,讓我來先給Service下一個定義,該定義的有效域至本文中下一次對Service的定義進行修正(如果有這樣的修正定義的話,否則定義就一直有效知文章結束)爲止。
 
Service - 一種執行接口,接受外部的調用請求,請求可以包含0到多個參數,根據參數處理該請求後,返回執行結果,結果包含處理的成功或失敗狀態及0到多個返回參數,其中每個請求參數或返回參數都由一個Key/Value對錶示。
-
 
根據該定義,讓我們來看看,在現實世界中,在哪裏我們可以看到這樣的Service呢?
 
依照一般的問題分析方法,對任何一個問題點,我們都可以從水平和垂直兩個緯度來分析,水平緯度一般指問題的廣度,垂直緯度一般指深度。無論水平或垂直緯度上的每個點,我們又可以從水平垂直兩個方向來遞歸分解。
 
這裏,我們先以一個計算機軟件的執行過程這個水平點,在不同的抽象層次深度上,找找Service的影子。
 
-
 
我們知道,對於任意一個馮·諾依曼體系的計算機,任意一個程序,歸根結底到最後都會被轉換爲一串串的0和1,這些0和1的不同組合代表了不同的計算機指令或者數據。Ok,我們找到了一個詞-“指令”,一個指令是什麼東西呢?在計算機內部,一個計算機指令的執行過程實際上是由解碼器解析傳入的一串0和1,根據這些0和1代表的不同含義,執行一些操作,其間可能會讀取或改變一些指定寄存器或者存儲器單元的值,不論是否執行成功,他都會有一定的反饋,可能是一箇中斷信號或者一個計數器遞增,總之代表了這個指令執行過程的結束,如果需要的話,以後的指令可以去讀取該指令修改的寄存器或存儲器的值。
 
比較一下一個計算機指令的執行過程和我們的Service的定義,我們可以發現,一個“指令”,就是一個“Service”。它是一個執行接口,接受調用請求和讀取指定位置(key,如約定的寄存器名稱或存儲器地址)的傳入參數(由0和1序列指定哪個指令被調用,並有之前的指令爲其準備好了可能要去讀的寄存器或者存儲器的value),執行一定的處理,並返回執行狀態(如中斷或計數器遞增)和返回參數(寫寄存器或存儲器,允許之後的指令訪問)。
 
除了“指令”的這些表面特徵,他還有些什麼特點?我們可以看到,計算機的發展日新月異,但是,基本的最操作指令卻基本是類似的,無外乎對一些0或1的處理嘛-與、或、非、異或、同或、左移、右移等等。但是,不同時代,甚至同時代的不同結構或者同結構的不同上下文環境,同一個指令的請求、輸入參數和返回結果可能相同,但是,執行的內部處理機制可以是不同的。比如,最早最簡單的計算機,可能僅僅通過硬佈線的與、或、非門及一定的線路組合就能夠完成一個指令,比如“非”這個操作,用一個“非”門就夠了;隨着技術的進步,這些與或非門可能被封裝進了各種通用組合元件中以方便支持複雜處理,或者不完全用這些“門”,用Rom陣列,或者半導體非數字模擬元件配合特殊的信號刺激,同樣能夠完成等價的處理效果;計數再進步,可能一個計算機處理器內部又有一個個特殊功能的微處理器,也就是一個個內嵌的小型計算機處理器,不同的指令直接傳遞給這些微處理器來處理就好了,速度不夠快了,人們又發明了各種緩存寄存器,流水線,微處理器陣列,等等等等。內部結構和設計思想在變,但是,什麼沒變呢?沒錯,這些基本指令的調用接口和執行結果基本不變
 
這種“調用接口和執行結果不變”是什麼思想呢?其實就是一個“黑盒”的思想,封裝的思想。外部的調用者無需知道處理的內部細節,每個“黑盒”可能在執行效率,寄存器、存儲器或時間等花銷這樣的非功能性效果上會有不同,但是,它們功能性效果-輸入輸出返回值,是不會變的,也不允許變,變了就不是同一個指令了。
 
顯然,指令的這樣一種“調用接口和執行結果不變”的特性,也是Service的特性
 
-
 
讓我們從與或非門中稍微解脫一些出來,到一個新的抽象層次-彙編。什麼是彙編呢?其實,它離0和1也不遠,教科書上說了,彙編是對0和1這些機器指令的抽象封裝,用add,or,not這樣的有那麼點人性的詞代替了001,010,100,一下子,寫計算機程序變得簡單多了,效率大大提升。但是,本質上,機器指令和彙編指令基本上是一一對應的,當然也可能一個彙編指令對應了一個有多個機器指令組成的指令序列。於是乎,很顯然的,我們當然可以說,一個彙編指令也是一個Service
 
非常幸運的,除了對機器指令調用的簡化,彙編對我們關於Service的討論也不是一點幫助都沒有。我們注意到“一個彙編指令也可能一個彙編指令對應了一個有多個機器指令組成的指令序列”!這是一種什麼特性呢?其實是一種分而治之的思想,一個彙編指令可以分別由多個機器指令的組合,甚至其它更簡單的彙編指令甚至遞歸調身指令本身的組合來實現效果。
 
Nice,我們再次發現,彙編指令的這樣一種“一個彙編指令也可能一個彙編指令對應了一個有多個機器指令組成的指令序列”的特性,也是Service的特性。換句話說,也就是說“一個Service內部可以調用其它的Service,甚至遞歸調用Service自己來實現需要的功能邏輯,而這種內部細節,對調用者完全透明”
 
-
 
好了,我們再進一步,來到我們可愛的高級語言C/C++,Java,C#。。。不知道讀者是不是看了這些詞鬆了口氣,至少Teddy是呼了口氣的-多優雅美麗的世界啊,機器指令、彙編,見鬼去吧,這年頭還誰喜歡和你們瞎摻乎啊~~
 
本來還想將我們的高級語言們分分過程化、OO什麼的,不過仔細想想也沒必要了,反正比起彙編都美多了,不是嗎?:)還是來看看這些新傢伙給我們帶來了什麼新東西吧。
 
恩~~ 似乎在彙編之後,我們漏了過程化的彙編,從某個時候起,彙編也是可以有“過程”的,現在這年頭叫子函數,總之就是程序不再一股腦兒從第一條指令執行到最後一條,而是中間有調用子函數,再跳轉回來,或者來個遞歸調用什麼的,只不過,這和我們前面說的一個彙編可以包含多個機器指令,內部可以遞歸調用等等真的有區別嗎?本質上其實一會事,不是嗎?只是,隨着高級過程化語言的出現,使得過程化的程序設計應用更簡單了,子函數多了,我們自然給他們歸類,他們成爲一個個--對了,一個個“模塊”,恩,準確地說應該是“過程化模塊”。
 
爲什麼說是“過程化模塊”呢?因爲,過程化的程序設計,除了過程/子函數,還有一些東西叫變量,尤其有一種叫全局變量。很多過程化程序教科書教育的好,如果數據需要被其它過程使用和共享的話,可以定義全局變量,這樣的好處是,不需要每次都把這些數據作爲參數在過程間傳過來傳過去了。說心裏話,我覺得全局變量這東西挺好的,大大簡化了過程化的程序代碼。姑且,請讀者允許我將這類過程/函數式,並且包括共享變量在內的模塊設計思想,和OO基於類的模塊化思想相區別。
 
好了,老樣子,比較一下過程模塊和Service的定義,很好,一個過程就是一個Service
 
-

下面,就輪到我們來看看我們噢年工作中最親密的夥伴OO了。相比較於傳統的過程化設計,OO帶來了什麼呢?讓我們來回想一下-接口、類、封裝、方法、多態、繼承、重載。。。除了這些詞,當然,更重要的是smalltalk的作者倡導的“世間萬物一切都是對象的,一切都是OO”的“變態”思想,很抱歉用了個粗話詞,雖然加了引號,但是,說真的,我是真的在說粗話,真的覺得他很變態。他提出的OO,當然是不錯的進步,有很多好處,幫助我們在認識世界,用計算機描述我們生活的世界方面居功至偉,但也帶來了很大的侷限,導致包括我在內的無數程序員市場變得神經兮兮,以五比七怪的視角一次又一次的審視着這個世界,這個後頭再談了,這裏還是先說說他的好吧!
 
“封裝”, “繼承”-多優雅的詞啊!世界變得整潔,沒有不知定義在那裏的全局變量了(喂,老兄,類裏面還是有作用類全局的變量啦-嗨,我能不知道這個嘛,可是,看他可不是作用全世界的變量),還有,拿我家的小狗爲例吧,你知道嗎?真是太棒了,當我定義好我家的小狗這個類,我可以給他指定各種它能做的活動-專業的叫法是“方法”,還有我給他定義了各種屬性,這樣我操縱我的小狗真簡單,讓它跑它就跑,讓它叫它就叫,把它的顏色這個屬性改成紅,他就變紅毛了,改成綠他就變綠毛了,真他X簡單。你知道嗎,你操縱它的時候根本不用去關心它裏面的細節,只要看它能幹什麼就行了。還有還有,你知道嗎,我也可以不把它當一隻狗,它同時還是一個動物呢,就和現實中小狗食動物是一個道理,很有意思吧?嘿嘿~~因爲它是一隻公狗,在他還很小的時候,長輩給它做了一個小手術,我也不太清具體的細節,總之,他們說做過這樣的手術他就會變得很溫順了,也不用擔心它以後被其它小母狗拐跑了,他只會忠於你一個人,所以,我後來不用“小狗”這個類來表示它,我用最忠誠的小狗來表示,這其中的區別,我現在已經知道了,可是不告訴你~~而且,它還是一隻小狗,他也還是一隻動物呢~~
 
好了,各位,我們別想到其它方面去了,現在可是在OO的世界,OO模塊化的世界是那樣的清潔而優雅,如果你問我“一隻小狗會不會上網寫Blog”這種弱智問題,我不會直接告訴你的,在以前的過程化的年代,也許我會去問問動物研究專家,或者直接告訴你我的意見,但我不得不if很多條件,有時還要去問世界萬狗之神狗當(汗,不知道這是不是指全局變量呢),總之,你明白我的意思,那種做法過時了,我現在只要讓我的小狗直接回答我就行了,你不信?我是這樣做的,告訴你吧,我用了很新的設計思想的,叫設計模式,你問那個設計模式?恩,一看就是內行,可是還真不好回答你,瞧,我這裏定義了一個接口,他有一個方法叫“會不會上網寫Blog”,然後呢,我寫一個新的類,讓他繼承自我的小狗,然後,我問小狗“你會不會上網寫Blog”,它搖遙尾巴就告訴我了。什麼?你問,他是怎麼知道答案的?這個我就不能告訴你了,你還是猜猜吧~~(嘿嘿,我纔不告訴你其實我還是用了不少if,發email問的小狗的祖宗“動物神”,他怎麼知道的我就不知道了),關鍵在於,我現在是直接問的小狗,它也回答了問題,這和以前的做法可是有天壤之別的。是不是感覺到不服不行啊,哈-哈-
 
直接了當的說了,既然方法都只能放到類裏了,那麼,類的一個方法就是一個Service
 
-
 
說到這裏,親愛的讀者朋友,不知道你是不是被我徹底弄糊塗了,既然一直以來,什麼都是Service,那我們現在還提什麼SOA啊?大聲高呼,我們一直都在SOA不就得了,還浪費我這麼多寶貴時間來讀你的狗x臭x文章,真是他xx的。息怒息怒~~
 
其實,您的理解沒錯,Service無處不在,尤其是當Service是按照我在本文開始的定義來理解的話!我還是再把它完整的寫一遍好了:
 
-
Service - 一種執行接口,接受外部的調用請求,請求可以包含0到多個參數,根據參數處理該請求後,返回執行結果,結果包含處理的成功或失敗狀態及0到多個返回參數,其中每個請求參數或返回參數都由一個Key/Value對錶示。
 
Service的特性:
1)封裝了細節,只要接口和返回結果不變,被封裝了的實現細節對用戶並不需要關心;
2)一個Service內部可以調用其它Service來實現,甚至可以遞歸調用Service自身;
-
 
但是~~ 要說SOA中的Service,以上的定義還缺了點東西。缺了什麼呢?缺少了上下文,缺少了依賴關係的限制。
 
以機器指令爲例,一個機器指令如果能被稱爲Service的話,首先他其實隱含了這樣的限制,首先,致令的執行環境是特定的機器,和元件的組成結構,其次,它隱含約定了寄存器、存儲器的數量,名稱,位置,這些和讀取輸入數據,返回執行結果都是密切相關的。如果我從另一臺機器的一個指令直接訪問本機器的一條指令,到然不行,甚至同一臺機器,在不同的隱含約定下,相同的指令的執行效果和功能也可以是完全不同的。
 
再到彙編,到C到C++,Java,C#。。。語言越抽象,越高級這樣的隱性限制和約定越來越少了,但是歸根結底,不管多少,都還是有上下文限制的,或者有語言限制的,就是語言沒限制也可能有運行平臺限制。那麼是不是可能沒有任何限制呢,當我要一個邏輯功能的時候,能不能讓我只要關心結果,不用關心任何限制和細節呢?
 
從哲學的角度講,沒有任何限制是不可能的,記得以前的哲學課上,老師一再強調,任何命題,如果沒有前提條件,沒有任何限制,那它就一定是錯誤的!任何錯誤的命題,只要加上合理的限制,那就一定可能變成正確的!金玉良言,金玉良言啊,同志們!!
 
藉助哲學老師的名言,我們可以重新理解上面的命題:
“是不是可能沒有任何限制呢,當我要一個邏輯功能的時候,能不能讓我只要關心結果,不用關心任何限制和細節呢?”-錯,不可以!
“如果能有統一的輸入輸出接口,能有跨平臺支持的數據交換協議,最好再輔以不同語言環境到同一接口的等價映射的話,能不能讓我只要關心結果,不用關心任何實現細節,互相協同工作呢?”-對了,可以!
 
所以,什麼是SOA,Service Oriented Architecture,什麼是SOA中的Service呢?加上一個限定上下文和條件,在指定的上下文這個前提限制下,還是以前面定義的這個Service的定義爲中心來架構軟件,就是SOA。大,可以大到跨平臺、跨語言甚至更大,小可以小到機器指令,脈衝信號,甚至更小。
 
SOA,不就是那麼簡單嗎?


轉自:

http://www.cnblogs.com/teddyma/archive/2005/11/21/281271.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章