界面偏析原理


インターフェイス偏析原理は、固体の一部であり、5つの設計原理の合計を束ねるニーモニック頭字語.
これはしばしばクリーンコードに関連付けられます.
しかし、それは正確には何ですか、あなたにも重要ですか?

どのような状態ですか?
ISPはかなり簡単な文を設定します.

"No client should be forced to depend on methods it does not use."


極端に適用されるISPは、役割インターフェースと呼ばれる一つのメソッドインターフェースに終わります.
次の例を見れば、ISPがどのようにして違反されるかを考えることができます.
interface ReportService {
  createEmployeeReport(employeeId: string): Report;
  createCustomerReport(customerId: string): Report;
  createManagementReport(projectId: string): Report;
}

class EmployeeReportService implements ReportService {
  createEmployeeReport(employeeId: string): Report {
    return {
      // ...
    };
  }
  createCustomerReport(customerId: string): Report {
    throw new Error("Method not implemented.");
  }
  createManagementReport(projectId: string): Report {
    throw new Error("Method not implemented.");
  }
}
あなたは問題を見つけることはできますか?
インターフェイスを実装するクラスは、実際にインターフェイス内で定義されている3つのメソッドのうち2つを実装する必要はありません.
しかし、インターフェイスが大きすぎるので、それを強制されます!
この場合のクライアントは、インターフェイスを満たすことです.

何を防ぐためにしようとすると?
最も重要なことは、以下を防ぐことです.
クライアント開発者の間の
  • 混乱
  • は、メンテナンスコストを広げます
    しかし、我々は今これが実際に意味するものを見つけるために見てみましょう.

    ℹ️ クライアント開発者間の混乱
    あなたが従業員レポートを実装するために基本クラスを使用したかっただけであるけれども、上記のようなそのようなかさ高いインターフェースを実装しなければならないと想像してください.
    あなたもそんなに多くを実装する必要が混乱していないだろうか?
    そうでしょう
    また、基底クラスが多分あまりに多くをしようとする徴候です.
    それにもかかわらず、実際に使用するつもりはなかった方法について実際に何かをする必要があります.
    そして、あなたが何をすべきかについて考えるために入れなければならない考えさえ、不必要な仕事です!

    ℹ️ 保全費の拡大
    インターフェースが変わるたびに、それを実装するいくつかのクラスは変更する必要があります.
    そしてこの場合、実際にメソッドを実装しても問題はありません.クライアントがコンパイルするコードを要求するか、少なくとも実行時にエラーが発生しないように強制されます.
    これは、メンテナンスコストへの巨大な追加です!
    そして、これはすべてのクライアント開発者のための非常に不必要な仕事のドライバーです.

    問題の修正
    問題を解決する1つの方法は、実際には、以下のように、インターフェイスを離れてプルすることができます.
    interface EmployeeReportService {
      createEmployeeReport(employeeId: string): Report;
    }
    
    interface CustomerReportService {
      createCustomerReport(customerId: string): Report;
    }
    
    interface ManagementReportService {
      createManagementReport(projectId: string): Report;
    }
    
    class EmployeeReportServiceImplementation implements EmployeeReportService {
      createEmployeeReport(employeeId: string): Report {
        // ...
      }
    }
    
    // and so on...
    
    これはISPに適用されたロール・インターフェースの極端なバージョンです.
    しかし、もう少し考えて、あなたはさらに問題を修正することができます、インターフェイスを一般化することによって!
    以下のバージョンを見てください.
    詳細の任意の概念は、あなたが今、多くの方法で実装することができるかなりの汎用インターフェイスを持っているという事実のために削除されました.
    interface ReportService {
      createReport(id: string): Report;
    }
    
    class EmployeeReportService implements ReportService {
      createReport(id: string): Report {
        // ...
      }
    }
    
    // and so on...
    

    あなたは気にする必要がありますか?
    私は、あなたがすでに答え==はいを知っているとかなり確信します、あなたはそうしなければなりません!
    JavaScriptのような動的にタイプされたものでさえ、バルキーインターフェースはどんな言語でも起こることができます.
    あなたが手でインターフェースを持っていないけれども、あなたはまだあなたが書くコードによって、クライアントがあなたに渡すと思っているものによって、あなたを定義します.
    ただ、神のオブジェクトを取り、そのオブジェクトにいくつかのメソッドを使用してその働きをする関数を想像してみてください.
    あなたの関数を使用している誰でも、あなたの機能を働かせるために少なくとも何かをそれらのオブジェクトのメソッドに入れなければなりません.
    ISPは、不要な依存の実装に不必要な作業の多くを置くから他とあなたを節約します.
    そして、きれいなコードに関連したほとんどすべての他の原理と同様に、コードはより読みやすくて、テストがより保守的になります!

    去る前に
    あなたが私のコンテンツが好きならば、私を訪ねてください、そして、おそらく、あなたはあなたが見るものが好きです!