📜  OOAD-实施策略

📅  最后修改于: 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();   
};
  • 一对多关联-考虑部门与具有一对多关联的雇员之间的关系,如下图所示。

一对多双向关联

使用C++ STL列表容器的实现

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之间的一对一关联。

与班级实施协会

使用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关联,将任何一个表的主键分配为另一表的外键。例如,考虑部门和经理之间的关联-

一对一协会

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侧的表的外键。例如,考虑部门与雇员之间的关联-

一对多协会

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,小时,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 
);

将继承映射到表

为了映射继承,将基表的主键以及派生表中的外键分配为主键。

将继承映射到表