「移譲」を実現する方法をJavaを例に新人エンジニア向けに解説

「移譲」を実現する方法は、Javaではいくつかあります。基本的な考え方は「クラスの処理を別のオブジェクトやメソッドに任せる」ことです。具体的な方法について順番に解説しますね!


1. コンポジション(Composition)を利用する

「移譲」の基本的な手法はコンポジションを使うことです。
コンポジションとは、クラスの中に別のクラスのインスタンスを持ち、そのクラスに処理を任せる方法です。

具体例

class Engine {
    public void start() {
        System.out.println("エンジンが始動しました");
    }
}

class Car {
    private Engine engine; // エンジンのインスタンスを持つ

    public Car(Engine engine) { // 外部からEngineを渡す
        this.engine = engine;
    }

    public void startCar() {
        engine.start(); // Engineに処理を移譲
    }
}

public class Main {
    public static void main(String[] args) {
        Engine engine = new Engine();
        Car car = new Car(engine); // EngineをCarに渡す
        car.startCar();
    }
}

コンポジションのポイント

  • CarクラスはEngineを持っていますが、生成は外部で行います。
  • CarEngineの操作をengine.start()を通じて「移譲」しています。

このように、インスタンスを外部から渡すことで、柔軟な設計が可能になります。


2. インターフェースを利用する

インターフェースを使うと、移譲の対象となるクラスを柔軟に切り替えることができます。
例えば、Engineクラスをインターフェースにして実装を切り替えるとしましょう。

インターフェースを使った移譲

interface Engine {
    void start();
}

class GasolineEngine implements Engine {
    public void start() {
        System.out.println("ガソリンエンジンが始動しました");
    }
}

class ElectricEngine implements Engine {
    public void start() {
        System.out.println("電気エンジンが始動しました");
    }
}

class Car {
    private Engine engine;

    public Car(Engine engine) { // 外部からEngineを渡す
        this.engine = engine;
    }

    public void startCar() {
        engine.start(); // Engineの処理を移譲
    }
}

public class Main {
    public static void main(String[] args) {
        Engine gasolineEngine = new GasolineEngine();
        Engine electricEngine = new ElectricEngine();

        Car car1 = new Car(gasolineEngine);
        car1.startCar();

        Car car2 = new Car(electricEngine);
        car2.startCar();
    }
}

ポイント

  1. インターフェース Engine を定義することで、異なるエンジンの実装(GasolineEngineElectricEngine)を渡せます。
  2. CarクラスはEngineインターフェースに依存しているため、具体的な実装には依存しません。

こうすることで、新しい種類のエンジンを追加する場合も、Engineインターフェースを実装するだけで済みます。


3. メソッドに処理を移譲する

移譲はクラスだけでなく、メソッド単位でも行えます。
あるクラスのメソッドが別のオブジェクトのメソッドを呼び出すことで「仕事を任せる」ことができます。

メソッド単位の移譲

class Printer {
    public void printMessage(String message) {
        System.out.println("プリンタが印刷中: " + message);
    }
}

class Report {
    private Printer printer;

    public Report(Printer printer) {
        this.printer = printer;
    }

    public void createReport(String content) {
        System.out.println("レポートを作成中...");
        printer.printMessage(content); // Printerに処理を移譲
    }
}

public class Main {
    public static void main(String[] args) {
        Printer printer = new Printer();
        Report report = new Report(printer);
        report.createReport("売上レポート");
    }
}

ポイント

  • Reportクラスが直接メッセージを印刷するのではなく、Printerに処理を移譲しています。
  • 責務(役割)を分けることで、コードがシンプルになり、保守がしやすくなります。

4. デザインパターンを利用する

「移譲」を実現する方法の中には、デザインパターンを活用するものもあります。
特に、委譲(Delegation)やAdapterパターンが代表的です。

  • 委譲パターン: 特定の処理を別のオブジェクトに任せることで、処理の柔軟性を高めます。
  • Adapterパターン: 既存クラスのインターフェースを新しいインターフェースに適合させる際に移譲を利用します。

デザインパターンは設計をさらにきれいにするためのテクニックなので、次のステップとして学ぶと良いでしょう。


移譲のまとめ

  1. コンポジションを使う
    クラスのインスタンスを持ち、処理を任せることで移譲を実現します。
  2. インターフェースを利用する
    実装の詳細を隠蔽し、柔軟に依存先を切り替えることができます。
  3. メソッドに処理を移譲する
    処理を別クラスに任せることで、責務を明確にします。
  4. デザインパターンを活用する
    より高度な設計を実現するために委譲やAdapterパターンなどを学びましょう。

移譲を意識して設計すると、コードが柔軟で拡張しやすくなります。
少しずつ移譲を取り入れて、クリーンで保守しやすいコードを書けるエンジニアを目指してくださいね!応援しています!✨

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。