OOAD - 实现策略



实现面向对象设计通常涉及使用标准的面向对象编程语言 (OOPL) 或将对象设计映射到数据库。在大多数情况下,它涉及两者。

使用编程语言实现

通常,将对象设计转换为代码的任务是一个简单的过程。任何面向对象编程语言,如 C++、Java、Smalltalk、C# 和 Python,都包含表示类的规定。在本章中,我们将使用 C++ 例举此概念。

下图显示了使用 C++ 表示 Circle 类。

Class Circle Representation

实现关联

大多数编程语言不提供直接实现关联的构造。因此,实现关联的任务需要仔细考虑。

关联可以是单向的或双向的。此外,每个关联可以是一对一、一对多或多对多。

单向关联

在实现单向关联时,应注意维护单向性。不同多重性的实现如下所示 -

  • 可选关联 - 在这里,参与对象之间可能存在或不存在链接。例如,在下图中,客户和活期账户之间的关联,客户可能拥有或不拥有活期账户。

Unidirectional Association

对于实现,在 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;
   } 
};
  • 一对一关联 - 在这里,一个类的实例与关联类的正好一个实例相关联。例如,部门和经理之间存在一对一关联,如下面的图所示。

One to One Unidirectional Association

这是通过在 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 之间的关联,如下面的图所示。

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);
   }               
};

双向关联

要实现双向关联,需要维护两个方向的链接。

  • 可选或一对一关联 - 考虑 Project 和 Project Manager 之间具有双向一对一关联的关系,如下面的图所示。

One to One Bidirectional Association

使用 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 之间具有多对一关联的关系,如下面的图所示。

One to Many Bidirectional Association

使用 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 之间的一对一关联,如下面的图所示。

Implementing Association with a Class

使用 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;			
   }
};

实现状态图

有两种替代的实现策略来实现状态图中的状态。

类中的枚举

在这种方法中,状态由数据成员(或一组数据成员)的不同值表示。这些值由类中的枚举显式定义。转换由更改相关数据成员值的成员函数表示。

泛化层次结构中类的排列

在这种方法中,状态以一种可以由公共指针变量引用的方式排列在泛化层次结构中。下图显示了从状态图到泛化层次结构的转换。

Implementing State Charts

对象映射到数据库系统

对象的持久性

开发面向对象系统的一个重要方面是数据的持久性。通过持久性,对象比创建它的程序具有更长的生命周期。持久性数据保存在辅助存储介质上,可以在需要时从那里重新加载。

RDBMS 概述

数据库是相关数据的有序集合。

数据库管理系统 (DBMS) 是一个软件集合,它有助于定义、创建、存储、操作、检索、共享和删除数据库中的数据。

在关系数据库管理系统 (RDBMS) 中,数据存储为关系或表,其中每一列或字段表示一个属性,每一行或元组表示一个实例的记录。

每一行都由一组称为主键的最小属性唯一标识。

外键是相关表的主键的属性。

在 RDBMS 中将类表示为表

要将类映射到数据库表,每个属性都表示为表中的一个字段。将现有属性(或属性)分配为主键,或添加一个单独的 ID 字段作为主键。类可以根据需要水平或垂直分区。

例如,Circle 类可以转换为如下所示的表。

Representing Classes as Tables
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 之间的关联 -

One–to–One Associations

创建表的 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 之间的关联 -

One–to–Many Associations

创建表的 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 之间的以下关联 -

Many–to–Many Associations

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 
);

将继承映射到表

要映射继承,基表的主键分配为派生表的主键和外键。

示例

Mapping Inheritance to Tables
广告