📅  最后修改于: 2020-12-14 04:13:29             🧑  作者: Mango
实施面向对象的设计通常涉及使用标准的面向对象的编程语言(OOPL)或将对象设计映射到数据库。在大多数情况下,这两者都涉及。
通常,将对象设计转换为代码的任务很简单。任何面向对象的编程语言(例如C++,Java,Smalltalk,C#和Python)都包含表示类的规定。在本章中,我们将使用C++举例说明这一概念。
下图显示了使用C++的Circle类的表示形式。
大多数编程语言不提供直接实现关联的构造。因此,实现协会的任务需要大量考虑。
关联可以是单向或双向的。此外,每个关联可能是一对一,一对多或多对多。
为了实现单向关联,应注意保持单向性。不同多样性的实现如下-
可选的关联-在这里,参与对象之间可能存在链接,也可能不存在链接。例如,在下图中“客户”与“当前帐户”之间的关联中,客户可能拥有也可能没有经常账户。
为了实现,将“当前帐户”的对象作为属性包含在“客户”中,该属性可以为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类中包含一个从属列表来实现的。使用C++ STL列表容器的实现-
class Employee {
private:
char * deptName;
list 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();
};
一对多关联-考虑部门与具有一对多关联的雇员之间的关系,如下图所示。
class Department {
private:
char * deptName;
list 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之间的一对一关联。
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;
}
};
有两种替代的实现策略可以在状态图图中实现状态。
在这种方法中,状态由数据成员(或一组数据成员)的不同值表示。这些值由类中的枚举明确定义。转换由成员函数表示,这些成员函数更改了相关数据成员的值。
在这种方法中,状态可以通过通用指针变量引用的方式排列在概括层次结构中。下图显示了从状态图到通用层次结构的转换。
开发面向对象系统的一个重要方面是数据的持久性。通过持久性,对象的寿命比创建对象的程序更长。永久数据保存在辅助存储介质上,可以在需要时从中重新加载。
数据库是相关数据的有序集合。
数据库管理系统(DBMS)是一组软件,可简化定义,创建,存储,操纵,检索,共享和删除数据库中数据的过程。
在关系数据库管理系统(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关联,将任何一个表的主键分配为另一表的外键。例如,考虑部门和经理之间的关联-
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侧的表的外键。例如,考虑部门与雇员之间的关联-
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,小时,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
);
为了映射继承,将基表的主键以及派生表中的外键分配为主键。
例