Object-oriented-analysis-design-ooad-implementation-strategies
OOAD-実装戦略
通常、オブジェクト指向設計の実装には、標準オブジェクト指向プログラミング言語(OOPL)の使用、またはオブジェクト設計のデータベースへのマッピングが含まれます。 ほとんどの場合、両方が含まれます。
プログラミング言語を使用した実装
通常、オブジェクト設計をコードに変換するタスクは簡単なプロセスです。 C 、Java、Smalltalk、C#、Pythonなどのオブジェクト指向プログラミング言語には、クラスを表現するためのプロビジョニングが含まれています。 この章では、C を使用した概念を例示します。
次の図は、C ++を使用したCircleクラスの表現を示しています。
アソシエーションの実装
ほとんどのプログラミング言語は、関連付けを直接実装するための構造を提供しません。 したがって、アソシエーションを実装するタスクには相当な検討が必要です。
関連付けは単方向または双方向のいずれかです。 また、各関連付けは1対1、1対多、または多対多のいずれかです。
単方向の関連付け
単方向の関連付けを実装するには、単方向性が維持されるように注意する必要があります。 さまざまな多重度の実装は次のとおりです-
- オプションの関連付け-ここでは、参加オブジェクト間にリンクが存在する場合と存在しない場合があります。 たとえば、下図の顧客と当座預金口座との関連付けでは、顧客は当座預金口座を持っている場合と持っていない場合があります。
実装のために、現在のアカウントのオブジェクトは、NULLである可能性がある顧客の属性として含まれています。 C ++を使用した実装-
class Customer {
private:
//attributes
Current_Account c;//an object of Current_Account as attribute
public:
Customer() {
c = NULL;
}//assign c as NULL
Current_Account getCurrAc() {
return c;
}
void setCurrAc( Current_Account myacc) {
c = myacc;
}
void removeAcc() {
c = NULL;
}
};
- * 1対1の関連付け*-ここでは、クラスの1つのインスタンスは、関連付けられたクラスの1つのインスタンスにのみ関連付けられています。 たとえば、下の図に示すように、DepartmentとManagerには1対1の関連付けがあります。
One to One Unidirectional Association
これは、NULLであってはならないManagerのオブジェクトであるDepartmentに含めることで実装されます。 C ++を使用した実装-
class Department {
private:
//attributes
Manager mgr;//an object of Manager as attribute
public:
Department (/*parameters*/, Manager m) {//m is not NULL
//assign parameters to variables
mgr = m;
}
Manager getMgr() {
return mgr;
}
};
- * 1対多の関連付け*-ここでは、クラスの1つのインスタンスが、関連付けられたクラスの複数のインスタンスに関連付けられています。 たとえば、次の図のEmployeeとDependentの間の関連付けを検討してください。
One to Many Unidirectional Association
これは、クラスEmployeeにDependentsのリストを含めることで実装されます。 C ++ STLリストコンテナを使用した実装-
class Employee {
private:
char * deptName;
list <Dependent> dep;//a list of Dependents as attribute
public:
void addDependent ( Dependent d) {
dep.push_back(d);
}//adds an employee to the department
void removeDeoendent( Dependent d) {
int index = find ( d, dep );
//find() function returns the index of d in list dep
dep.erase(index);
}
};
双方向の関連付け
双方向の関連付けを実装するには、両方向のリンクを維持する必要があります。
- オプションまたは1対1の関連付け-下の図に示すように、1対1の双方向の関連付けを持つProjectとProject Managerの関係を考慮します。
C ++を使用した実装-
Class Project {
private:
//attributes
Project_Manager pmgr;
public:
void setManager ( Project_Manager pm);
Project_Manager changeManager();
};
class Project_Manager {
private:
//attributes
Project pj;
public:
void setProject(Project p);
Project removeProject();
};
- * 1対多の関連付け*-下図に示すように、1対多の関連付けを持つ部門と従業員の間の関係を考慮します。
C ++ STLリストコンテナを使用した実装
class Department {
private:
char *deptName;
list <Employee> emp;//a list of Employees as attribute
public:
void addEmployee ( Employee e) {
emp.push_back(e);
}//adds an employee to the department
void removeEmployee( Employee e) {
int index = find ( e, emp );
//find function returns the index of e in list emp
emp.erase(index);
}
};
class Employee {
private:
//attributes
Department d;
public:
void addDept();
void removeDept();
};
関連付けをクラスとして実装する
関連付けに属性が関連付けられている場合、別のクラスを使用して実装する必要があります。 たとえば、次の図に示すように、従業員とプロジェクトの間の1対1の関連付けを検討します。
C ++を使用したWorksOnの実装
class WorksOn {
private:
Employee e;
Project p;
Hours h;
char* date;
public:
//class methods
};
制約の実装
クラスの制約は、属性が取る値の範囲とタイプを制限します。 制約を実装するために、オブジェクトがクラスからインスタンス化されるときに、有効なデフォルト値が属性に割り当てられます。 実行時に値が変更されるたびに、値が有効かどうかがチェックされます。 無効な値は、例外処理ルーチンまたは他のメソッドによって処理される場合があります。
- 例 *
年齢が18から60の範囲の値を持つ属性であるEmployeeクラスを考えます。 次のC ++コードにはそれが組み込まれています-
class Employee {
private: char* name;
int age;
//other attributes
public:
Employee() { //default constructor
strcpy(name, "");
age = 18; //default value
}
class AgeError {}; //Exception class
void changeAge( int a) { //method that changes age
if ( a < 18 || a > 60 ) //check for invalid condition
throw AgeError(); //throw exception
age = a;
}
};
状態図の実装
状態チャート図に状態を実装するには、2つの代替実装戦略があります。
クラス内の列挙
このアプローチでは、状態はデータメンバー(またはデータメンバーのセット)の異なる値によって表されます。 値は、クラス内の列挙によって明示的に定義されます。 遷移は、関係するデータメンバーの値を変更するメンバー関数によって表されます。
汎化階層でのクラスの配置
このアプローチでは、一般的なポインター変数によって参照できるように、状態が一般化階層に配置されます。 次の図は、状態チャート図から一般化階層への変換を示しています。
データベースシステムへのオブジェクトマッピング
オブジェクトの永続性
オブジェクト指向システムの開発の重要な側面は、データの永続性です。 永続性により、オブジェクトはそれを作成したプログラムよりも長い寿命を持ちます。 永続データは、必要に応じてリロードできる場所からセカンダリストレージメディアに保存されます。
RDBMSの概要
データベースは、関連データの順序付けられたコレクションです。
データベース管理システム(DBMS)は、データベース内のデータの定義、作成、保存、操作、取得、共有、および削除のプロセスを容易にするソフトウェアのコレクションです。
リレーショナルデータベース管理システム(RDBMS)では、データはリレーションまたはテーブルとして保存されます。各列またはフィールドは属性を表し、各行またはタプルはインスタンスのレコードを表します。
各行は、「主キー」と呼ばれる選択された最小限の属性のセットによって一意に識別されます。
- 外部キー*は、関連テーブルの主キーである属性です。
RDBMSでクラスをテーブルとして表現する
クラスをデータベーステーブルにマップするために、各属性はテーブル内のフィールドとして表されます。 既存の属性が主キーとして割り当てられるか、別のIDフィールドが主キーとして追加されます。 クラスは、要件に応じて水平または垂直に分割できます。
たとえば、下の図に示すように、Circleクラスをテーブルに変換できます。
Schema for Circle Table: CIRCLE(CID, X_COORD, Y_COORD, RADIUS, COLOR)
Creating a Table Circle using SQL command:
CREATE TABLE CIRCLE (
CID VARCHAR2(4) PRIMARY KEY,
X_COORD INTEGER NOT NULL,
Y_COORD INTEGER NOT NULL,
Z_COORD INTEGER NOT NULL,
COLOR
);
データベーステーブルへの関連付けのマッピング
1対1の関連付け
1:1の関連付けを実装するには、1つのテーブルの主キーが他のテーブルの外部キーとして割り当てられます。 たとえば、部門とマネージャー間の関連付けを考慮してください-
テーブルを作成するSQLコマンド
CREATE TABLE DEPARTMENT (
DEPT_ID INTEGER PRIMARY KEY,
DNAME VARCHAR2(30) NOT NULL,
LOCATION VARCHAR2(20),
EMPID INTEGER REFERENCES MANAGER
);
CREATE TABLE MANAGER (
EMPID INTEGER PRIMARY KEY,
ENAME VARCHAR2(50) NOT NULL,
ADDRESS VARCHAR2(70),
);
1対多の関連付け
1:Nアソシエーションを実装するには、アソシエーションの1側のテーブルの主キーが、アソシエーションのN側のテーブルの外部キーとして割り当てられます。 たとえば、部門と従業員との間の関連付けを検討してください-
テーブルを作成するSQLコマンド
CREATE TABLE DEPARTMENT (
DEPT_ID INTEGER PRIMARY KEY,
DNAME VARCHAR2(30) NOT NULL,
LOCATION VARCHAR2(20),
);
CREATE TABLE EMPLOYEE (
EMPID INTEGER PRIMARY KEY,
ENAME VARCHAR2(50) NOT NULL,
ADDRESS VARCHAR2(70),
D_ID INTEGER REFERENCES DEPARTMENT
);
多対多の関連付け
M:Nアソシエーションを実装するために、アソシエーションを表す新しい関係が作成されます。 たとえば、従業員とプロジェクトの間の次の関連付けを検討してください-
- Works_Onテーブルのスキーマ*-WORKS_ON(EMPID、PID、HOURS、START_DATE)
- Works_On関連付けを作成するSQLコマンド*-CREATE TABLE WORKS_ON
(
EMPID INTEGER,
PID INTEGER,
HOURS INTEGER,
START_DATE DATE,
PRIMARY KEY (EMPID, PID),
FOREIGN KEY (EMPID) REFERENCES EMPLOYEE,
FOREIGN KEY (PID) REFERENCES PROJECT
);
テーブルへの継承のマッピング
継承をマッピングするために、ベーステーブルのプライマリキーが、派生テーブルの外部キーと同様にプライマリキーとして割り当てられます。
例