2012-10-19 56 views
1

我有兩個類,一個取決於另一個。它的實現是這樣的:合作咖啡標記服務/類

class myns.ClassA 
    constructor(@serviceB): -> 

    publicFunctionA: -> 
    privateFunctionB.call this 

    privateFunctionB = -> 
    @serviceB.someFunction() 

然後我初始化它的膠件:

myns.classA = new myns.ClassA(myns.serviceB) 

,並使用如:

myns.classA.publicFunctionA() 

這裏的問題是我想從訪問serviceB privateFunctionB。除了使用call之外,還有更好的方法嗎?或者也許我的整個方法受到我的Java背景的太多影響?我需要的是相互依賴的代碼模塊,它與單件服務相當。我知道我可以使用coffeescript類的功能,避免瞬間,但如何處理以乾淨的方式注入serviceB然後呢?

回答

1

關於你提到的關於Java成語問題:

沒有的公共和私人在CoffeeScript的概念。您的privateFunctionB只是在課程結束時聲明的普通函數。一般來說,模擬私有函數並不是一個好習慣,因爲這樣的函數具有非常不同的語義(例如,如果privateFunctionB是班級以外的變量,它將被覆蓋,而publicFunctionA不存在這種風險)。 。

因此最好是寫兩個功能爲正常類屬性(也就是你所謂的公共職能然後你的代碼可以簡化爲這樣:

class myns.ClassA 
    constructor(@serviceB): -> 

    functionA: -> 
    @functionB() 

    functionB: -> 
    @serviceB.someFunction() 

你可以爲單身樣做的另一件事你可以在CS而不是在java中做的事情是使用全局變量,這通常不被認爲是最佳實踐,但它取決於你的應用程序(例如,如果編寫庫代碼,這是一個很大的問題,但最終可能會好起來用戶類型的東西,取決於使用情況)

此外,你可以也考慮避免整個班級的事情,只是把它寫成一個普通的對象,這可能是一個好主意,如果不會有任何實例,並且你打算不做子類化等。

+0

謝謝,我可能會偏向於以前的經歷,是真的。我剛剛發現有關require.js,也會考慮這個來管理依賴關係。 – mrembisz

2

您可以將ClassA實例作爲參數傳遞給私有函數,而不是this。如果你將每個類保存在自己的文件中,然後在沒有--bare選項的情況下編譯,我建議將該私有函數放在類之外,並將其作爲普通函數使用(它對於文件來說是私有的,所以不需要擔心外界泄露的東西):

privateFunctionB = (a) -> 
    a.serviceB.someFunction() 

class myns.ClassA 
    constructor(@serviceB): -> 

    publicFunctionA: -> 
    privateFunctionB @ 

你也可以把該函數的類裏面,如果你不喜歡它是在文件的頂層(我寧願把它那裏,因爲我認爲這是比較容易理解這只是一個簡單的功能)。

+0

我在想這樣的事情,謝謝一堆。我主要想知道在這種情況下什麼是公認的做法。可以試試。 – mrembisz

+0

@mrembisz,不幸的是,我認爲沒有關於如何在JS中執行私有方法/屬性的共識。以非常「適當」的方式處理方法隱私的一種方法是使用[Crockford的「特權」方法加上私密關閉變量](http://www.crockford.com/javascript/private.html)(另請參閱[這個答案](http://stackoverflow.com/a/55637/581845))。該方法的缺點是使用私有方法(即特權)的公共方法需要在構造函數中而不是在原型中聲明,從而在每個實例上重複它們。 (待續......) – epidemian

+0

我也看到了用於表示屬性和方法的隱私的前導分號,這是一個簡單的約定,可能比Crockford的特權方法更容易理解。當然,不利的一面是,所有這些下劃線都污染了代碼,並沒有太多好處。一般來說,我儘量減少對對象中私有可變狀態(屬性)的需求,並將私有函數實現爲單獨的函數(如在此答案中)。 – epidemian