これはJAISTの試験勉強をしててUMLを書いていた際に何が違うんだこれ?となったことのメモです。
ざっくり
参照関係と依存関係の違い
- 参照関係: 具体的なクラスのインスタンスをフィールドや変数として保持し、そのインスタンスのメソッドやプロパティにアクセスする関係を指します。この場合、クラスAはクラスBを「参照」していると言います。
- 依存関係: クラスAがクラスBの存在に依存しているが、そのインスタンスを直接保持していない場合を含みます。依存関係は、インターフェースの使用や一時的なオブジェクト生成など、より広い範囲の関係を指します。 上が依存、下が参照の例
くわしく
依存関係が描かれるケース
Interfaceの利用:
- 例: クラスAがクラスBのインターフェースを利用する場合、クラスAはクラスBのインターフェースに依存していると見なされます。インターフェースが変更されると、それを利用するクラスも変更を余儀なくされる可能性があるため、依存関係として描かれます。
public class Client { private Service service; public Client(Service service) { this.service = service; } public void doSomething() { service.performTask(); } }
一時オブジェクトの生成:
- 例: クラスが他のクラスのオブジェクトを直接生成して利用する場合(
new
キーワードを使用)、依存関係が生じます。このケースでは、生成されるオブジェクトのクラスが変更されると、生成元のクラスにも影響を及ぼすため、依存関係として描かれます。
public class OrderProcessor { public void processOrder() { PaymentService paymentService = new PaymentService(); paymentService.processPayment(); } }
- 例: クラスが他のクラスのオブジェクトを直接生成して利用する場合(
メソッドの引数として他のクラスを受け取る場合:
- 例: クラスがメソッドの引数として他のクラスのインスタンスを受け取る場合も依存関係が描かれます。引数として受け取ったクラスが変更されると、そのメソッドを持つクラスにも影響が出る可能性があるためです。
public class ReportGenerator { public void generateReport(DataFetcher dataFetcher) { dataFetcher.fetchData(); // レポート生成ロジック } }
戻り値として他のクラスを返す場合:
- 例: メソッドが他のクラスのインスタンスを返す場合も依存関係が生じます。呼び出し元のクラスがその戻り値に依存するためです。
public class ServiceFactory { public Service createService() { return new ConcreteService(); } }
フィールドとして他のクラスを保持する場合:
- 例: クラスが他のクラスのインスタンスをフィールドとして保持する場合も依存関係が発生します。この場合、フィールドの型やインスタンスのクラスが変更されると、そのクラスにも影響を与えるため、依存関係として描かれます。
- ただし、これは参照関係でもあります。
public class Controller { private Repository repository; public Controller(Repository repository) { this.repository = repository; } }
例外処理:
- 例: クラスが特定の例外クラスをキャッチまたはスローする場合、そのクラスは例外クラスに依存していると見なされます。例外クラスが変更された場合、依存関係を持つクラスにも影響が出る可能性があります。
public void loadData() throws DataNotFoundException { // 処理 }
まとめ
依存関係が描かれるケースは、インターフェースの利用や一時的なオブジェクトの生成に限られません。以下のようなケースでも依存関係が発生し、それがUML図に描かれます。
- メソッドの引数や戻り値として他のクラスを使用する場合
- 他のクラスをフィールドとして保持する場合
- 特定の例外クラスをキャッチまたはスローする場合
依存関係は、クラスが他のクラスやインターフェース、例外、ライブラリなどに影響されるあらゆる状況で発生し、設計上重要な要素となりえるわけです。