クラス関係-UMLからコードへ

はじめに


UMLクラス図により、クラスとそのインスタンス間の関係を示すことができます。 彼らは何のために? たとえば、アプリケーションフィールドのモデリングに必要です。 しかし、関係はどのようにコードに反映されますか? この小さな研究では、この質問に答えようとしています-これらの関係をコードで示しています。



最初に、UMLのクラス間の関係が相互にどのように関係しているかを明確にしてみましょう。 さまざまなソースを使用して、さまざまな関係を示す次の構造図を作成できました。









図 1-クラス間の関係



関連付けには、双方向または単方向のナビゲーションがあり、通信の方向を示します。 つまり、各タイプの関連付けにはまだ2つの亜種がありますが、図には示されていません。



1.一般化


したがって、私たちの目標は、UMLクラス図(クラスモデル)を構築し、それをオブジェクト指向コードに反映することです。



適用分野として、特定の企業の人事部門を取り上げ、そのモデルの構築を開始します。 例として、Java言語を使用します。



汎化関係は継承です。 この態度は、OOP言語のすべての教科書で十分に考慮されています。 Javaでは、あるクラスから別のクラスへの拡張(拡張)による明示的な実装があります。





図 2-汎化関係



Manクラスはより抽象的であり、Employeeクラスはより専門的です。 Employeeクラスは、Manのプロパティとメソッドを継承します。



この図のコードを作成してみましょう。

public class Man{ protected String name; protected String surname; public void setName(String newName){ name = newName; } public String getName(){ return name; } public void setSurname(String newSurname){ name = newSurname; } public String getSurname(){ return surname; } } //   Man public class Employee extends Man{ private String position; //    public Employee(String n, String s, String p){ name = n; surname = s; position = p; } public void setPosition(String newProfession){ position = newProfession; } public String getPosition(){ return position; } }
      
      







2.協会


関連付けは、クラスのインスタンスオブジェクト間の関係を示します。

2.1バイナリ


「IdCard」クラスがモデルに追加され、従業員の身分証明書(パス)を表します。 各従業員は、通信力が1対1の1枚のIDカードしか持てません。



図 3-バイナリ協会



クラス:

 public class Employee extends Man{ private String position; private IdCard iCard; public Employee(String n, String s, String p){ name = n; surname = s; position = p; } public void setPosition(String newPosition){ position = newPosition; } public String getPosition(){ return position; } public void setIdCard(IdCard c){ iCard = c; } public IdCard getIdCard(){ return iCard; } } public class IdCard{ private Date dateExpire; private int number; public IdCard(int n){ number = n; } public void setNumber(int newNumber){ number = newNumber; } public int getNumber(){ return number; } public void setDateExpire(Date newDateExpire){ dateExpire = newDateExpire; } public Date getDateExpire(){ return dateExpire; } }
      
      







プログラムの本体で、オブジェクトを作成してバインドします。

 IdCard card = new IdCard(123); card.setDateExpire(new SimpleDateFormat("yyyy-MM-dd").parse("2015-12-31")); sysEngineer.setIdCard(card); System.out.println(sysEngineer.getName() +"    "+ sysEngineer.getPosition()); System.out.println("   " + new SimpleDateFormat("yyyy-MM-dd").format(sysEngineer.getIdCard().getDateExpire()) );
      
      







Employeeクラスにはカードフィールドがあり、そのタイプはIdCardです。クラスには、このフィールドに値(setIdCard)を割り当てるメソッドと、

値を取得します(getIdCard)。 Employeeオブジェクトのインスタンスから、IdCardタイプの関連オブジェクトを見つけることができます。つまり、

ナビゲーション(行の矢印)はEmployeeからIdCardに向けられています。



2.2 N項連想


組織が従業員に施設を割り当てることになっていると想像してください。 新しいRoomクラスを追加します。

各オブジェクトの従業員(従業員)は、複数のワークルームに対応できます。 1対多の通信能力。

