2016-07-29 61 views
0

我喜歡功能風格的編程。但是在我看來,傳遞函數作爲參數有時會在組件之間產生比使用非函數參數傳遞創建的更強的耦合。例如,在下面的(做作)示例中:A,B和C通過C的函數參數的輸出類型,C的int參數的類型以及C的arity和輸入類型函數參數。如果A想要將其功能更改爲BiFunction,則B和C都必須更改。作爲參數的函數:強耦合?

public class Functional { 

    public void A() { 
    C(i -> String.valueOf(i + 2), 123); 
    } 

    public void B() { 
    C(i -> String.valueOf(i + 1), 123); 
    } 

    private String C(Function<Integer, String> f, int a) { 
    int len = String.valueOf(a).length(); 
    return f.apply(len); 
    } 
} 

對比用一個例子,其中A和B計算功能的結果前面,然後傳遞字符串結果和第二int參數C.這裏A,B和C耦合只有兩個地方 - C的兩個參數。計算第一個參數的函數可以自由更改。

顯然傳遞函數有它的位置,但當事情變得更加複雜時,似乎這種問題會複合並創建嚴格的代碼。我很想聽聽用什麼經驗法則來決定何時以這種方式進行耦合與否。

+1

這是一個奇怪的考慮因素。 1)「*如果A想把它的函數改變成BiFunction *」,那麼調用者何時可以決定改變一個方法的參數類型? 'C'提供了一個功能並定義了先決條件; 'A'不需要在這裏「需要」任何東西。 2)如果沒有'C'作爲參數類型的要求,它不應該要求得到一個函數。如果提供的功能需要它,那麼它就沒有了討論。在你的例子中,儘可能地做到這一點,呼叫者不可能預先計算函數的結果。但他們可以*之後*。 – Holger

回答

3

在你的榜樣,我會建議遵循的Single Responsibility

原則莫不是出於同樣的理由改變的東西放在一起。 分開那些因不同原因而改變的東西。

所以選擇以什麼方式將A,B和C結合在一起取決於他們爲什麼要改變。


,從你的例子我想起另一個原則是Rule of least power

給出解決方案的選擇,挑選有能力在你的簡單的例子解決您的問題

最少的強大解決方案函數C不需要函數作爲參數。該功能可以在AB一側調用。

2

如果你用一個函數參數替換一個簡單的值,那麼你正在做一件嚴重錯誤的事情。功能只應該用更緊密的聯軸器代替,通常是應用專用的Interface