"デコレータパターン"としてあなたが何を記述しているかは完全に可能であり、一般的に知られています。
リンクのみの回答が悪いので、後で詳しく説明します。
一方、Wikipediaにはさらに詳しい情報があります:Decorator Pattern。
1 Cat cat = new Cat();
2 Animal pet = new Pet(cat, "Foo");
3 if (pet instanceof Pet){
4 if (pet.kind instanceof Cat){
5 Pet.sayMeow();
6 }
7 }
これはinstanceOf
を使用する必要があるという欠点があります。通常は、Animal
クラスにメソッドがあります。makeNoise
としましょう。おそらく抽象的です。あなたの動物の実装(Cat
、Dog
...)は、それぞれのノイズ( "Bark"、 "Miow" ...)を作るためにそのメソッドをオーバーライドします。
スニペットでは、ペットだけがノイズを発生させることができるようです...それは、それを行うさまざまな方法があるため、少し複雑になります。
デコレータにサウンドを保存させ、そのサウンドを作るためにmakeNoiseをオーバーライドすることができます。これと同じように:
Cat catInstance = new Cat();
catInstance.makeNoise(); // Default impl: NOP => "" - no sound.
Animal pet = new Pet(catInstance, "Mieow");
pet.makeNoise(); // => "Mieow"
このすべてのポイントは次のとおりです。あなたはinstanceof
を使用しないようにしたいです。動物が猫の犬、ペットの猫またはペットの犬であるかどうかは気にしません。彼らは正しいことを言われたときに、正しい音を出す。だからあなたは "動物"のコレクションを持っていて、 "makeNoise"にそれらのすべてを教えてもらえます。それぞれがペットであるか、またはAnimal
の特定の子供であるかを気にすることなく、それぞれは沈黙しています。
EDIT:私の答えをもう一度読んで、それはデコレータよりもポリシー(戦略パターン)に似ています。 ポリシーは何かが行われたときに変更されますが、装飾者はその機能を追加します。
真のデコレータになるためには、makeNoise
がPet
のインターフェイスにあることを意味します。つまり、あなたは動物のそのメソッドを呼び出すことはできませんでした。
私は「Decorator」から「Strategy」というパターンに変更しました。
上記の例はまだ成り立ちます。デコレータのような実装アプローチを使って、 "デフォルト"の戦略を持ち、 "ペット"戦略を注入します。
もちろん、このすべてをパターンをより厳密に実装するために別の方法で行うこともできます。
最後に、if(x instanceof X) ...
は常に「Visitor」-Bellを噛んでいます。
自分自身に質問してください。「ペット」は、渡された「動物」と何が関係していますか?あなたは現在それを何もしていないので、この質問は不明です(Animalを渡すあなたの理由は不明です)。 – Tom
@Tomが言ったこと:あなたが達成しようとしていることに関するいくつかの情報がうまくいくでしょう。現在のところ、これはあなたが 'interface'を使うことができるようなものです。 – domsson
あなたが 'Animal'の既存のインスタンスを取得し、**そのインスタンス**を' Pet'に遡って変換したいと言うなら、あなたはそれを行うことはできません。 'Animal'インスタンスから初期化された新しい' Pet'を作成することはできますが、それは分離されます。インスタンスのクラスは、作成時にロックされます。 (インスタンスには異なるインタフェースを持つことができますが、いくつかのコードでは 'Animal'しか知りませんし、他のコードでは' Cat'であることがわかるかもしれませんが、*インスタンス*には特定のクラスが設定されています。 –