従業員から部屋へのナビゲーション。



図 4-N-aryアソシエーション



これをコードに反映してみましょう。 新しいルームクラス:

 public class Room{ private int number; public Room(int n){ number = n; } public void setNumber(int newNumber){ number = newNumber; } public int getNumber(){ return number; } }
      
      







ルームを操作するためのフィールドとメソッドをEmployeeクラスに追加します。

 ... private Set room = new HashSet(); ... public void setRoom(Room newRoom){ room.add(newRoom); } public Set getRoom(){ return room; } public void deleteRoom(Room r){ room.remove(r); } ...
      
      







使用例:

 public static void main(String[] args){ Employee sysEngineer = new Employee("John", "Connor", "Manager"); IdCard card = new IdCard(123); card.setDateExpire(new SimpleDateFormat("yyyy-MM-dd").parse("2015-12-31")); sysEngineer.setIdCard(card); Room room101 = new Room(101); Room room321 = new Room(321); sysEngineer.setRoom(room101); sysEngineer.setRoom(room321); System.out.println(sysEngineer.getName() +"    "+ sysEngineer.getPosition()); System.out.println("   " + sysEngineer.getIdCard().getDateExpire()); System.out.println("   :"); Iterator iter = sysEngineer.getRoom().iterator(); while(iter.hasNext()){ System.out.println( ((Room) iter.next()).getNumber()); } }
      
      





2.3集約


モデルにDepartmentクラスを導入します。当社は部門ごとに構成されています。 各部門で1人以上の人が働くことができます。 部門には1人以上の従業員が含まれているため、それらを集約していると言えます。 会社には、会社の取締役など、どの部門にも属さない従業員がいる場合があります。



図 5-集約



