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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

论面向组合子程序设计方法 之 创世纪

發布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 论面向组合子程序设计方法 之 创世纪 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
發現老莊的連載方法很好.又能吸引眼球又能好整以暇.于是從善如流.?


這幾天在完善我的neptune系統和jaskell語言。順手發現了一個logging的需求。如獲至寶阿。?

為什么呢?不是因為這個需求多么難,或者我的解決方法多么巧妙,而是因為,這個例子足夠簡單,直觀,要說明它,背景知識幾乎不大需要,三兩句話大家就明白需要達到什么效果。這種例子可不是隨便就想得到的。?

而同時,它又對實現提出了一定程度的靈活性要求,正好方便我展示我叫做“面向組合子”的程序設計方法。?


說到這里,不禁又有點沮喪,我也挺想象別人那樣,先高舉高打,玄之又玄,弄些哲學思辨,什么佛法呀,道德經阿,西游記亞,以及各位西方先哲的亟語,甚至量子力學的悖論。這樣才能吸引眼球,增加人氣呀。?
可是,等而下之的工匠氣作祟,說著說著就要拐到具體例子上去了。不爭氣呀。?


算了,不想那么多了。論道不是俺這種俗人所擅長的,還是鼓搗“器”吧。?


大致的背景是這樣:?
我的neptune是一個build system,在build的過程中會產生很多log信息。這些信息分為不同的重要級別。?

說到這里,肯定有人已經按奈不住:用Log4j!?

先不要急,我們這里不是要告訴你怎么處理你得程序中的logging需求,而是要通過這樣一個容易理解的例子來說明以下“面向組合子”的編程方法。所以,這里讓我們先假設我們不知道什么log4j。什么是log4j呀??

當然,大致的思路總歸差不多的。因為我的neptune系統只需要一個logging的工具,而不關心這個logging工具是什么,這就是一個perfect的依賴注射的場合。?

先定義接口Logger,然后從構造函數傳遞近來一個Logger實例,接著就直接調用Logger就是了。?

