Учебники

OOAD — Стратегии реализации

Реализация объектно-ориентированного проектирования обычно включает использование стандартного объектно-ориентированного языка программирования (OOPL) или сопоставление объектных проектов с базами данных. В большинстве случаев это включает оба.

Реализация с использованием языков программирования

Обычно задача преобразования объекта в код — это простой процесс. Любой объектно-ориентированный язык программирования, такой как C ++, Java, Smalltalk, C # и Python, включает в себя условия для представления классов. В этой главе мы иллюстрируем концепцию, используя C ++.

На следующем рисунке показано представление класса Circle с использованием C ++.

Представление круга класса

Реализация Ассоциаций

Большинство языков программирования не предоставляют конструкций для непосредственной реализации ассоциаций. Таким образом, задача внедрения ассоциаций требует значительных усилий.

Ассоциации могут быть как однонаправленными, так и двунаправленными. Кроме того, каждая ассоциация может быть либо один к одному, один ко многим, либо много ко многим.

Однонаправленные Ассоциации

Для реализации однонаправленных ассоциаций необходимо соблюдать осторожность, чтобы поддерживать однонаправленность. Реализации для различной множественности следующие:

  • Необязательные ассоциации. Здесь может существовать или не существовать связь между участвующими объектами. Например, в связи между клиентом и текущим счетом на рисунке ниже, клиент может иметь или не иметь текущий счет.

Необязательные ассоциации. Здесь может существовать или не существовать связь между участвующими объектами. Например, в связи между клиентом и текущим счетом на рисунке ниже, клиент может иметь или не иметь текущий счет.

Однонаправленная Ассоциация

Для реализации объект Текущего счета включен в качестве атрибута в 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;
   } 
};
  • Связи один-к-одному — Здесь один экземпляр класса связан ровно с одним экземпляром ассоциированного класса. Например, отдел и менеджер имеют непосредственную связь, как показано на рисунке ниже.

Связи один-к-одному — Здесь один экземпляр класса связан ровно с одним экземпляром ассоциированного класса. Например, отдел и менеджер имеют непосредственную связь, как показано на рисунке ниже.

Однонаправленная ассоциация один к одному

Это реализуется путем включения в 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. Реализация с использованием контейнера списков 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);
   }               
};

Двунаправленные ассоциации

Для реализации двунаправленной ассоциации необходимо поддерживать связь в обоих направлениях.

  • Необязательные или взаимно-однозначные ассоциации. Рассмотрим взаимосвязь между Проектом и Руководителем проекта, имеющую двустороннюю связь «один-к-одному», как показано на рисунке ниже.

Необязательные или взаимно-однозначные ассоциации. Рассмотрим взаимосвязь между Проектом и Руководителем проекта, имеющую двустороннюю связь «один-к-одному», как показано на рисунке ниже.

Двунаправленная ассоциация один к одному

Реализация с использованием 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 <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();
};

Реализация ассоциаций как классов

Если с ассоциацией связаны некоторые атрибуты, она должна быть реализована с использованием отдельного класса. Например, рассмотрим связь «один к одному» между сотрудником и проектом, как показано на рисунке ниже.

Реализация ассоциации с классом

Реализация WorksOn с использованием C ++

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) данные хранятся в виде отношений или таблиц, где каждый столбец или поле представляет атрибут, а каждая строка или кортеж представляет запись экземпляра.

Каждая строка уникально идентифицируется выбранным набором минимальных атрибутов, называемых первичным ключом .

Внешний ключ — это атрибут, который является первичным ключом связанной таблицы.

Представление классов в виде таблиц в РСУБД

Чтобы отобразить класс в таблицу базы данных, каждый атрибут представлен в виде поля в таблице. Либо существующий атрибут (ы) назначается в качестве первичного ключа, либо отдельное поле идентификатора добавляется в качестве первичного ключа. Класс может быть разделен горизонтально или вертикально согласно требованию.

Например, класс 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, HOURS, START_DATE)

Команда SQL для создания ассоциации Works_On — 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 
);

Отображение наследования в таблицы

Для сопоставления наследования первичный ключ базовой таблицы (таблиц) назначается как первичный ключ, а также внешний ключ в производной таблице (таблицах).

пример