儘管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類,而不是改變典型用法。
有人同意/不同意這種觀點嗎?或者也許知道一些優越的方法? (我在這裏省略了混入,我意識到)。
我認爲很大程度上取決於上下文。您的meta方法是全球範圍還是僅在特定情況下有用?我發現我最大的問題是記住添加元方法的位置,以及是否在當前上下文中使用元方法。我曾經多次將它用作一個類別,然後意識到它在全球範圍內更適合應用程序,並將其作爲重構的一部分加入其中。 – dstarh 2010-12-08 20:51:19
@dstarh這很有道理 - 這是我列出就地引導方法和自舉方法的動機的一部分。我認爲將metamethods整合到bootstrap類將是最有組織的方法。我可能是錯的,但我相信這是通常在Grails中採用的方法。它可以讓你控制添加的內容和時間。我只是不喜歡脆弱的因素,也沒有比我必須更復雜的構建過程。從類別開始,但是因爲它們更容易重構,這當然是一種合理的方法。 – Northover 2010-12-08 21:50:02