部門クラス:

 public class Department{ private String name; private Set employees = new HashSet(); public Department(String n){ name = n; } public void setName(String newName){ name = newName; } public String getName(){ return name; } public void addEmployee(Employee newEmployee){ employees.add(newEmployee); //      newEmployee.setDepartment(this); } public Set getEmployees(){ return employees; } public void removeEmployee(Employee e){ employees.remove(e); } }
      
      







したがって、クラスには、コンストラクターと部門の名前を変更するメソッドに加えて、部門に新しい従業員を追加し、従業員を削除し、この部門に含まれるすべての従業員を取得するメソッドがあります。 ダイアグラム上のナビゲーションは表示されません。つまり、双方向であることを意味します。「Department」タイプのオブジェクトから従業員について調べることができ、「Employee」タイプのオブジェクトから所属する部門を見つけることができます。



特定の従業員がどの部署に属しているかを簡単に見つける必要があるため、部署を割り当てたり受け取ったりするためにEmployeeクラスにフィールドとメソッドを追加します。



 ... private Department department; ... public void setDepartment(Department d){ department = d; } public Department getDepartment(){ return department; }
      
      







使用法:



 Department programmersDepartment = new Department(""); programmersDepartment.addEmployee(sysEngineer); System.out.println("   "+sysEngineer.getDepartment().getName());
      
      





2.3.1構成


システムの要件の1つが、企業で保持されていた以前の職位にデータを保存する要件であるとします。

新しいクラス「pastPosition」を紹介します。 「name」プロパティに加えて、「department」プロパティも導入します。これにより、「department」クラスに接続されます。



保持されている過去の職位に関するデータは従業員のデータの一部であるため、それらの間の全体的な関係と、同時に、「従業員」タイプのオブジェクトなしでは過去の職務に関するデータは存在できません。 Employeeオブジェクトを破棄すると、pastPositionオブジェクトが破壊されます。



図 6-構成



クラス「PastPosition」:

 private class PastPosition{ private String name; private Department department; public PastPosition(String position, Department dep){ name = position; department = dep; } public void setName(String newName){ name = newName; } public String getName(){ return name; } public void setDepartment(Department d){ department = d; } public Department getDepartment(){ return department; } }
      
      





Employeeクラスで、前の位置に関するデータを操作するためのプロパティとメソッドを追加します。

 ... private Set pastPosition = new HashSet(); ... public void setPastPosition(PastPosition p){ pastPosition.add(p); } public Set getPastPosition(){ return pastPosition; } public void deletePastPosition(PastPosition p){ pastPosition.remove(p); } ...
      
      







アプリケーション:

 //   sysEngineer.setPosition(""); //    : System.out.println("   :"); Iterator iter = sysEngineer.getPastPosition().iterator(); while(iter.hasNext()){ System.out.println( ((PastPosition) iter.next()).getName()); }
      
      







3.依存


ユーザーとの対話を整理するために、「Menu」クラスをシステムに導入します。 従業員とその役職のリストを表示する「showEmployees」という1つのメソッドを実装します。 メソッドのパラメーターは、Employeeオブジェクトの配列です。 したがって、Employeeクラスに加えられた変更には、Menuクラスの変更も必要になる場合があります。



図 7-依存



「メニュー」クラスはアプリケーション領域には適用されませんが、仮想アプリケーションの「システム」クラスを表すことに注意してください。

クラス「メニュー」:

 public class Menu{ private static int i=0; public static void showEmployees(Employee[] employees){ System.out.println(" :"); for (i=0; i<employees.length; i++){ if(employees[i] instanceof Employee){ System.out.println(employees[i].getName() +" - " + employees[i].getPosition()); } } } }
      
      







使用法:

 //     Employee director = new Employee("", "", ""); Menu menu = new Menu(); Employee employees[] = new Employee[10]; employees[0]= sysEngineer; employees[1] = director; Menu.showEmployees(employees);
      
      





4.実装


実装とは、継承のように、Java言語で明示的に表現されたものです。つまり、インターフェイス宣言と、クラスによる実装の可能性です。



実装関係を示すために、Unitインターフェースを作成します。 組織を部門だけでなく、たとえばワークショップ、支部などに分割できると考えている場合 Unitインターフェースは、最も抽象的な除算ユニットです。 特定の数の従業員が各部門ユニットで働いているため、作業者数を取得する方法は、Unitインターフェースを実装する各クラスに関連します。





図 8-実装



ユニットインターフェイス:



 public interface Unit{ int getPersonCount(); }
      
      





Departmentクラスでの実装:

 public class Department implements Unit{ ... public int getPersonCount(){ return getEmployees().size(); }
      
      







アプリケーション:

 System.out.println("  "+sysEngineer.getDepartment().getName()+"  " +sysEngineer.getDepartment().getPersonCount()+" .");
      
      







ご覧のとおり、getPersonCountメソッドの実装はDepartmentクラスに完全に関連しているわけではありません。

Employeeオブジェクトのコレクション。



完全なコード: http : //code.google.com/p/umljava/downloads/list



結論


UMLモデリング言語には、クラスモデルを構築するための一連のリレーションがありますが、Javaのような高度なOOP言語でも、リレーションシップを反映するための2つの明示的な構築だけがあります:拡張(拡張)とインターフェイス/実装(実装)です。

シミュレーションの結果、次の図が得られました。





図 8-クラス図



文学


1)G.ブーフ、D。ランボー、A。ジェイコブソン。 UML言語ユーザーガイド。



2) A.V. レオネンコフ。 UMLチュートリアル



3)Eckel B. Javaの哲学。 プログラマーのライブラリ。 -サンクトペテルブルク:Peter、2001 .-- 880 p。



4)Orlov S.テクノロジーソフトウェア開発:教科書。 -サンクトペテルブルク:Peter、2002。-464 p。



5)Mukhortov V.V.、Rylov V.Yu.オブジェクト指向プログラミング、分析、設計。 整然としたマニュアル。 -ノボシビルスク、2002年。



6) アナンド・ガネサン。 UMLでのクラス関係のモデリング



All Articles