OOAD - Стратегии внедрения
Реализация объектно-ориентированного дизайна обычно включает использование стандартного объектно-ориентированного языка программирования (OOPL) или отображение дизайна объектов на базы данных. В большинстве случаев это касается обоих.
Реализация с использованием языков программирования
Обычно задача преобразования дизайна объекта в код - простой процесс. Любой объектно-ориентированный язык программирования, такой как C ++, Java, Smalltalk, C # и Python, включает возможность представления классов. В этой главе мы проиллюстрируем эту концепцию на примере C ++.
На следующем рисунке показано представление класса Circle с использованием C ++.
Реализующие ассоциации
Большинство языков программирования не предоставляют конструкции для непосредственной реализации ассоциаций. Так что задача создания ассоциаций требует серьезного размышления.
Ассоциации могут быть как однонаправленными, так и двунаправленными. Кроме того, каждая ассоциация может быть один-к-одному, один-ко-многим или многие-ко-многим.
Однонаправленные ассоциации
При реализации однонаправленных ассоциаций следует позаботиться о сохранении однонаправленности. Реализации для разной кратности следующие:
Optional Associations- Здесь связь между участвующими объектами может существовать, а может и не существовать. Например, в связи между клиентом и текущим счетом на рисунке ниже клиент может иметь или не иметь текущий счет.
Для реализации объект Current Account включается в качестве атрибута в Customer, который может иметь значение 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 Associations- Здесь один экземпляр класса связан ровно с одним экземпляром связанного класса. Например, у отдела и менеджера есть взаимно однозначная связь, как показано на рисунке ниже.
Это реализуется включением в 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;
}
};
One–to–many Associations- Здесь один экземпляр класса связан с более чем одним экземпляром связанного класса. Например, рассмотрим связь между сотрудником и зависимым на следующем рисунке.
Это реализуется включением списка иждивенцев в класс Employee. Реализация с использованием контейнера списков STL C ++ -
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);
}
};
Двунаправленные ассоциации
Чтобы реализовать двунаправленную ассоциацию, необходимо поддерживать связи в обоих направлениях.
Optional or one–to–one Associations - Рассмотрите связь между проектом и менеджером проекта, имеющую двунаправленную связь один-к-одному, как показано на рисунке ниже.
Реализация с использованием 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();
};
One–to–many Associations - Рассмотрим отношения между отделом и сотрудником, имеющие связь «один ко многим», как показано на рисунке ниже.
Реализация с использованием контейнера списка 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
};
Реализация ограничений
Ограничения в классах ограничивают диапазон и тип значений, которые могут принимать атрибуты. Для реализации ограничений атрибуту присваивается допустимое значение по умолчанию, когда объект создается из класса. Каждый раз, когда значение изменяется во время выполнения, проверяется, действительно ли значение. Недопустимое значение может быть обработано процедурой обработки исключений или другими методами.
Example
Рассмотрим класс Employee, где возраст является атрибутом, который может иметь значения в диапазоне от 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;
}
};
Реализация диаграмм состояний
Есть две альтернативные стратегии реализации для реализации состояний в диаграммах диаграмм состояний.
Перечисления внутри класса
В этом подходе состояния представлены разными значениями элемента данных (или набора элементов данных). Значения явно определяются перечислением внутри класса. Переходы представлены функциями-членами, которые изменяют значение соответствующего элемента данных.
Расположение классов в иерархии обобщений
В этом подходе состояния организованы в иерархию обобщения таким образом, чтобы на них можно было ссылаться с помощью общей переменной-указателя. На следующем рисунке показано преобразование диаграммы состояний в иерархию обобщения.
Отображение объекта в систему базы данных
Постоянство объектов
Важным аспектом разработки объектно-ориентированных систем является постоянство данных. Благодаря настойчивости объекты имеют более длительный срок службы, чем программа, которая их создала. Постоянные данные сохраняются на вторичном носителе, откуда их можно перезагружать при необходимости.
Обзор СУБД
База данных - это упорядоченный набор связанных данных.
Система управления базами данных (СУБД) - это набор программного обеспечения, которое упрощает процессы определения, создания, хранения, манипулирования, извлечения, совместного использования и удаления данных в базах данных.
В системах управления реляционными базами данных (СУБД) данные хранятся в виде отношений или таблиц, где каждый столбец или поле представляет атрибут, а каждая строка или кортеж представляет собой запись экземпляра.
Каждая строка уникально идентифицируется выбранным набором минимальных атрибутов, называемых primary key.
А foreign key - атрибут, являющийся первичным ключом связанной таблицы.
Представление классов в виде таблиц в СУБД
Чтобы сопоставить класс с таблицей базы данных, каждый атрибут представлен в виде поля в таблице. Либо существующие атрибуты назначаются в качестве первичного ключа, либо в качестве первичного ключа добавляется отдельное поле идентификатора. Класс может быть разделен по горизонтали или вертикали в соответствии с требованиями.
Например, класс 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, создается новое отношение, которое представляет ассоциацию. Например, рассмотрим следующую связь между сотрудником и проектом:
Schema for Works_On Table - WORKS_ON (EMPID, PID, HOURS, START_DATE)
SQL command to create Works_On association - СОЗДАТЬ ТАБЛИЦУ 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
);
Сопоставление наследования с таблицами
Для сопоставления наследования первичный ключ базовой таблицы (таблиц) назначается в качестве первичного ключа, а также внешнего ключа в производных таблицах.
Example