Java代碼??
  • public?interface?Logger{??
  • ??void?print(int?level,?String?msg);;??
  • ??void?println(int?level,?String?msg);;??
  • ??void?logException(Throwable?e);;??
  • }??


  • print用來輸出信息,但是不折行,println可以折行。?
    logException用來直接紀錄異常。這樣,對異常是直接printStackTrace,還是println(e.getMessage())就是由具體的Logger實現來決定,我的neptune只需要把遇到的異常報告給Logger就是了。?


    好。接下來我吭哧吭哧地把neptune完成了,剩下的就是從哪里找一個Logger實現了。?

    最簡單的Logger實現自然就是直接往屏幕上打印了:?

    Java代碼??
  • class?SimpleLogger?implements?Logger{??
  • ??public?void?print(int?lvl,?String?msg);{??
  • ????System.out.print(msg);;??
  • ??}??
  • ??public?void?println(int?lvl,?String?msg);{??
  • ????System.out.println(msg);;??
  • ??}??
  • ??public?void?printException(Throwable?e);{??
  • ????e.printStackTrace();;??
  • ??}??
  • }??


  • 直接把這個SimpleLogger注射進我的neptune,整個系統就可以工作了。?
    no big deal,對么??


    好了,下面我們開始真正實現完整的logging系統了。經過分析,我們大致有以下的需要:?

    [list]1。logger可以把信息打印到log文件中。?

    2。不同的重要程度的信息也許可以打印到不同的文件中?象websphere,有error.log, info.log等。?
    如果這樣,那么什么重要程度的信息進入error.log,什么進入warning.log,什么進入info.log也需要決定。?

    3。也許可以象ant一樣把所有的信息都打印到一個文件中。?

    4。每條logging信息是否要同時打印當前的系統時間?也是一個需要抉擇的問題。?

    5。不僅僅是log文件,我們還希望能夠在標準錯誤輸出上直接看見錯誤,普通的信息可以打印到log文件中,對錯誤信息,我們希望log文件和標準輸出上都有。?

    6。標準輸出上的東西只要通知我們出錯了就行,大概不需要詳細的stack trace,所以exception stack trace可以打印到文件中,而屏幕上有個簡短的exception的message就夠了。?

    7。warning似乎也應該輸出到屏幕上。?

    8。不管文件里面是否要打印當前系統時間,屏幕上應該可以選擇不要打印時間。?

    9。客戶應該可以通過命令行來決定log文件的名字。?

    10。客戶可以通過命令行來決定log的細節程度,比如,我們只關心info一樣級別的信息,至于debug, verbose的信息,對不起,不要打印。?

    11。neptune生成的是一些Command對象,這些對象運行的時候如果出現exception,這些exception會帶有execution trace,這個execution trace可以告訴我們每個調用棧上的Command對象在原始的neptune文件中的位置(行號)。?
    這種exception叫做NeptuneException,它有一個printExecutionTrace(PrintWriter)的方法來打印execution trace。?
    所以,對應NeptuneException,我們就不僅僅是printStackTrace()了,而是要在printStackTrace()之前調用printExecutionTrace()。?


    12。neptune使用的是jaskell語言,如果jaskell腳本運行失敗,一個EvaluationException會被拋出,這個類有一個printEvaluationTrace(PrintWriter)的方法來打印evaluation trace,這個trace用來告訴我們每個jaskell的表達式在腳本文件中的位置。?
    所以,對應EvaluationException,我們要在printStackTrace()之前,調用printEvaluationTrace()。?

    13。execution trace和evaluation trace應該被打印到屏幕上和log文件兩個地方。?

    14。因為printExecutionTrace()和printEvaluationTrace()本身已經打印了這個異常的getMessage(),所以,對這兩種異常,我們就不再象對待其它種類的異常那樣在屏幕上打印getMessage()了,以免重復。?

    15。也許還有一些暫時沒有想到的需求, 比如不是寫入log文件,而是畫個圖之類的變態要求。[/list:u]?

    大致上,我目前遇到的需求也就是這些了。?

    好了,允許我賣個關子,下回分解的時候再說怎么用“面向組合子”和依賴注射的方法來解決這個問題吧。?

    在本節結束之前,我稍微提一下“面向組合子”的來歷。?


    組合子,英文叫combinator,是函數式編程里面的重要思想。如果說OO是歸納法(分析歸納需求,然后根據需求分解問題,解決問題),那么“面向組合子”就是“演繹法”。通過定義最基本的原子操作,定義基本的組合規則,然后把這些原子以各種方法組合起來。我最近一段時間做的東西,jaskell不用說了,函數式語言。yan, neptune, jparsec全是用面向組合子的思想開發的。?

    OO就像是猜謎,給你一個蘋果,然后問你:這個蘋果是怎么得到的呢?然后你分析一番,說:我認為這個蘋果是由分子組成的,這些分子如此這般排列,然后分子又由原子組成,如此這般排列...?

    而CO(面向組合子),就等于是說:這有H, C, O三種原子,強弱兩種作用力,你來看看能做點什么出來吧,然后你就像搭積木一樣,把這三種原子,兩種作用力搭建出這大千世界,什么毛毛蟲,狗熊,周星星,不小心,一下就做出了一個蘋果。?

    OO的關鍵是需求。?
    所謂"refactor",不過也是強調需求,讓你不要自作聰明地瞎假設需求而復雜化設計。時刻著眼于當前的需求。這樣,一旦需求變更,所浪費的力氣可以保證最小,而且,船小才好調頭嘛。?
    如果需求分析的不好,一切就歇菜了,雖然因為一些比如ioc之類的設計方法能讓你不至于推到重來,但是需求仍然是重中之重。?


    那些什么上下文沒有,上來就說“怎么用OO來做一個人騎車呀?”,“是人.騎(車)呀?還是車.被騎(人)?”純粹是沒頭沒腦地瞎掰。?

    而CO的關鍵則是組合子和組合規則的設計。這些組合方法必須非常精巧,盡量正交。組合子的設計既要簡單(越簡單才越容易被組合),還要完整。?
    比如說,對整數這個組合子,我們有+-*等組合方法,這樣只要有了0,1這兩個組合子,我們就可以構造出整個整數世界。?
    可是,精巧的組合子設計也不是那么容易的。需要有一點點數學的感覺和嚴密的邏輯思維基礎。?


    有人說,上帝是用OO設計的世界,可要我是上帝,我寧可用CO。?
    設計幾個簡單的基本粒子,幾個簡單的相互作用力,然后讓這些東西自己組合,隨意發展,不是比事必躬親,先想透徹了自己想讓世界是什么樣子,然后一張一張圖紙地具體設計,一個一個人地造,?
    “撒旦,你去干壞事,往死了整這幫賤人!”?
    “天使,你去干好事,打個巴掌再給他們點甜棗吃?!?
    “兒子,你下去混混,看丫敢不敢釘死你!”?
    來的容易美妙??

    哈。終于形而上起來了,爽!

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

    總結

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

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