レイヤーアーキテクチャーで使用されるテクニックにレイヤースーパータイプ
というものがあります。各レイヤーは基本となるクラスを設けて、具象画面用のクラスはこれらの基本クラスを継承します。この基本となるクラスをレイヤースーパータイプと呼びます。複数のレイヤーでレイヤースーパータイプを使用するとそれぞれのレイヤーで継承階層ができます。それぞれのレイヤーは一方を継承すれば別のレイヤーも継承が必要になる場合があります。このような状態をパラレル継承階層
と呼び、アンチパターンの1つとされています。
このような状況をアンチパターンとみなすかパターンとみなすかメリット・デメリットを天秤に掛ける必要があるでしょう。NetFrameworkではDataTableとTypedDataTable、DataRowとTypedDataRowにパラレル継承階層が見られます。入れ物と中身の関係で中身を継承すると入れ物も継承しなければならないといった場合がありますので私はアンチパターンと言えない場合もあると考えています。
別の継承階層を参照している継承階層では継承のたびにダウンキャストが発生します。この場合はView側でアプリケーション層のクラスを参照するのにダウンキャストが発生します。
パラレル継承階層においてダウンキャストを無くすためにはコーディングの工夫で対応することはできず、言語が対応する必要があります。
例えば下記のような機能があると良いのです。
- 継承可能な型引数をサポートすること
- C#等現在普及している言語は、継承によってジェネリックの型引数を実体化すると型引数が固定されてしまい、さらに継承する場合には型引数をオーバーライドすることができません。ダウンキャストを無くすためにはオープンジェネリックのままで型引数を実体化できる必要があります。
- ジェネリックワイルドカードをサポートすること
- 継承可能な型引数をサポートすると
リスコフの代入原則
(一般には置換原則と邦訳されている)との整合性をどうするかが問題になります。型安全を保ったまま他の階層の継承されたクラスを操作できるようにするためには、Javaで実装されているジェネリックワイルドカードをサポートする必要があります。
残念ながら現状ではダウンキャストを無くすことはできません。