Decoratorパターンが遂に消滅する日がやってきた?
例えば、GoFデザインパターンのIIteratorでは、もうJavaやC#では拡張forなりforeachがあるのでほぼ不要になっており意識して実装することも無くなってきていると思うわけだが、ここにきてDecoratorパターンもパターンとして意識する必要性が無くなってくるのではないかと思う。
というのも、Java SE8では、ラムダ式が遂に実装されることばかりがクローズアップされるが、実はインターフェイスのデフォルト実装が導入されるというかなり重大な変更も予定されている。構文はまだ変更されるかもしれないが、こんな感じになるらしい。
public interface Sample { public Object doSomething() default { return null; } }
あのRubyの父親まつもとゆきひろも指摘していたらしいJavaの大きな欠点だった「実装を共有できない」というインターフェイスの欠点がここに来て修正されることになる。
Rubyの作成者であるまつもとゆきひろ氏は「多重継承の代わりにインタフェースを使ったのはJavaの賢いところ。ただし、実装の継承を落としたことはとても痛い」と指摘する。
従前は、実装の共有ができないインターフェイスだと、
public abstract class Fruit { protected string name; protected Boolean isFruit(); { return true; } } public interface IVegetable { public Boolean isVegetable(); } public class Vegetable implement IVegetable { public Boolean isVegetable() { return true; } } public class Apple extends Fruit { } public class Melon extends Fruit, implements IVegetable { private IVegetable vegetable; public Melon(IVegetable vegetable) { this.vegetable = vegetable; } public Boolean isVegetable() { return vegetable.isVegetable(); } }
こんな感じに作るしかなかった。実装を共有するには、インターフェイスを実装したクラスを用意してそれに委譲させないといけないし、共有するクラスのすべてに、そのインスタンスを渡さないといけない。これはすごく手間暇がかかったものであるが、デフォルト実装が共有されるのであれば、もうインターフェイスはpublicのメソッドについては抽象クラスと同様の扱いができる。ただ、依然としてフィールドは定義できないどころか、メソッドはpublicしか定義できないんだがね。結局、インターフェイスって概念そのものが、外部から見たら同一のものとして見えるようにするってことだから。Javaは多重継承は認めてないつーのは変わらん。