[Flutter]クラスの依存関係を適切に管理するとは


はじめに

依存関係という言葉は良く聞きますけど、ちゃんと理解されてますか?
僕は、正直うまく説明できません。
なので、調べました。「なんとなく分かる」を、「理解して説明できる状態」になれるよう、一緒に学習していきましょう!

依存関係を適切に管理するとどうなるの?

一言で言いうと、依存関係を適切に管理することで、コードの整理とメンテナンスが容易になります。

依存関係が適切に管理されていないコードを見てみる

まずは、依存関係が適切に管理されていないコードを提示します。
下記は、注文が入った商品を、データベースに保存する処理を簡易的に書いたものです。

例としてあげる処理の流れ

処理の流れは簡単で、
①Orderクラスで設定した注文情報が、データとして与えられます。
②そのデータをデータベースに保存する為に接続します。
 「データベースに接続しました」という返答がきます。
③接続したら、データベースに保存します。
 「注文をデータベースに保存しました」という返答がきます。
という簡単な処理です。それでは見てみてください。

依存関係が適切に管理されていないコード

void main() {
  // 注文を作成
  Order order = Order('12345', 'John Doe', ['Item1', 'Item2']);

  // 注文をデータベースに保存
  order.saveToDatabase();
}

class Order {
  // 注文の詳細情報を保持
  String orderId;
  String customerName;
  List<String> items;

  Order(this.orderId, this.customerName, this.items);

  // 注文をデータベースに保存
  void saveToDatabase() {
    // データベース接続のためのインスタンスを直接生成
    DatabaseConnection dbConnection = DatabaseConnection();
    dbConnection.connect();
    dbConnection.saveOrder(this);
  }
}

class DatabaseConnection {
  // データベースに接続するためのメソッド
  void connect() {
    // データベースに接続するコード
    print('データベースに接続しました');
  }

  // 注文情報をデータベースに保存
  void saveOrder(Order order) {
    // 注文をデータベースに保存するコード
    print('注文をデータベースに保存しました');
  }
}

上記のコードでは、Order クラスが直接 DatabaseConnection クラスを生成してデータベースに接続し、注文情報を保存しています。これにより、次のような問題が生じています。

  1. クラスの結合度が高い: Order クラスは DatabaseConnection クラスに直接依存しており、クラス間の結合度が高くなっています。このため、Order クラスの変更が DatabaseConnection クラスに影響を与えやすいです。

  2. 再利用性の低さ: DatabaseConnection クラスが Order クラスに密接に結びついているため、他の部分で再利用するのが難しいです。

依存関係が適切に管理されているコードを見てみる

それでは、適切に管理されているコードを見てみましょう。

void main() {
  // データベース接続のインスタンスを作成
  DatabaseConnection dbConnection = DatabaseConnection();

  // 注文を作成
  Order order = Order('12345', 'John Doe', ['Item1', 'Item2']);

  // 注文をデータベースに保存(依存性を注入)
  order.saveToDatabase(dbConnection);
}

class Order {
  // 注文の詳細情報を保持
  String orderId;
  String customerName;
  List<String> items;

  Order(this.orderId, this.customerName, this.items);

  // データベースへの依存性を注入する
  void saveToDatabase(DatabaseConnection dbConnection) {
    dbConnection.connect();
    dbConnection.saveOrder(orderId, customerName, items);
  }
}

class DatabaseConnection {
  // データベースに接続するためのメソッド
  void connect() {
    // データベースに接続するコード
    print('データベースに接続しました');
  }

  // 注文情報をデータベースに保存
  void saveOrder(String orderId, String customerName, List<String> items) {
    // 注文をデータベースに保存するコード
    print('注文をデータベースに保存しました');
  }
}

修正点

コードを修正し、クラスの依存関係を適切に管理するために以下の変更を行いました。

  1. main 関数内での依存性の注入:

    • main 関数内で、データベース接続のインスタンスである dbConnection を作成しました。これは Order クラスのメソッド呼び出しに注入されます。

  2. 依存性の注入:

    • Order クラスの saveToDatabase メソッドに、DatabaseConnection クラスのインスタンスである dbConnection を引数として追加しました。

    • dbConnection.connect() および dbConnection.saveOrder(this) の呼び出しを、直接インスタンスを生成せずに dbConnection を介して行うように変更しました。

※「依存性の注入」っていう言葉、難しいですよね。
依存性の注入は、あるコードが他のコードを直接作成するのではなく、必要なものを外部から提供してもらう方法です。
もう少し具体的に説明すると、あるクラスが別のクラスを直接作成または管理せずに、外部から提供される依存関係を受け入れる方法です。これにより、クラス間の結合度が低くなり、柔軟性とテスト可能性が向上します。

どの様な改善点が見込めるのか。

  1. 依存性の注入: Order クラスの saveToDatabase メソッドに DatabaseConnection のインスタンスが注入され、依存関係が明示的になりました。これにより、Order クラスはデータベースへの依存を直接持たず、結合度が低くなりました。

  2. 再利用性の向上: Order クラスはデータベース接続に依存しないため、他の部分で再利用しやすくなります。

依存関係の注入を適切に行うことで、クラス間の疎結合性が向上し、コードの保守性とテスト可能性が改善されます。

適切に管理することは相手を思いやる気持ち

依存関係を適切に管理することは、コードの品質を向上させ、協力するチームメンバーや未来の開発者たちのためになります。クラスが疎結合であり、依存関係が明示的であると、コードの理解、テスト、保守が容易になります。そして、この実践は、より信頼性の高いアプリケーションの構築につながります。
ぜひ、依存関係を意識して、相手を思いやる気持ちで書いてみましょう。

この記事が気に入ったらサポートをしてみませんか?