2015-08-22 23 views
0

我剛剛回答了另一個問題(Select method based on field in class),我在想這個模式是否有名字。這種「電話倒置」模式是否有名字?

電話action.applyX(a),其中X取決於a(在本例中例如type)的一些屬性,讓你改爲調用a.apply(action),讓a(或Type)調用相應的applyX

這是否有一個名稱?

public enum Type { 
    INTEGER { 
     @Override 
     public void apply(Action action, A a) { 
      action.applyInteger(a); 
     } 
    }, 
    STRING { 
     @Override 
     public void apply(Action action, A a) { 
      action.applyString(a); 
     } 
    }; 
    public abstract void apply(Action action, A a); 
} 

public interface Action { 
    public void applyInteger(A a); 
    public void applyString(A a); 
} 

public class A { 
    private Type type; 
    ... 
    public void apply(Action action) { 
     this.type.apply(action, this); 
    } 
} 

更新

上面的僅僅是一個例子,以及使用type作爲選擇不是重要的部分。

決定調用哪個方法的選擇標準可以是任何東西。在骰子游戲中,X可能是'Odd'或'Even',而A可能是'Dice',其值爲1-6 int

該示例使用抽象enum方法作爲避免switch語句(較少出錯)的方式。抽象方法的實現是一種交換技術,在這種情況下,選擇適當的方式X

更新2

這個問題是關於用於避免開關語句做類(A)以外「動作」邏輯的圖案,而不是要改變的A行爲(策略/策略),其中「開關選擇」已被很好地定義,例如作爲類型枚舉(上面的示例),或者通過A的衆所周知的子類。

作爲示例,A可以定義表列。該類不應與實現代碼緊密耦合,但會有許多不同的實現方法(「操作」)必須以不同的方式處理列類型。

行動可能是適當的getXxx方法的調用上ResultSet,調用相應的setXxx方法上PreparedStatement,格式化用於顯示的值,使其在XML或JSON,解析值,...

所有這些方法可能需要switch聲明,他們可以實現與「類型」方法的接口,並要求班級「請爲我打電話」。

這個問題變得相當長。對不起,如果我不明確說明模式。

+1

戰略模式中剝皮貓的一種方法。 – Roam

+0

當你提出一個合理的問題時,你不討厭它;然後兩年後,有人來不及解釋呢?在您的活動儀表板上發生了-2 ...。有趣的是,我們如何從今天早上的評論中獲益於我的答案;-) – GhostCat

回答

6

這類似於Visitor pattern,因爲你基本上是增加新的操作A不改變它(你是外化的操作,以單獨的類)。

this.type.apply(action, this);

扮演的角色:

visitor.visit(this);

如果添加一個新的動作(比如applyBoolean),你需要,如果你使用switch語句來更改代碼A。但是,在您的實現中,您只需使用新的訪問者子類(一個新的Type枚舉常量),該實現代碼將被放置在A中。

+0

謝謝,那就是我一直在尋找的東西。 wiki顯示了子類的例子,所以接口使用方法重載,但由於我的例子使用了枚舉,我的接口必須以不同方式命名方法。同樣的模式。 – Andreas

+1

@Andreas您的標題是「call-inversion」的部分內容:https://en.wikipedia.org/wiki/Double_dispatch – michaelsnowden

0

我認爲這個名字只是所用語言功能的名稱polymorphism

+1

多態不是更多關於繼承?因爲我的例子使用'type'作爲選擇器,所以我可以看出爲什麼多態*可能是合適的,但是我的問題意圖更通用。如果選擇器是「A」的某個整數屬性的奇數/偶數測試呢? – Andreas

0

貌似類型分解,你會發現在函數式語言

+0

我不熟悉函數式編程。一個簡單的谷歌搜索「類型分解」似乎沒有拿出一個很好的參考。你有鏈接到類型分解的解釋嗎? – Andreas

+0

似乎與此類似。 (xs)+「)+ pCons(xs)+」)。 「 } – toskv

+0

確實一個鏈接似乎更好。試試這個:http://ascendant76.blogspot.ro/2012/10/scala-pattern-matching-decomposition.html – toskv

0

我會說這是一個使用strategy pattern的例子。維基百科文章(用C#編寫)中的示例也使用枚舉。

+0

我沒有看到在那裏使用枚舉。 – Andreas

+0

對不起,我匆匆讀過這個例子。這不是一個實際的枚舉,而是一個實現通用接口的內部類的(可枚舉)列表。不過,您可以使用枚舉更優雅地編寫相同的東西。 [本答案](http://stackoverflow.com/a/24435279/905488)實際上包含使用枚舉在Java中重寫的示例。 –

2

這是一個Strategy Pattern

Strategy Pattern Wikimedia

的開端這是一個Behavorial模式,而不是更常見的結構模式。

在您的示例中,您沒有充分利用該模式。由於您使用一個單一的界面爲所有策略

在計算機編程,策略模式(又稱政策模式)是一種軟件設計模式,使在運行時選擇的算法的行爲。

+0

策略/策略模式是關於改變某些邏輯的行爲。所討論的模式不是試圖改變'A'的行爲,而是爲''A'實現一些邏輯*外部*,這取決於'A'的一些屬性,通常需要一個'switch'語句來實現。 – Andreas

+0

@Andreas戰略模式不需要開關。通常情況下,它使用賦值給一個基類型變量,就像你正在做的那樣。它可以被看作是控制反轉,因爲具體的「策略」作爲一個變量被傳入。 'A'的行爲不會被**改變**,只是在運行時選擇交替策略**。 – kervin