- OOAD 教程
- OOAD - 首頁
- OOAD - 面向物件正規化
- OOAD - 面向物件模型
- OOAD - 面向物件系統
- OOAD - 面向物件原則
- OOAD - 面向物件分析
- OOAD - 動態建模
- OOAD - 功能建模
- OOAD - UML 分析模型
- OOAD - UML 基本符號
- OOAD - UML 結構圖
- OOAD - UML 行為圖
- OOAD - 面向物件設計
- OOAD - 實現策略
- OOAD - 測試與質量保證
- OOAD 有用資源
- OOAD - 快速指南
- OOAD - 有用資源
OOAD - 實現策略
實現面向物件設計通常涉及使用標準的面向物件程式語言 (OOPL) 或將物件設計對映到資料庫。在大多數情況下,它涉及兩者。
使用程式語言實現
通常,將物件設計轉換為程式碼的任務是一個簡單的過程。任何面向物件程式語言,如 C++、Java、Smalltalk、C# 和 Python,都包含表示類的規定。在本章中,我們將使用 C++ 例舉此概念。
下圖顯示了使用 C++ 表示 Circle 類。
實現關聯
大多數程式語言不提供直接實現關聯的構造。因此,實現關聯的任務需要仔細考慮。
關聯可以是單向的或雙向的。此外,每個關聯可以是一對一、一對多或多對多。
單向關聯
在實現單向關聯時,應注意維護單向性。不同多重性的實現如下所示 -
可選關聯 - 在這裡,參與物件之間可能存在或不存在連結。例如,在下圖中,客戶和活期賬戶之間的關聯,客戶可能擁有或不擁有活期賬戶。
對於實現,在 Customer 中包含一個 Current Account 的物件,該物件可能為 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;
}
};
一對一關聯 - 在這裡,一個類的例項與關聯類的正好一個例項相關聯。例如,部門和經理之間存在一對一關聯,如下面的圖所示。
這是透過在 Department 中包含一個 Manager 物件來實現的,該物件不能為 NULL。使用 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;
}
};
一對多關聯 - 在這裡,一個類的例項與關聯類的多個例項相關聯。例如,考慮 Employee 和 Dependent 之間的關聯,如下面的圖所示。
這是透過在 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);
}
};
雙向關聯
要實現雙向關聯,需要維護兩個方向的連結。
可選或一對一關聯 - 考慮 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();
};
一對多關聯 - 考慮 Department 和 Employee 之間具有多對一關聯的關係,如下面的圖所示。
使用 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();
};
將關聯實現為類
如果關聯有一些相關的屬性,則應使用單獨的類來實現它。例如,考慮 Employee 和 Project 之間的一對一關聯,如下面的圖所示。
使用 C++ 實現 WorksOn
class WorksOn {
private:
Employee e;
Project p;
Hours h;
char * date;
public:
// class methods
};
實現約束
類中的約束限制了屬性可以取的值的範圍和型別。為了實現約束,在從類例項化物件時,會為屬性分配一個有效的預設值。每當在執行時更改值時,都會檢查該值是否有效。無效值可以透過異常處理例程或其他方法來處理。
示例
考慮一個 Employee 類,其中 age 是一個屬性,其值範圍為 18 到 60。以下 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;
}
};
實現狀態圖
有兩種替代的實現策略來實現狀態圖中的狀態。
類中的列舉
在這種方法中,狀態由資料成員(或一組資料成員)的不同值表示。這些值由類中的列舉顯式定義。轉換由更改相關資料成員值的成員函式表示。
泛化層次結構中類的排列
在這種方法中,狀態以一種可以由公共指標變數引用的方式排列在泛化層次結構中。下圖顯示了從狀態圖到泛化層次結構的轉換。
物件對映到資料庫系統
物件的永續性
開發面向物件系統的一個重要方面是資料的永續性。透過永續性,物件比建立它的程式具有更長的生命週期。永續性資料儲存在輔助儲存介質上,可以在需要時從那裡重新載入。
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 關聯,任何一個表的主鍵都分配為另一個表的外部索引鍵。例如,考慮 Department 和 Manager 之間的關聯 -
建立表的 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:N 關聯,關聯 1 端的表的主鍵分配為關聯 N 端的表的外部索引鍵。例如,考慮 Department 和 Employee 之間的關聯 -
建立表的 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 關聯,將建立一個新的關係來表示關聯。例如,考慮 Employee 和 Project 之間的以下關聯 -
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 );
將繼承對映到表
要對映繼承,基表的主鍵分配為派生表的主鍵和外部索引鍵。
示例