2012-01-24 7 views
8

私は以下のインターフェースを持っています。これはデコレータかストラテジパターンか、どちらのパターンでもありませんか?

PowerSwitch.java

public interface PowerSwitch { 
    public boolean powerOn(); 
    public boolean powerOff(); 
    public boolean isPowerOn(); 
} 

は、上記インターフェースは、追加PowerSwitch実装を追加する可能な限り簡単にするために、他の機能が由来することができる方法の最小セットで構成すべきです。私は2つのtoggleOnOff(のような、PowerSwitchインスタンスの組成物を保持し、新しいメソッドを追加するクラスを作成することによって、(デコレータは何をすべきか)実行時にPowerSwitchインターフェイスに機能を追加したいと思います

方法以下。そうすれば、私は2回のトグル方法を一度実装するだけで済み、すべてのPowerSwitchの実装に適用されます。

これは良い/悪い習慣と考えられますか?悪い場合は、他の推奨事項はありますか?

それは余分なメソッドを追加するように、それは本当にデコレータパターンに準拠していません。それは戦略パターンか構図パターンか?それとも別のパターン名ですか? 「インターフェースデコレータ」のようなものはありますか?実行時に、あなたのPowerSwitchインスタンスを強化する必要がある場合は良い習慣だ

PowerSwitchDecorator.java

public class PowerSwitchDecorator { 
    private PowerSwitch ps; 

    public PowerSwitchDecorator(PowerSwitch ps) { 
     this.ps = ps; 
    } 

    public void toggleOnOff(int millis) throws InterruptedException{ 
     powerOn(); 
     Thread.sleep(millis); 
     powerOff(); 
    } 

    public void toggleOnOff(){ 
    powerOn(); 
    powerOff(); 
    } 

    public boolean powerOn() { 
     return ps.powerOn(); 
    } 

    public boolean powerOff() { 
     return ps.powerOff(); 
    } 

    public boolean isPowerOn() { 
     return ps.isPowerOn(); 
    } 
} 
+5

なぜPowerSwitchDecoratorはPowerSwitchインタフェースを実装していませんか?それは確かに... – Ani

答えて

3

。デコレータにPowerSwitchインターフェイスを実装することをお勧めします。デコレータパターンのもう一つの名前はプロキシパターンです。

あなたのPowerSwitchインターフェイスを拡張し、別のインターフェイスの拡張メソッドを定義することができます。これらの拡張メソッドを呼び出す必要がある場合、デコレータに依存することは避けられます。あなたはコンパイル時に行動を強化したり、再定義する必要がある場合は、クラスの拡張

は良い習慣です。

+0

ありがとう!私はデコレータにPowerSwitchインターフェイスを実装します – etxalpo

0

デコレータもPowerSwitchインタフェースを実装している場合、それは本当にデコレータだろう。私はオブジェクトの集約としてこれを特徴づけるだろう。

7

ことがあるので、toggleOnOff(int)またはtoggleOnOff()メソッドを使用したい任意のコードがPowerSwitchPowerSwitchDecoratorのインスタンスをする必要はないとしています。この種のデコレータは、クライアントに透過的でなければなりません。

あなたはすべての実装は、これらのメソッドを持っているしたい場合は、PowerSwitchインターフェイスでそれらを含める必要があります。 @Aniが示唆するよう

その後、あなたはあなたがこれを行うことができPowerSwitchを拡張するために、上記のPowerSwitchDecoratorを変更できます。

PowerSwitch switch = new PowerSwitchDecorator(new ConcretePowerSwitch()); 
switch.toggleOnOff(); 

今、あなたはPowerSwitchDecoratorの機能を備えたタイプPowerSwitchの変数を持っています。

編集:あなたのニーズに合っている場合にのみ、確立されたパターンを使用するようにしてください。表示されている方法を使用することができます。それを特定のパターンに靴ひだにする必要はありません。

どのような種類のオブジェクトを渡したいですか?あなたは、元をしたい場合は、

(申し訳ありませんが、彼らは非常に良い例ではないよ)

void connect(PowerSwitchDecorator powerSwitch, Appliance appliance); 

void connect(PowerSwitch powerSwitch, Appliance appliance); 

またはこのような方法:あなたがあなたのAPIで、このような方法をしたいですか誰も手作業で「PowerSwitch」の装飾をして、いくつかの便利な方法を手に入れなければなりません。今はあなたにとっては便利かもしれませんが、あなたのコードのユーザにとっては不便であり、おそらくそれを気にすることはないでしょう。後者を使用するには、メソッドのシグネチャにPowerSwitchDecoratorタイプを使用する必要があります。これは、PowerSwitchDecoratorを常に処理し、未処理のPowerSwitchを処理しないという傾向があるためです。

+1

しかし、これは私がすべてのpowerswitchの実装でダミーメソッド(toggleOnOff)を実装する必要があるのではないでしょうか?また、後でデコレータで新しいメソッドを追加したい場合は、PowerSwitchインターフェイスに追加し、現在のPowerSwitchのすべての実装を更新する必要があります(これはコンパイルされません)。 PowerSwitchのすべての実装(サービスプロバイダインターフェイスの一部である可能性があります)にアクセスできない場合もあります。 – etxalpo

+1

etxalpoとして、私は同意しません。装飾されたインタフェースをデコレータに実装するだけで、PowerSwitchのすべてのクライアントがPowerSwitchDecoratorを使用できるので、これはまだ有用です。 Readerのすべてのクライアントは、透過的にBufferedReaderを使用できます。これにより、BufferedReaderが独自のメソッド(たとえば、readLine()など)を追加することや、このパターンを非常に便利にすることはできません。 –

+0

はい、そうです。おそらく、すべての実装が継承する基本的なトグルメソッドを持つ抽象クラスが必要になるでしょう。あなたがトグルの特定の方法をしたい場合は、それを飾ることができます。私は私の答えを編集した、うまくいけば助けて;) –

