日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

论面向组合子程序设计方法 之 重构2

發(fā)布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 论面向组合子程序设计方法 之 重构2 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
已經(jīng)有點感覺用ioc container來說明co不見得是個好主意了。?
這個container的例子舉出來,明顯提出意見的人比那個簡單的logging例子少了很多。?
畢竟連pico是怎么回事,怎么用,很多人都還不見得了了。更不提多少人對pico的用法就是一個很in的fancy factory。買櫝還珠。?



不過,既然開始了,讓我還是有始有終吧。?


這章還是讓我們看看co的refactor。?

其實,很多人問:怎樣把握co里面的基本組合子的度;什么樣的組合子算是基本;怎樣做到正交;多少的基本組合子才算夠用;怎么知道這個組合子會被用到等等。?


其實,答案都來自重構。?

沒有誰一下子就作對的。co比起oo,我感覺在設計上反而更容易避免過度設計。?

為什么??

設計oo的時候,你要分析需求,設計各個模塊的通信接口,這個過程,同樣需要經(jīng)驗,同樣需要摸索,同樣沒有一踀而就的捷徑。?

但是,oo設計的時候又要避免過度,一些時候,在是否通過接口預留靈活性,提取容易變化的部分,或者是盡量簡單之間,還是有沖突的。你需要做一個艱難的猜測和抉擇。?
而一旦抉擇作出,以后如果發(fā)現(xiàn)事情進展不如所愿,那么改動接口的代價相當?shù)拇蟆?


而如果使用co,在設計簡單的各個組合子的時候,你會以一種非常漸進式的方式來發(fā)現(xiàn):哦,原來的組合子設計不夠正交,有這個地方可以抽出來,好,抽出來,把波及到的幾個組合子的設計修改一下。?

因為組合子都非常簡單,這個變化的波及范圍一般來說相當小。?


好,空話少說,我們還是看具體例子。?


現(xiàn)在,我們發(fā)現(xiàn),除了withArgument, withProperty,我們還希望更靈活地設置參數(shù),比如,我們希望說:?
[list]對組件X的各個參數(shù),類型為A的,選取以"a1"標識的組件作為參數(shù)值,其它的按照缺省方式。?
對組件Y的各個參數(shù),類型為A的,選取以"a2"標識的組件為參數(shù)值,其它的按照缺省方式。[/list:u]?


這個需求有幾個點:?
[list]1。需要能夠通過key來直接指定某個某個組件,相當于一個"ref"。?
2。需要對參數(shù)配置有除了按照參數(shù)位置之外的更靈活的配置(比如,按照參數(shù)類型)。[/list:u]?


對第一點,我們制作以下的組合子來對應。(看,我們是可以隨著需求雖然豐富我們的基本組合子的集合的)?
我們期望做一個UseKey組合子,它可以從容器里面取得另外一個用某個key標識的組件,然后把一切動作都delegate過去。?

