Java中級

中級 Javaで学ぶオブジェクト指向設計|アンチパターン編

導入

オブジェクト指向設計は、ソフトウェア開発において重要な役割を果たします。しかし、設計の過程で陥りやすいアンチパターンも存在します。本記事では、実際の業務で遭遇することが多い「過剰な継承」をテーマに、具体的な例を通じてその問題点と改善策を考察します。

教科書レベルの解説(オブジェクト指向設計)

重要な概念の整理

オブジェクト指向設計において、クラスの継承は再利用性を高める手段の一つです。しかし、継承を過度に使用すると、コードの可読性やメンテナンス性が低下し、システム全体が複雑化します。特に、親クラスの変更が子クラスに影響を与えるため、バグの温床となることがあります。

コード例(Java)


class Animal {
    void makeSound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    void makeSound() {
        System.out.println("Meow");
    }
}

class Labrador extends Dog {
    void makeSound() {
        System.out.println("Labrador bark");
    }
}

コードの行ごとの解説

  1. Animalクラスは基本的な動物の振る舞いを定義しています。
  2. DogクラスはAnimalを継承し、特定の動物の音をオーバーライドしています。
  3. CatクラスもAnimalを継承し、異なる音を実装しています。
  4. LabradorクラスはDogを継承し、さらに特定の犬種の音をオーバーライドしています。

アンチパターン編

過剰な継承のアンチパターンは、特にLabradorクラスの実装に見られます。DogクラスからLabradorクラスを継承することで、Labrador特有の振る舞いを実装していますが、これはクラス階層を不必要に深くし、変更に対する脆弱性を生み出します。例えば、Dogクラスに新しい機能を追加すると、Labradorクラスにも影響が及ぶ可能性があります。

この問題を解決するためには、継承の代わりにコンポジションを使用することが有効です。具体的には、Animalクラスに対して「SoundBehavior」インターフェースを実装し、各動物が自身の音を持つようにします。これにより、柔軟性が向上し、クラスの再利用性が高まります。

まとめ

  • 過剰な継承はコードの複雑さを増し、メンテナンス性を低下させる。
  • 継承の代わりにコンポジションを活用することで、柔軟で再利用可能な設計が可能になる。