2010-12-07 36 views
3

儘管Web充斥着大量Groovy元數據編程功能,但我還沒有發現任何與實際使用這些功能相關的綜合「最佳實踐」指南。Idiomatic MetaProgramming

從典型 買者自負警告過度使用的

除此之外,我讀過的意見最具體的一條建議有利於增強元類的使用類別可能時(這實在是加強老成語的另一種方式'有限的範圍')。

常識對於我那些微不足道的項目來說已經足夠了,但是我越來越擔心在解決更多雄心勃勃的任務時從潛在的差異/不一致的先例中構建出來。因此,我非常感謝Groovy的任何建議,資源或具體示例(甚至語言不可知論 - 我對Ruby的簡短經驗讓我同樣想要)元編程最佳實踐。

要澄清的話題,我會提供可能採用元編程在幾個不同的方式(高度)簡化有理數項目:

@Immutable class Rational{ 
    int num, den 

    Rational multiply(Integer v){ 
     new Rational(num:num*v, den:den) 
    } 
} 
assert new Rational(num:1, den:2) * 3 == new Rational(num:3, den:2) 

然而,試圖3*new Rational(num:1, den:2)顯然會產生MissingMethodException。

最簡單的,而且可能至少增加交換特性的脆弱的辦法是用在Rational類的靜態初始化塊:

static { 
    Integer.metaClass.multiply = {Rational fraction -> fraction*delegate} 
} 
... 
assert 3*new Rational(num:1, den:2) == new Rational(num:3, den:2) 

但是,這實際上是全球因此,和相當剛性。

更通用的,或許更有條理的方法是用某種可選的自舉:

class BootStrap{ 
    static void initialize(){ 
     Integer.metaClass.multiply = {Rational fraction -> fraction*delegate} 
    } 
} 

現在我們已經啓用該功能(S),我們希望擁有的選項。然而,這可能會導致各種依賴性問題。

再有就是類..安全露骨,但不完全方便:

@Category(Integer) class RationalCategory{ 
    Rational multiply(Rational frac){ 
     frac*this 
    } 
} 
use(RationalCategory){ 
    assert 3*new Rational(num:1, den:2) == new Rational(num:3, den:2) 
} 

在一般情況下,我發現我修改元類,當我增加新的行爲,但是使用類別時,我可能會改變現有的行爲。例如,覆蓋分部操作員生成分數將最好包含在類別內。因此,解決方案1或2將是「可接受的」,因爲我只是將行爲附加到Integer類,而不是改變典型用法。

有人同意/不同意這種觀點嗎?或者也許知道一些優越的方法? (我在這裏省略了混入,我意識到)。

+1

我認爲很大程度上取決於上下文。您的meta方法是全球範圍還是僅在特定情況下有用?我發現我最大的問題是記住添加元方法的位置,以及是否在當前上下文中使用元方法。我曾經多次將它用作一個類別,然後意識到它在全球範圍內更適合應用程序,並將其作爲重構的一部分加入其中。 – dstarh 2010-12-08 20:51:19

+0

@dstarh這很有道理 - 這是我列出就地引導方法和自舉方法的動機的一部分。我認爲將metamethods整合到bootstrap類將是最有組織的方法。我可能是錯的,但我相信這是通常在Grails中採用的方法。它可以讓你控制添加的內容和時間。我只是不喜歡脆弱的因素,也沒有比我必須更復雜的構建過程。從類別開始,但是因爲它們更容易重構,這當然是一種合理的方法。 – Northover 2010-12-08 21:50:02

回答

1

Groovy in Action中有一章關於元編程的內容,其中涵蓋了相當不錯的主題。一定要獲得第二版(印刷版尚不可用,但可以通過電子格式獲得早期版本),因爲第一版非常過時,特別是在元編程方面。

相關問題