Java代碼??
  • class?UseKey?extends?Component{??
  • ??private?final?Object?key;??
  • ??public?Object?create(Dependency?dep);{??
  • ????//???????????
  • ??}??
  • ??....??
  • }??



  • 可是,一開始寫代碼,就發(fā)現(xiàn),這個代碼寫不下去!我們需要得到這個容器,才能從這個容器里面取得那個要delegate的組件。可是這個可愛容器對象在哪里呀??

    仔細分析下來,發(fā)現(xiàn),沒有辦法。唯一的辦法是修改Dependency接口,讓它除了幫助解析參數(shù)和property之外,再提供給我們當前容器的信息。?

    Dependency接口變?yōu)?#xff1a;?


    Java代碼??
  • interface?Dependency{??
  • ??Object?getArgument(int?i,?Class?type);;??
  • ??Object?getProperty(Object?key,?Class?type);;??
  • ??Container?getContainer();;??
  • }??



  • Wow!要改接口了!其實,這一點也不可怕。為什么??

    co還有另外一個優(yōu)點我們一直沒有提及:細節(jié)封裝。這個封裝不是一般OO意義上的封裝,而是說:把要實現(xiàn)的接口細節(jié)封裝起來,讓客戶通過預定義好的組合方式來擴展,而不是象oo那樣讓用戶實現(xiàn)實現(xiàn)這個接口來擴展。?

    其實,如果用戶使用的都是Component對象,而創(chuàng)建Component對象都是通過:?
    Java代碼??
  • Container.getInstance(Object?key);;??

  • 這種方式,那么,Dependency這個接口已經(jīng)實際上淪為我們的內部實現(xiàn)細節(jié)了。用戶根本不需要知道存在這么一個接口。?
    實際上,當我們的組合子足夠豐富之后,完全可以把Dependency接口隱藏在包內部,徹底地對用戶屏蔽這個接口。?
    如此,客戶的擴展完全通過組合Component對象,而不是實現(xiàn)Component接口并且調用Dependency接口。?
    不管這個Dependency接口是如何設計的,如何變化,我們都可以把變化隔離在我們包內部,而不會影響用戶。?

    好吧。現(xiàn)在假設我們修改了Dependency接口,那么UseKey可以被寫為:?

    Java代碼??
  • class?UseKey?extends?Component{??
  • ??private?final?Object?key;??
  • ??public?Object?create(Dependency?dep);{??
  • ?????final?Component?c?=?dep.getContainer();.getComponent(key);;??
  • ?????if(c==null);throw?new?ComponentNotFoundException(...);;??
  • ?????return?c.create(dep);;??
  • ??}??
  • ??....??
  • }??



  • 然后,更靈活的參數(shù)配置。對這個,我們可以借鑒bind操作,做一個對參數(shù)的bind。?


    Java代碼??
  • interface?ParameterBinder{??
  • ??Component?bind(int?i,?Class?type);;??
  • }??

  • 不知道你從Binder接口和ParameterBinder接口看出點什么沒有??
    1。Binder, ParameterBinder接口都是給用戶去實現(xiàn)的。?
    2。這兩個接口都不暴露Component的細節(jié),它們的參數(shù)和返回值都不涉及Component的接口簽名,客戶在實現(xiàn)這兩個接口的時候,完全不必關心象Dependency接口這種細節(jié)。?
    3。返回值都是Component,這樣,所有的Component組合子都可以被自由使用。?

    實際上,monad組合子就是通過這種方式來在高階邏輯的層次上隱藏底層細節(jié)。?



    Java代碼??
  • class?ParameterBoundDependency?implements?Dependency{??
  • ??private?final?Dependency?dep;??
  • ??private?final?ParameterBinder?binder;??
  • ??public?Object?getArgument(int?i,?Class?type);{??
  • ????return?binder.bind(i,?type);.create(dep);;??
  • ??}??
  • ??...??
  • }??

  • Java代碼??
  • ParameterBoundComponent?extends?Component{??
  • ??private?final?Component?c;??
  • ??private?final?ParameterBinder?binder;??
  • ??public?Object?create(Dependency?dep);{??
  • ????return?c.create(new?ParameterBoundDependency(dep,?binder););;??
  • ??}??
  • ??...??
  • }??

  • 用ParameterBinder來做一個Dependency的decorator,問題得到了解決。?


    然后我們來使用ParameterBoundComponent,為了書寫簡便,我們假設Component類有一個函數(shù)叫做bind(ParameterBinder binder)。另外Components類有一個useKey(Object key)函數(shù)來生成一個Component對象,用來指向容器內的另外一個組件。?

    于是,上面的需求被實現(xiàn)為:?

    Java代碼??
  • Component?x?=?...;??
  • Component?x2?=?x.bind(new?ParameterBinder();{??
  • ??public?Component?bind(int?i,?Class?type);{??
  • ????if(type.equals(A.class););{??
  • ??????return?Components.useKey("a1");;??
  • ????}??
  • ????else{??
  • ??????//?????行1??
  • ????}??
  • ??}??
  • });;??

  • 這個x2組件,就是為了實現(xiàn)“當參數(shù)類型為A,使用a1,否則使用缺省方式”。?
    可是,在行1處,再次遇到了障礙。這個所謂的“缺省方式”,怎么表示??
    。?

    經(jīng)過思考,我們決定實現(xiàn)一個useArgument(int i, Class type)這樣一個組合子,這個組合子可以主動在當前的Dependency對象中選擇某個參數(shù)作為自己的值。這樣,上面的行1就可以寫作:?
    Java代碼??
  • Component?x?=?...;??
  • Component?x2?=?x.bind(new?ParameterBinder();{??
  • ??public?Component?bind(int?i,?Class?type);{??
  • ????if(type.equals(A.class););{??
  • ??????return?Components.useKey("a1");;??
  • ????}??
  • ????else{??
  • ??????return?Components.useArgument(i,?type);;//?行1??
  • ????}??
  • ??}??
  • });;??


  • 下面來實現(xiàn)一個UseArgument類:?

    Java代碼??
  • class?UseArgument?extends?Component{??
  • ??private?final?int?i;??
  • ??private?final?Class?type;??
  • ??public?Object?create(Dependency?dep);{??
  • ????return?dep.getArgument(i,?type);;??
  • ??}??
  • ??.....??
  • }??


  • 哈。完美。一切仍然盡在掌握。?
    我們可以以幾乎任何方式來customizer組件的參數(shù)和property。?

    實際上,如果我們回頭看看,甚至可以發(fā)現(xiàn),withArgument(int i, Class type)完全可以用bind(ParameterBinder)來重寫:?
    Java代碼??
  • Component?withArgument(Component?c,?final?int?i,?final?Component?arg);{??
  • ??return?c.bind(new?ParameterBinder();{??
  • ????public?Component?bind(int?k,?Class?type);{??
  • ??????if(k==i);?return?arg;??
  • ??????else?return?Components.useArgument(k,?type);;??
  • ????}??
  • ??});;??
  • }??


  • 我們很開心地看到,原來的WithArgument類,WithProperty類都可以掃進垃圾箱了。我們只需要實現(xiàn)更加簡單的ParameterBinder接口就可以搞定一切。哈。?


    同時,希望你也看到了隱藏這些具體的WithArgument,ValueComponent類,而用靜態(tài)工廠函數(shù)withArgument(), value()來代替的好處:?
    我們可以自由地重構。當發(fā)現(xiàn)某個組合子本身并非最簡單,而是可以從一些更簡單的組合子推演出來,我們只需要改動這些靜態(tài)工廠函數(shù),而不必告訴用戶:對不起,我的設計改了,不想要WithArgument類了,你能不能改改你的那段new WithArgument(...)的代碼??


    co讓用戶只關注接口,而不要管某個功能是直接實現(xiàn)的,還是組合出來的。靜態(tài)工廠函數(shù)提供了對這個細節(jié)的封裝。?


    另外一個也許會比較常見的需求,是用一個數(shù)組來一次性指定某個組件的所有參數(shù),比如:?

    Java代碼??
  • c.withArguments(new?Component[]{c1,?c2,?c3});;??


  • 這個功能用bind非常非常好實現(xiàn):?

    Java代碼??
  • Component?withArguments(final?Component[]?args);{??
  • ??return?bind(new?ParameterBinder();{??
  • ????public?Component?bind(int?i,?Class?type);{??
  • ??????return?args[i];??
  • ????}??
  • ??});;??
  • }??


  • 當然,你還可以舉一反三地提出很多其它的定制參數(shù)和property的方法。?


    好了。今天就到這里。在結束前,我來先提出兩個新的需求:?
    1。希望對一些用到Logger對象的類注射Logger實例,而這個Logger實例需要用這個使用Logger對象的類對象來創(chuàng)建,這樣,這個Logger對象可以靜態(tài)地知道誰在使用它,而不必每次都構造一個異常來取得StackTrace。?
    比如,?
    Java代碼??
  • new?ClassX(...,?Loggers.instance(ClassX.class);,?...);;??

  • 怎樣在容器級別全局地規(guī)定這個規(guī)則呢?我們不知道哪些組件需要注射Logger,也不知道這些組件在哪個參數(shù)注射Logger對象。?

    2。怎樣提供缺省參數(shù)?這樣,如果某個參數(shù)的需要可以在容器中解析,則擁這個解析出來的實例,否則,使用一個缺省組件。?

    在下一節(jié),我們會通過這兩個例子來繼續(xù)解釋co的重構過程。


    from:http://ajoo.iteye.com/blog/23329

    總結

    以上是生活随笔為你收集整理的论面向组合子程序设计方法 之 重构2的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美不在线| 日韩 欧美 自拍 | 黄网免费视频 | 欧美大片www | 亚洲午夜久久久久久久久 | 美日韩久久 | 成人在线免费电影 | 亚洲福利在线观看 | a级免费网站| 日本公与丰满熄 | 青青草国产精品视频 | 中文字幕免费在线观看视频 | 成人a毛片久久免费播放 | 伊人22| 国产伦理自拍 | 邻居校草天天肉我h1v1 | 国产精品爽爽 | 蜜臀久久99精品久久久画质超高清 | 精久久久久久 | 精品欧美乱码久久久久久1区2区 | 天天操夜夜操夜夜操 | 国产区91| 91免费国产在线 | 天天爱天天做 | 自拍偷拍校园春色 | 成人写真福利网 | 欧美色88| 男女做那个视频 | 国产专区一区二区 | 婷婷俺也去 | 一本久道久久综合无码中文 | 国产精品夜夜夜爽张柏芝 | 亚洲aa在线 | 国产福利一区二区三区 | 日韩精品一区二区三区无码专区 | 台湾综合色| 疯狂做爰的爽文多肉小说王爷 | 大地资源影视在线播放观看高清视频 | 国产成人无码精品久久二区三 | 欧美二级片 | 成人教育av| 久操视频在线播放 | 大胸美女被爆操 | 精品一区视频 | 欧美做受视频 | 奇米影视av | 村上凉子av| 综合久久一区 | 人人澡澡人人 | 一区二区三区丝袜 | 天堂激情网 | 久操中文| 韩国伦理片在线播放 | 国产伦理自拍 | 男男啪啪无遮挡 | 国产一级α片 | 精品动漫3d一区二区三区免费版 | 国产18p | 亚洲国产第一区 | 国产午夜视频 | 国产日产精品一区二区三区 | 夜夜嗨av一区二区三区 | 国产在线aaa | 爱爱视频一区二区 | 伊人网在线播放 | 黄色一级片国产 | 美国三级a三级18 | 国产精品久免费的黄网站 | 国产精品欧美久久久久天天影视 | 一级全黄男女免费大片 | 无码人妻精品一区二区蜜桃色欲 | 国产一区二区在线电影 | 美女作爱网站 | 蜜桃视频色 | 一区二区在线播放视频 | 爱情岛成人 | 亚洲 欧美 成人 | 亚洲久久影院 | 在线观看一区二区三区四区 | 国产精品秘入口18禁麻豆免会员 | 欧美成年人在线观看 | 欧美高清在线一区 | 网站免费黄色 | 丁香花完整视频在线观看 | 国产激情一区二区三区 | 网站av在线| 在线a免费 | 日本一区二区免费电影 | 婷婷激情影院 | 草莓视频在线观看18 | 红桃视频隐藏入口 | 国产精品av一区 | 黄色中文字幕 | 五月综合激情 | 国产成人中文字幕 | 香蕉久久av| 国产又粗又长又黄 | 亚洲成人一区在线观看 | 欧美 日韩 视频 |