0

どちらのパターンでもありません。

デコレータは、オブジェクトをラップし、既存の機能を拡張して、クライアントのインターフェイスをトランスペアレントにすることを意図しています。 BufferedInputstreamは例です。 Decoratorは、ラッピングする型と同じインタフェースを実装する必要があることに注意してください。

//Let Type be the interface that both the Decorator and DecoratedClass implements 
Type yourInstance = new Decorator(new DecoratedClass()); 

注主な目的は、必ずしも他のオブジェクトをラップすることによって、オブジェクトへのアクセスを制御することであるプロキシパターンの相違。この場合、プロキシに同じインタフェースを実装させることもできます。

+0

"Not that ..."と "not the difference ..."と言うとき、 "注意してください..."と "違いをメモ..."と意味しますか? –

+0

はい、申し訳ありません、タイプミス。ありがとうございました! –

0

いくつかのパターンはよく似ていますが、その違いは使用目的にあります。このトピックに関するより一般的なスレッドは次のとおりです。When and How Strategy pattern can be applied instead of decorator pattern?

コードでは、実際の違いはまだありません。 PowerSwitchDecoratorは仕事(つまりアルゴリズム)をPowerSwitchに委譲するだけなので、戦略のように見えます。それがあなたの意図で、別の方法で切り替える代替PowerSwitchesがある場合は、戦略パターンを選択します。

これらのPowerSwitchesを入れ替えることができます(トグルを装飾する)と、これらのPowerSwitchを入れ子にすることができ、その後、あなたはデコレータを実装しています。前述のように、この場合は、デコレータも型階層の一部にする必要があります。

0

私はそれがパターンのどれでもないと言います。

Decoratorパターン

Decoratorパターンは、既存の実装の動作を拡張するために使用されます。グラフィックウィンドウを例にとると、スクロールバーを持つウィンドウを持つことができます。そして、あなたは

public class ScrollBarsWindow : Window 
{ 
    private Window windowToDecorate; 
    public ScrollBarsWindow(Window windowToDecorate) 
    { 
     this.windowToDecorate = windowToDecorate; 
    } 

    public void Draw() 
    { 
     windowToDecorate.Draw(); 
     DrawScrollBars(); 
    } 

    public void DrawScrollBars() 
    { Draw the scroll bars } 
} 

戦略パターンが選択した戦略に応じて異なることを行うために使用される戦略パターン

のようなクラスを持つことができます。コーヒーを作っているとしましょう。あなたのようなものかもしれない:

public interface IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee(); 
} 

public class CappuccinoStrategy : IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee { make your cappuccion } 
} 

public class LatteStrategy : IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee { make your latte } 
} 

public class Context 
{ 
    private IMakeCoffeeStrategy strategy; 
    public Context(IMakeCoffeeStrategy strategy) 
    { 
     this.strategy = strategy; 
    } 

    public Coffee MakeSomeCoffee() 
    { 
     return strategy.MakeCoffee(); 
    } 
} 

を、より多くの情報については、以下のリンクをご覧

public class MyCoffeeMachine 
{ 
    public Coffee MakeCoffee(CoffeeType coffeeType) 
    { 
     if(coffeeType == CoffeeType.Latte) 
      return new Context(new LatteStrategy()).MakeSomeCoffee(); 
     else if(coffeeType == CoffeeType.Cappuccino) 
      return new Context(new CappuccinoStrategy()).MakeSomeCoffee(); 

     ... 
    } 
} 

のようにそれを使用します。

0

PowerSwitchDecoratorクラスはデコレータではありません。あなたの実装はStrategy_patternに近いコマンドがDecoratorパターン、DecoratorCommand_pattern

に似ているにもかかわらず、実際にインタフェースを実装する(すなわち、Component)とあなたのクラスが同じことをやっていません。

Componentがインタフェースで、クラス図上の図で

enter image description here

を見てください。 DecoratorComponentインターフェイスを実装し、Compositionのインターフェイスを含んでいます。メンバー変数 - componentを見てください。

はより良く理解するためにこれらの質問を参照してください。

Decorator Pattern for IO

Real World Example of the Strategy Pattern

関連する問題