OOAD-実装戦略
オブジェクト指向設計の実装には、通常、標準のオブジェクト指向プログラミング言語(OOPL)を使用するか、オブジェクト設計をデータベースにマッピングすることが含まれます。ほとんどの場合、両方が関係します。
プログラミング言語を使用した実装
通常、オブジェクト設計をコードに変換するタスクは簡単なプロセスです。C ++、Java、Smalltalk、C#、Pythonなどのオブジェクト指向プログラミング言語には、クラスを表すためのプロビジョニングが含まれています。この章では、C ++を使用した概念を例示します。
次の図は、C ++を使用したCircleクラスの表現を示しています。
アソシエーションの実装
ほとんどのプログラミング言語は、関連付けを直接実装するための構造を提供していません。したがって、アソシエーションを実装するタスクにはかなりの考慮が必要です。
アソシエーションは、単方向または双方向のいずれかです。さらに、各関連付けは、1対1、1対多、または多対多のいずれかになります。
一方向の関連付け
一方向の関連付けを実装するには、一方向性が維持されるように注意する必要があります。さまざまな多重度の実装は次のとおりです-
Optional Associations−ここでは、参加オブジェクト間にリンクが存在する場合と存在しない場合があります。たとえば、次の図の顧客と当座預金の関連付けでは、顧客は当座預金を持っている場合と持っていない場合があります。
実装のために、当座預金のオブジェクトは、NULLの可能性があるCustomerの属性として含まれています。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;
}
};
One–to–one Associations−ここで、クラスの1つのインスタンスは、関連付けられたクラスの1つのインスタンスにのみ関連しています。たとえば、次の図に示すように、部門とマネージャーには1対1の関連付けがあります。
これは、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;
}
};
One–to–many Associations−ここで、クラスの1つのインスタンスは、関連付けられたクラスの複数のインスタンスに関連付けられています。たとえば、次の図の従業員と扶養家族の関係について考えてみます。
これは、クラスEmployeeに依存関係のリストを含めることによって実装されます。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);
}
};
双方向の関連付け
双方向の関連付けを実装するには、両方向のリンクを維持する必要があります。
Optional or one–to–one Associations −次の図に示すように、1対1の双方向の関連付けを持つプロジェクトとプロジェクトマネージャーの関係を検討してください。
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();
};
One–to–many Associations −次の図に示すように、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
};
制約の実装
クラスの制約は、属性が取ることができる値の範囲とタイプを制限します。制約を実装するために、オブジェクトがクラスからインスタンス化されるときに、有効なデフォルト値が属性に割り当てられます。実行時に値が変更されるたびに、値が有効かどうかがチェックされます。無効な値は、例外処理ルーチンまたは他のメソッドによって処理される場合があります。
Example
年齢が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)では、データはリレーションまたはテーブルとして格納されます。各列またはフィールドは属性を表し、各行またはタプルはインスタンスのレコードを表します。
各行は、と呼ばれる最小限の属性の選択されたセットによって一意に識別されます primary key。
A foreign key 関連するテーブルの主キーである属性です。
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の関連付けを実装するために、一方のテーブルの主キーがもう一方のテーブルの外部キーとして割り当てられます。たとえば、部門とマネージャーの関係について考えてみましょう。
テーブルを作成するための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アソシエーションを実装するために、アソシエーションを表す新しいリレーションが作成されます。たとえば、従業員とプロジェクトの間の次の関連付けについて考えてみます。
Schema for Works_On Table − WORKS_ON(EMPID、PID、HOURS、START_DATE)
SQL command to create Works_On association − 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
);
継承のテーブルへのマッピング
継承をマップするために、ベーステーブルの主キーが、派生テーブルの外部キーと同様に主キーとして割り当てられます。
Example