考察:継承から委譲、そして単なる手続きへ
Template Method+Factory Methodパターンのように継承関係のクラスに処理を任せることに対比して、Abstract Factoryパターンのように他のオブジェクトにひとまとまりの処理を任せることを委譲と呼びます。一般的に、継承よりも委譲を用いるほうがプログラムを柔軟に変更しやすくなります。また、委譲先のオブジェクトの型が関数型インタフェースであれば、ラムダ式を適用することが可能です。
このようにして最終的にラムダ式を適用したリスト4では、AbstractFactoryに相当するインタフェース、ConcreteFactoryに相当するクラスいずれの定義も、プログラム中に現れていないということに注目してください。ファクトリの姿がないのですから、これをあえてAbstract Factoryパターンを使ったプログラムとみなし、「ジョブ定義はジョブのファクトリにジョブ生成処理を委譲する」のように考える必要はないと思われます。単純に「ジョブ定義のコンストラクタは、ジョブを生成する手続きを引数として取る」と考えればよいのです。
ラムダ式を使ったリスト4のプログラムは、Factory Methodを使ったプログラムに比べて、簡潔な構造が実現できています。しかし、元々がひどい設計というわけではないのですから、必ずしもこのような設計変更をする必要があるわけではありません。変更の影響が広範囲に及ぶ場合には、設計変更を思いとどまるほうが賢明でしょう。逆に、変更の影響が狭い範囲にとどまり、なおかつConcreteFactoryクラスの多用で見通しが悪くなっている場合には、設計変更の恩恵が受けられる可能性があります。その場合でも、テストを用いて既存のプログラムが壊れないことを確認しながら、慎重に設計変更を行うべきです。
連載のまとめ
本連載では、Command、Strategy、Observerといったデザインパターンを用いたプログラムについてJava SE 8のラムダ式を適用することで、あえてパターンを意識する必要がないほどに簡潔なプログラムが実現できることを示してきました。パターンを意識しなくてよくなる理由は、これらのパターンが「処理」「計算」「手続き」といった概念を、クラスを用いて表現するための、迂遠な回り道にすぎないためだと考えられます。ラムダ式が表現するものは「処理」「計算」「手続き」そのものですから、回り道を通る必要がない、というわけです。
連載最終回の今回は、継承の代わりに処理の委譲によってプログラムを構成することで、ラムダ式が適用しやすくなる、ということを示しました。本稿のような既存プログラムの変更に限らず、新しいプログラムを構想する際にも、気に留めて役立てていただければと思います。
それではまたいつの日か。Happy Coding!
