<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      享受代碼,享受人生

      SOA is an integration solution. SOA is message oriented first.
      The Key character of SOA is loosely coupled. SOA is enriched
      by creating composite apps.
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      Separate Contract from Implementation

      Posted on 2006-01-12 14:06  idior  閱讀(3902)  評論(9)    收藏  舉報
              在平時的開發中, 如果你接到的是一個全部由自己團隊開發的項目, 那么恭喜你, 你將擺脫很多讓人煩惱的問題. 然而事情總非如此, 在新項目中使用已有的第三方類庫, 甚至在已有的遺留系統基礎上做開發, 這種事情已經成為必然.
              如果對原有的類庫做一定程度的擴展,加上自己需要的新功能. 這個問題也在我們的開發中一而再的出現. 如果原來的設計良好,遵循OCP(對修改封閉,對擴展開放), 那么這個問題倒還好解決, 但問題是你不會總是那么好運. 看看下面這個例子.
       

          6     public void UseQueue(MessageQueue q)

          7     {

          8         q.Send("Hello!");

          9     }

          
              在這個例子中UseQueue方法就是一個不利于擴展的設計, 在它的參數中使用了MessageQueue這么一個具體類. 這也意味著UseQueue方法將與MessageQueue綁定. 如果我想換一個Queue ( 比如一個叫IBMMQ的類 )的話, 以上所有的UseQueue方法(這里只是一個例子,可以想象會有很多用到Queue的方法)都無法重用.
             
              此時如何處理? 難道祭起copy/paste大法? 最容易想到的一個辦法就是讓IBMMQ繼承于MessageQueue, 然后override 相關方法的實現. 但是我們知道C# 是單繼承的, 你怎么確保IBMMQ沒有繼承于其他類, 而將這個寶貴的機會讓給MessageQueue? 而且繼承的最大優勢在于重用基類的代碼, 但是現在我只是想獲得一個基類的類型和該類型中的方法名. 確切的說我只是想獲得一個MessageQueue的一個隱式接口,而不是它的實現. Martin Folwer將這個想法描述為  ImplicitInterfaceImplementation.

              既然繼承不是一個好的方法, 那么來試試最近很流行的Dynamic Proxy. 讓我們換一個更簡單明了的例子.      

         11     private static void Speak(Dog dog)

         12     {

         13         dog.Talk();

         14     }

         15 

         16     public class Dog

         17     {

         18         public virtual void Talk()

         19         {

         20             Console.Out.WriteLine("arf!");

         21         }

         22     }

         23 

         24     public class Robot

         25     {

         26         public virtual void Talk()

         27         {

         28             Console.Out.WriteLine("Click!");

         29         }

         30     }


               現在我們想讓Speak方法能接受Robot做為參數,去執行Robot的Talk方法. 然而由于靜態類型的限制, 我們是不可能讓Speak方法接受Robot類型的參數的,不過通過Dynamic Proxy我們倒是可以讓Speak去執行Robot的Talk方法.

          6     internal class Program

          7     {

          8         [STAThread]

          9         private static void Main()

         10         {

         11             Dog dog=Dog.DogInstance();

         12             Dog robot=Robot.DogInstance();

         13 

         14             Speak(dog);

         15             Speak(robot);

         16         }

         17 

         18         private static void Speak(Dog dog)

         19         {

         20             dog.Talk();

         21         }

         22     }

         23 

         24     public class Dog

         25     {

         26         public static Dog DogInstance()

         27         {

         28             return new Dog();

         29         }

         30         public virtual void Talk()

         31         {

         32             Console.Out.WriteLine("arf!");

         33         }

         34     }

         35 

         36     public class Robot

         37     {

         38         public static Dog DogInstance()

         39         {

         40             ProxyGenerator generator = new ProxyGenerator();

         41             Dog robot = (Dog) generator.CreateClassProxy(typeof (Dog), new RobertInterceptor());

         42             return robot;

         43         }

         44 

         45         public virtual void Talk()

         46         {

         47             Console.Out.WriteLine("Click!");

         48         }

         49     }

         50 

         51     public class RobertInterceptor : StandardInterceptor

         52     {

         53         public override object Intercept(IInvocation invocation, params object[] args)

         54         {

         55             if (invocation.Method.Name.Equals("Talk"))

         56             {

         57                 Robot robot=new Robot();

         58                 robot.Talk();

         59             }

         60             return null;

         61         }

         62     }


          
              有關Dynamic Proxy(這里用的是Castle)的內容, 本文不作詳細介紹, 在園子里搜索一下你可以找到相關內容. 從上面的程序的輸出結果中你可以看出通過動態代理我們實現了Speak方法的重用, 讓它可以間接的使用Robot的Talk方法.          

                   
      Tip一個類A和另一個類B發生關聯, 有兩種形式: 1. A創建B     2: A使用B
      那么請你考慮遵循下面的原則:
      A
      要么創建B,要么使用B.不要同時創建并使用B.
      這樣可以為你的代碼帶來更強的擴展性(方便的替換B的實例).

         32     class A

         33     {

         34         public void Method()

         35         {

         36             //Bad way

         37             //B b=new B();

         38             //b.Method1();

         39 

         40             //Good way

         41             B b=B.GetInstance();

         42             b.Method1();

         43         }

         44     }

               上面用Dynamic Proxy的方法雖然可行,但是實在過于繁瑣,而且看上去非常的丑陋. 來看看C++怎么處理這個問題的.

          6 class Dog { public: void Talk() { cout << "arf!" << endl; };

          7 class Robot { public: void Talk() { cout << "Click!" << endl; };

          8 

          9 template < class T > void Speak( T spkr ) { spkr.Talk(); }

         10 

         11 int main() {

         12     Dog d;

         13     Robot r;

         14     Speak(d);

         15     Speak(r):

         16 }

            
              由于C++的template沒有類型的約束, 給出一個非常漂亮的解決方案. 不過C#, java的泛型可就望洋興嘆了. 

              動態語言面對這個問題就更是一笑了之了.   

      def speak(anything):

          anything.talk()

       

      class Dog:

          def talk(self): print "arf!"

          def reproduce(self): pass

         

      class Robot:

          def talk(self): print "Click!"

          def oilChange(self): pass

       

      dog = Dog()

      robot = Robot()

      speak(dog)

      speak(robot)

              
              由于Duck Typing的特性, 使得Robot類只需要有一個叫做Talk的方法就可以被調用到,根本不受到參數類型的限制.

      Summary:

              其實以上的方法都是一種亡羊補牢的辦法. 但是這種情況幾乎是無法避免的.同時你應該思考是什么原因導致了這種問題的產生?      

          5     public interface ITalkable

          6     {

          7         void Talk();

          8     }

          9 

         10     public class Dog : ITalkable

         11     {

         12         public virtual void Talk()

         13         {

         14             Console.Out.WriteLine("arf!");

         15         }

         16     }

         17 

         18     public class Robot : ITalkable

         19     {

         20         public virtual void Talk()

         21         {

         22             Console.Out.WriteLine("Click!");

         23         }

         24     }

         25 

         26     internal class Program

         27     {

         28         [STAThread]

         29         private static void Main()

         30         {

         31             ITalkable dog = new Dog();

         32             ITalkable robot = new Robot();

         33             Speak(dog);

         34             Speak(robot);

         35         }

         36 

         37         private static void Speak(ITalkable talker)

         38         {

         39             talker.Talk();

         40         }

         41     }

        
            如果這樣做你還會有以上的問題嗎? Design to interface.可以說是面向對象的核心概念之一. 你應該盡可能得將Contract和Implement分離開來. COM就強制你必須這么做. C#,Java給了你自由,它沒有強制你這么做, 但是你應該盡可能這么做, 不然你就象最開始那個例子,被MessageQueue限制死了,也使得很多的使用了MessageQueue的代碼無法得到重用.

              聽說過Web Service嗎? Contract都用xml(WSDL)來定義了.

      主站蜘蛛池模板: 国语精品一区二区三区| 黄色亚洲一区二区三区四区| 激情综合网址| 亚洲av无码精品色午夜蛋壳| 欧洲亚洲色一区二区色99| 国产精品丝袜亚洲熟女| 欧洲中文字幕国产精品| 激情文学一区二区国产区| 精品无码三级在线观看视频| 国产av丝袜旗袍无码网站| 18禁视频一区二区三区| 毛茸茸性xxxx毛茸茸毛茸茸| 久草热在线视频免费播放| 亚洲综合色成在线观看| gogogo高清在线观看视频中文| 国产精品一码二码三码四码| 成人免费A级毛片无码网站入口| 亚洲国产精品高清线久久| 免费a级毛片无码av| 湘潭县| 日韩一区二区三在线观看| 精品乱码一区二区三四五区| 男人狂桶女人出白浆免费视频 | 国产av一区二区三区久久| 亚洲精品日韩在线丰满| 亚洲午夜无码久久久久蜜臀av| 国产高清小视频一区二区| 一面膜上边一面膜下边视频| 漂亮人妻被强中文字幕久久| 丰满少妇内射一区| 高要市| 婷婷综合缴情亚洲| 国产成人一区二区三区在线| 熟妇的味道hd中文字幕| 福利视频一区二区在线| 中文人妻av高清一区二区| 青青草国产精品日韩欧美| 性视频一区| 九九热视频在线观看精品| 国产成人久久综合一区| 免费现黄频在线观看国产 |