ホームページ  >  記事  >  Java  >  Java におけるデメテルの法則の詳細な説明

Java におけるデメテルの法則の詳細な説明

黄舟
黄舟オリジナル
2017-08-07 10:30:251169ブラウズ

この記事では主にデメテルの法則を紹介します。デメテルの法則は、クラスでメソッドやプロパティを作成するときに従う必要があるルールです。興味のある方は学習してください。

定義: オブジェクトは一定期間変更されない必要があります。その他のオブジェクト 最低限の理解。

問題の原因: クラス間の関係が緊密であればあるほど、結合度は大きくなり、一方のクラスが変更されると、他方のクラスへの影響も大きくなります。

解決策: クラス間の結合を可能な限り減らします。

私たちはプログラミングに触れてきたので、ソフトウェア プログラミングの一般原則、つまり低結合と高凝集性を知っています。プロセス指向プログラミングでもオブジェクト指向プログラミングでも、モジュール間の結合を可能な限り低く保つことによってのみ、コードの再利用率を向上させることができます。低結合の利点は自明ですが、プログラミングを通じてどのように低結合を実現できるでしょうか?それがまさにデメテルの法則が達成しようとしていることです。


最も知られていない原則としても知られるデミットの法則は、1987 年に米国ノースイースタン大学のイアン ホランドによって初めて提案されました。平たく言えば、クラスが依存するクラスについての知識が少なければ少ないほど良いのです。つまり、依存クラスでは、どんなに複雑なロジックであっても、ロジックは可能な限りクラス内にカプセル化し、提供されるパブリックメソッド以外には情報が外部に漏洩しないようにする必要があります。デメテルの法則の定義はより単純です。つまり、直接の友人とのみ通信するというものです。まず、直接のフレンドとは何かについて説明します。各オブジェクトは他のオブジェクトとカップリング関係を持ちます。2 つのオブジェクト間にカップリング関係がある限り、その 2 つのオブジェクトはフレンドであると言います。結合には、依存関係、関連付け、結合、集約など、さまざまな方法があります。このうち、メンバー変数、メソッドのパラメータ、メソッドの戻り値に現れるクラスを直接の友達と呼びますが、ローカル変数に現れるクラスは直接の友達ではありません。言い換えれば、馴染みのないクラスがローカル変数としてクラス内に出現しないことが最善です。


例を示します。あるグループ会社の配下に支店と直属の部門があり、すべての配下にある従業員 ID を印刷する必要があります。まず、デメテルの法則に違反するデザインを見てみましょう。



 //总公司员工
class Employee{
 private String id;
 public void setId(String id){
 this.id = id;
 }
 public String getId(){
 return id;
 }
}

//分公司员工
class SubEmployee{
 private String id;
 public void setId(String id){
 this.id = id;
 }
 public String getId(){
 return id;
 }
}

class SubCompanyManager{
 public List<SubEmployee> getAllEmployee(){
 List<SubEmployee> list = new ArrayList<SubEmployee>();
 for(int i=0; i<100; i++){
  SubEmployee emp = new SubEmployee();
  //为分公司人员按顺序分配一个ID
  emp.setId("分公司"+i);
  list.add(emp);
 }
 return list;
 }
}

class CompanyManager{

 public List<Employee> getAllEmployee(){
 List<Employee> list = new ArrayList<Employee>();
 for(int i=0; i<30; i++){
  Employee emp = new Employee();
  //为总公司人员按顺序分配一个ID
  emp.setId("总公司"+i);
  list.add(emp);
 }
 return list;
 }
 
 public void printAllEmployee(SubCompanyManager sub){
 List<SubEmployee> list1 = sub.getAllEmployee();
 for(SubEmployee e:list1){
  System.out.println(e.getId());
 }

 List<Employee> list2 = this.getAllEmployee();
 for(Employee e:list2){
  System.out.println(e.getId());
 }
 }
}

public class Client{
 public static void main(String[] args){
 CompanyManager e = new CompanyManager();
 e.printAllEmployee(new SubCompanyManager());
 }
}

この設計の主な問題は CompanyManager にあります。ディミットの法則によれば、コミュニケーションは直接の友人とのみ行われ、SubEmployee クラスは CompanyManager クラスの直接の友人ではありません (ローカル変数の形式は直属の友人に属さない)、論理的に言えば、本社は支店と結合するだけでよく、支店の従業員とは連絡を取りません。この設計では明らかに不必要な結合が追加されます。デメテルの法則によれば、クラス内での間接的な友人関係とのこのようなカップリングは避けるべきです。変更後のコードは以下の通りです。


class SubCompanyManager{
 public List<SubEmployee> getAllEmployee(){
 List<SubEmployee> list = new ArrayList<SubEmployee>();
 for(int i=0; i<100; i++){
  SubEmployee emp = new SubEmployee();
  //为分公司人员按顺序分配一个ID
  emp.setId("分公司"+i);
  list.add(emp);
 }
 return list;
 }
 public void printEmployee(){
 List<SubEmployee> list = this.getAllEmployee();
 for(SubEmployee e:list){
  System.out.println(e.getId());
 }
 }
}

class CompanyManager{
 public List<Employee> getAllEmployee(){
 List<Employee> list = new ArrayList<Employee>();
 for(int i=0; i<30; i++){
  Employee emp = new Employee();
  //为总公司人员按顺序分配一个ID
  emp.setId("总公司"+i);
  list.add(emp);
 }
 return list;
 }
 
 public void printAllEmployee(SubCompanyManager sub){
 sub.printEmployee();
 List<Employee> list2 = this.getAllEmployee();
 for(Employee e:list2){
  System.out.println(e.getId());
 }
 }
}

変更後は支店に社員IDを印刷するメソッドを追加し、本社が直接呼び出して印刷することで支店の従業員との結合を回避します。


デメテルの法則の本来の目的は、クラス間の結合を減らすことであり、各クラスは不要な依存関係を減らすため、実際に結合関係を減らすことができます。しかし、すべてに限界があります。間接的なコミュニケーションは避けられますが、たとえば、この例では、本社と支店の従業員が「仲介者」を介してコミュニケーションを行う必要があります。デメテル原理を過度に使用すると、そのような中間クラスや転送クラスが多数生成され、システムの複雑さが増大します。したがって、ディミットの法則を採用する場合は、明確な構造と高い凝集性と低い結合性の両方を達成するために、トレードオフを繰り返し検討する必要があります。


以上がJava におけるデメテルの法則の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。