Всеосяжна ПРИКЛАД об’єктного підходу

У попередньому розділі були представлені базові концепції обєктного підходу У цьому розділі на вичерпному прикладі послідовно демонструється застосування цих ідей на практиці, а саме: тут показано, як визначається обєктна база даних, як вона поповнюється даними і як в ній виконуються операції вибірки та оновлення даних У розглянутому прикладі використовуються обєктна СУБД GemStone (розробка корпорації GemStone Systems) і її мова запитів OPAL [2513] Мова OPAL, в свою чергу, заснований на мові Smalltalk [2523]

Примітка Мова Smalltalk відноситься до числа найбільш ранніх і чистих втілень обєктного підходу, тому він використовується тут як приклад, але заради справедливості слід зазначити, що в програмних продуктах і додатках він все частіше замінюється мовою C + +, а останнім часом-мовою Java

Як приклад скористаємося спрощеною версією бази даних професійної підготовки з упр 97 глави 9 У цій базі даних міститься інформація про схему підготовки та навчання фахівців усередині деякої компанії Для кожного

курсу навчання (COURSE) в базі даних міститься опис окремих потоків, організованих для його вивчення (OFFERING) Для кожного потоку зберігаються дані про всі його слухачах (ENROLLMENT) і викладачах (TEACHER) Крім того, в базі містяться відомості про співробітників компанії ОМР Реляційну версію бази даних можна

описати таким чином

COURSE    { COURSE*, TITLE }

OFFERING  { COURSES, OFF#, OFFDATE, LOCATION } TEACHER   { COURSES, OFF#, EMP# }

ENROLLMENT { COURSE*, OFF#, EMP#, GRADE }

EMP                                         { EMP#, ENAME, SALARY, POSITION }

Рис 256 Схема звязків для освітньої бази даних

На рис 256 показана схема звязків для розглянутої бази даних

Визначення даних

Тепер перейдемо до визначення даних мовою OPAL для освітньої бази даних Нижче наводиться перше визначення обєктного класу ОМР, що описує співробітників (для зручності рядки цього визначення пронумеровані)

1 OBJECT SUBCLASS: ОМР

2 INSTVARNAMES: # [ОМР #, ENAME, POSITION]

3 CONSTRAINTS: # [# [# ОМР #, STRING],

4&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ #ENAME, STRING ],

5&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ #POSITION, STRING ] ]

Пояснення У рядку 1 визначено обєктний клас ОМР як підклас вбудованого класу OBJECT (Згідно термінології мови OPAL, в рядку 1 передається повідомлення обєкту OBJECT із запитом викликати метод SUBCLASS в цьому виклику методу задані фактичні параметри INSTVARNAMES і CONSTRAINTS Для визначення нового класу, як і всього іншого, в мові OPAL необхідно відправити повідомлення обєкту) У рядку 2 зазначено, що обєкти класу ОМР мають, відповідно, три закриті змінні екземпляра – ОМР #, ENAME і POSITION, а в рядках 3-5 на ці змінні екземпляра накладаються обмеження, які вказують, що вони повинні містити обєкти класу STRING

Примітка У даний главі ігноруються чисто синтаксичні подробиці, несуттєві для переслідуваних нами цілей (зокрема, те, що всюдисущі знаки #, застосовувані в даному прикладі, не допускаються за умовами синтаксису)

Підкреслимо, що змінні екземпляра ОМР #, ENAME І POSITION- закриті змінні для класу ОМР, тому доступ до них по іменах допустимо тільки в коді реалізації методів цього класу Як приклад нижче дано визначення методів отримати і встановити, тобто методів, що дозволяють вибрати і оновити номера службовців (тут символ ^ можна читати як повернути)

METHOD: ОМР

GET_EMP#

^ ОМР #

%

METHOD: ОМР

SET_EMP# : EMP#_PARM

ОМР #: = EMP # _PARM%

У наступному підрозділі про методи ми поговоримо докладніше А зараз розглянемо визначення класу COURSE

1&nbsp&nbsp&nbsp OBJECT SUBCLASS : COURSE

2&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INSTVARNAMES : #[ COURSE*, TITLE, OFFERINGS ]

3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp CONSTRAINTS : #[ #[ #COURSE#, STRING ] ,

4&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ #TITLE, STRING ] ,

5&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ SUFFERINGS, OSET ] ]

Пояснення У рядку 5 визначена закрита змінна екземпляра OFFERINGS, яка містить ідентифікатор обєкту класу OSET (цей клас буде визначений дещо пізніше) Висловлюючись неформально, змінна OFFERINGS позначає безліч всіх потоків для даного курсу Інакше кажучи, звязок курс-потік моделюється за допомогою ієрархії вкладення, в якій потоки концептуально містяться всередині відповідного курсу Визначення класу потоку OFFERING може бути записано таким чином

1&nbsp&nbsp&nbsp OBJECT SUBCLASS : OFFERING

2&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INSTVARNAMES : #[ OFF*, ODATE, LOCATION,

3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ENROLLMENTS , TEACHERS ]

4&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp CONSTRAINTS : #[ #[ #OFF#, STRING ] ,

5&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [#ODATE, DATETIME ],

6&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [#LOCATION, STRING ],

7&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [«ENROLLMENTS, NSET ],

8&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [#TEACHERS, TSET ] ]

Пояснення У рядку 7 визначається закрита змінна екземпляра ENROLLMENTS, що містить ідентифікатор обєкта класу NSET Говорячи неформально, змінна ENROLLMENTS позначає безліч всіх слухачів в даному потоці Аналогічним чином, змінна TEACHERS позначає безліч всіх викладачів розглянутого потоку Тому тут знову використовується представлення ієрархії вкладення Визначення класів NSET і TSET будуть дані нижче Визначення класу слухачів ENROLLMENT може бути записано таким чином

1&nbsp&nbsp&nbsp OBJECT SUBCLASS : ENROLLMENT

2&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INSTVARNAMES : # [ EMP , GRADE ]

3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp CONSTRAINTS : #[ #[ #EMP, EMP ] ,

4&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ #GRADE, STRING ] ]

Пояснення У рядку 3 визначається закрита змінна екземпляра ОМР, що містить ідентифікатор обєкта класу ОМР, представляє окремого співробітника, який є слухачем курсу

Примітка Щоб продовжити створення ієрархії вкладення, обєкт ОМР поміщається знутрь відповідного обєкта ENROLLMENT Однак тут можна помітити асиметрію: зарахування співробітників на навчання в різні потоки описується як відношення типу багато до багатьох, але учасники цієї звязку, співробітники і потоки, трактуються зовсім по-різному

Нарешті, розглянемо обєкти, що представляють викладачів Тут ми трохи відійдемо від оригінальної реляційної версії бази даних і будемо розглядати викладачів (TEACHER) як підклас класу співробітників (ОМР)

1 ОМР SUBCLASS: TEACHER

2&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INSTVARNAMES  : #[ COURSES ]

3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp CONSTRAINTS    : #[ #[ #COURSES, CSET ] ]

Пояснення У рядку 1 визначено обєктний клас TEACHER, який є підкласом раніше визначеного класу ОМР (іншими словами, клас TEACHER зєднаний звязком ISA з класом ОМР) Таким чином, кожен окремий обєкт TEACHER має закриті змінні екземпляра ОМР #, ENAME І POSITION (які унаследовани10 від класу ОМР), а також змінну COURSES, яка містить ідентифікатор обєкта класу CSET Обєкт CSET позначає безліч всіх курсів, які може вести даний викладач Кожен обєкт TEACHER також успадковує всі методи класу ОМР

Як вже зазначалося, в наведених вище визначеннях класів передбачалося існування декількох класів колекцій ESET, CSET, OSET, NSET і TSET Нижче даються визначення всіх цих класів, починаючи з класу ESET

1&nbsp&nbsp&nbsp SET SUBCLASS     : ESET

2 CONSTRAINTS: ОМР

Пояснення У рядку 1 дається визначення обєктного класу ESET, який є підкласом вбудованого класу SET У рядку 2 на обєкти класу ESET накладається обмеження: вони повинні бути множинами ідентифікаторів обєктів класу ОМР У загальному випадку може існувати довільна кількість обєктів класу ESET, але в даній ситуації буде створений тільки один обєкт (подробиці наводяться в наступному підрозділі), який буде представляти собою безліч ідентифікаторів всіх обєктів класу ОМР, які в даний час існують в базі даних Висловлюючись неформально, цей єдиний обєкт ESET можна розглядати як обєктний аналог базової змінної відносини ОМР в реляційної версії бази даних

Визначення класів CSET, OSET, NSET і TSET аналогічні (вони наводяться нижче) Однак для кожного з них доведеться створити не один, а кілька обєктів відповідної колекції класів Наприклад, у нашому випадку буде існувати стільки колекцій обєктів OSET, скільки існує окремих обєктів COURSE

SET SUBCLASS   :     CSET CONSTRAINTS :                                        COURSE

SET SUBCLASS   :     OSET CONSTRAINTS :                                        OFFERING

SET SUBCLASS    :     NSET CONSTRAINTS :                                        ENROLLMENT

SET SUBCLASS    :     TSET CONSTRAINTS :TEACHER

10 Зауважимо, що тут успадковується закрите уявлення (тобто фізична реалізація)

Заповнення бази даних

Тепер опишемо, як можна помістити у розглянуту базу даних необхідну інформацію При цьому зупинимося на пяти основних класах обєктів (EMP, COURSE І тд) Почнемо з співробітників Нагадаємо про наш намір зібрати разом ідентифікатори всіх обєктів ОМР в єдиному обєкті ESET Таким чином, перш за все необхідно створити обєкт ESET, як показано нижче

OID_OF_SET_OF_ALL_EMPS    :=   ESET  NEW   

Вираз у правій частині цього оператора присвоювання повертає обєктний ідентифікатор (OID) нового порожнього примірника обєкта класу ESET (тобто порожній безліч ідентифікаторів обєктів класу ОМР), а потім ідентифікатор цього нового екземпляра присвоюється програмної змінної OID_OF_SET_OF_ALL_EMPS Говорячи дуже неформально, ця змінна позначає безліч всіх співробітників.

Тепер кожен раз при створенні нового обєкта класу ОМР ідентифікатор цього обєкта слід поміщати в обєкт ESET, ідентифікатор якого зберігається у змінній OID_OF_SET_OF_ALL_EMPS Тому для створення обєкту класу ОМР і вставки його ідентифікатора в обєкт класу ESET необхідно визначити спеціальний метод (Ще один варіант полягає в тому, що для виконання такого ж завдання може бути написана прикладна програма) Код зазначеного методу наведено нижче

1 METHOD: ESET анонімний

2 ADD_EMP #: EMP # _PARM формальні параметри

3&nbsp&nbsp&nbsp ADD_ENAME : ENAME_PARM

4&nbsp&nbsp&nbsp ADD_POS  : POS_PARM

5 | EMP_OID | локальна змінна

6 EMP_OID: = EMP NEW новий співробітник

7 EMP_OID SET_EMP #: EMP # _PARM ініціалізація

8&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp SET_ENAME : ENAME_PARM

9&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp SET_POS    : POS_PARM

10 SELF ADD: EMP_OID вставка

11 %

Пояснення

і У рядку 1 починається запис коду даного методу (який завершується символом % в рядку 11), який застосовується до обєктів класу ESET (Насправді, в системі під час виконання програми буде існувати один і тільки один обєкт класу ESET)

■ У рядках 2-4 визначені три параметра із зовнішніми іменами ADD_EMP #, ADD_ENAME і ADD_POS Ці імена будуть використані в повідомленнях, що викликають даний метод Відповідні внутрішні імена EMP # _PARM, ENAME_PARM І POS_PARM будуть застосовуватися тільки всередині коду реалізації даного методу

■ У рядку 5 визначена локальна змінна EMP_OID, а в рядку 6 їй присвоєно ідентифікатор нового неініціалізованих примірника обєкта класу ОМР

■ У рядках 7-9 передається повідомлення новому обєкту класу ОМР із зазначенням трьох викликаються методів (SET_EMP #, SET_ENAME і SET_POS) і передачею одного фактичного параметра кожному з них (EMP # _PARM для SET_EMP #, ЕNАМЕ_РАRМ для SET_ENAME І РОS_РАRМ для SET_POS)

Примітка Тут передбачається, що методи SET_ENAME і SET_POS (як і метод SET_EMP #, показаний вище) також повинні бути визначені заздалегідь

■ У рядку 10 передається повідомлення обєкту SELF Це імя обєкта є спеці альних позначенням, що представляє під час виконання той поточний обєкт, в якому визначений вказаний метод (тобто повідомлення передається самому поточним цільовим обєкту) Повідомлення викликає застосування вбудованого методу ADD до цього обєкта (метод ADD передбачений у всіх класах, що визначають кіл лекції) В результаті ідентифікатор обєкта, який міститься в локальної змінної EMP_OID, буде вставлений в обєкт, ідентифікований значенням пе пасової SELF (в даному випадку це буде обєкт ESET, що містить идентифи Каторі всіх існуючих на поточний момент обєктів класу ОМР) Примітка Мінлива SELF необхідна тому, що параметр, відповідаю щий обєкту-одержувачу, не має власного імені (смстроку 1)

■ Зверніть увагу на те, що, як зазначено в коментарі до рядка 1, визна ленний тут метод залишається анонімним У загальному випадку в мові OPAL методи не мають імен замість цього для них використовується сигнатура (У мові OPAL сиг натура визначається як комбінація імені класу, в якому він застосовується, і зовнішніх імен їх формальних параметрів) Цілком очевидно, що застосування та кого угоди може привести до створення незграбних і величезних конструк цій Можна відзначити і ще один недолік: якщо два методи застосовуються до од ному і того класу і мають однакові формальні параметри, то в цих двох методах вказаними параметрами повинні бути присвоєні довільні, але різні зовнішні імена

Тепер створено метод для вставки в базу даних нових обєктів ОМР, але до цих пір така операція ще не була виконана Тому нижче наведено приклад вставки в базу даних відомостей про співробітників

OID_OF_SET_OF_ALL_EMPS ADD_EMP# : E009 ADD_ENAME : Helms ADD_POS   : Janitor

.

При використанні наведеного виразу буде створений обєкт класу ОМР для співробітника з номером Е009, а ідентифікатор цього обєкта буде додано до безлічі вже існуючих ідентифікаторів обєктів класу ОМР

Зверніть увагу на те, що вбудований метод NEW ніколи не повинен використовуватися для класу ОМР, крім тих випадків, коли він є частиною щойно певного методу Інакше можуть бути створені деякі обєкти класу ОМР з обірваними звязками, які не будуть представлені в обєкті ESET, що містить ідентифікатори всіх існуючих обєктів ОМР

Примітка Слід принести вибачення за надто часте повторення таких громіздких виразів, як щойно певний метод і обєкт ESET, містить ідентифікатори всіх існуючих обєктів ОМР , але інакше нелегко точно описати предмети, що не мають назв

Обєкти для співробітників являють собою найбільш простий випадок, оскільки вони відповідають звичайним сутностей (Згідно з термінологією моделі типу сутність / звязок) і не містять ніяких інших впроваджених у них обєктів (не рахуючи незмінних)

Далі слід розглянути більш складний випадок обєктів для курсів, які (незважаючи на те, що вони все ще залишаються звичайними сутностями) концептуально містять інші включені в них змінювані обєкти В цілому, щоб створити обєкти для курсів, необхідно виконати описані нижче дії

1 Застосувати метод NEW до класу CSET в цілях створення початково порожнього безлічі всіх курсів(Насправді – безлічі ідентифікаторів обєктів класу COURSE)

2 Визначити метод для створення нового обєкта класу COURSE і вставити його ідентифікатор в безліч всіх курсів Цей метод приймає як факти чеських параметрів вказані значення COURSE # і TITLE І створює новий обєкт COURSE з цими заданими значеннями Крім того, за допомогою цього методу до класу OSET застосовується метод NEW для створення спочатку порожнього множе ства ідентифікаторів потоків OFFERING, а потім ідентифікатор цього порожнього безлічі ідентифікаторів потоків поміщається в змінну OFERINGS ре дині нового обєкта класу COURSE

3 Викликати щойно певний метод для кожного окремого курсу

Тепер створимо обєкти потоків Для цього необхідно виконати такі дії

1 Визначити метод для створення нового обєкта класу OFFERING Цей метод має приймати в якості фактичних параметрів значення змінних OFF #, ODATE і LOCATION і приводити до створення нового обєкту класу OFFERING із зазначеними параметрами Крім того, буде потрібно виконати неко торие додаткові дії

■ Для створення початково порожнього безлічі ідентифікаторів слухачів ENROLLMENT слід застосувати метод NEW до класу NSET, а потім помістити ідентифікатор цього порожнього безлічі слухачів у змінну ENROLLMENTS всередині нового обєкту класу OFFERING

■ Для створення початково порожнього безлічі ідентифікаторів викладачів TEACHER слід застосувати метод NEW до класу NSET, а потім помістити іден тіфікатор цього порожнього безлічі викладачів в змінну TEACHERS всередині нового обєкту класу OFFERING

2 Даний метод приймає як фактичного параметра значення COURSE *, після чого значення COURSE # використовується в ньому для виконання описаних ні же дій

■ Виконати поіск11 відповідного обєкта COURSE для нового обєкта OFFERING (рекомендації з виконання цієї дії наведені в сле дме підрозділі)

” Безумовно, даний метод повинен запобігати спроби створити новий обєкт потоку, якщо не може бути знайдений відповідний курс Тут і в подальшому описі такі виняткові ситуації детально не розглядаються

■ Знайти таким чином безліч всіх потоків для даного обєкта класу

COURSE

■ Додати ідентифікатор нового обєкта класу OFFERING До соответствующе му безлічі всіх потоків

Відзначимо, що (як уже згадувалося в цьому розділі) тут ідентифікатори не дозволяють уникнути необхідності застосовувати таких користувача ключі, як COURSE * Дійсно, такі ключі необхідні не тільки для ідентифікації обєктів у зовнішньому світі, а й для використання в якості основи при виконанні певних операцій пошуку всередині самої бази даних

Нарешті, слід викликати тільки що певний метод для кожного окремого потоку

Зверніть увагу на те, що (відповідно до використовуваним поданням ієрархії вкладення) тут не було створено безліч всіх потоків Одним з наслідків цього упущення стає те, що в будь-якому запиті, областю дії якого стає це безліч (наприклад: Визначити всі потоки, організовані в Нью-Йорку), доведеться використовувати певний обсяг процедурного коду, що дозволяє виправити цю ситуацію (див наступний підрозділ)

Тепер розглянемо процедуру створення обєктів слухачів Ці обєкти (ENROLLMENT)

відрізняються від обєктів потоків тим, що містять змінну примірника ОМР, значення якої є ідентифікатором відповідного обєкта ОМР Тому послідовність дій повинна бути такою, як описано нижче

1 Визначити метод для створення нового обєкта класу ENROLLMENT Цей метод в якості фактичних параметрів приймає вказані значення COURSE *, OFF *, ОМР # і GRADE і створює новий обєкт ENROLLMENT із заданим значенням GRADE Крім того, потрібно виконати деякі додаткові дії

■ Використовувати значення COURSE # і OFF # для пошуку відповідного обєкта

OFFERING ДЛЯ НОВОГО обєкта ENROLLMENT

■ Знайти безліч всіх слухачів для даного обєкта класу OFFERING

■ Додати ідентифікатор нового обєкта класу ENROLLMENT до відповідаю щему безлічі всіх слухачів

■ Крім того, буде потрібно виконати описані нижче дії

■ Використовувати значення ОМР * # для пошуку відповідного обєкта ОМР

■ Помістити ідентифікатор обєкта ОМР в змінну ОМР всередині нового обєк єкта класу ENROLLMENT

2 Викликати щойно певний метод для кожного окремого слухача по черзі

Нарешті, перейдемо до створення обєктів викладачів Різниця між способами створення обєктів для викладачів і потоків полягає в тому, що клас TEACHER є підкласом класу ОМР Нижче наведена послідовність дій, які необхідно виконати в даному випадку

1 Визначити метод створення нового обєкту класу TEACHER Цей метод принима ет в якості фактичних параметрів задані значення COURSE #, OFF # і ОМР # Будуть потрібні також деякі додаткові дії

■ Використовувати значення ОМР # для пошуку відповідного обєкта класу ОМР

■ Замінити найбільш певний клас цього обєкта ОМР класом TEACHER, оскільки даний співробітник тепер є також викладачем (але спосіб зазначеної зміни класи значною мірі залежить від конкретної розглянутої системи, тому додаткові відомості на цю тему тут не наведено) Крім того, повинні бути виконані такі дії

■ Використовувати значення COURSE # і OFF # для пошуку відповідного обєкта

OFFERING ДЛЯ НОВОГО обєкта TEACHER

■ Знайти безліч всіх викладачів для цього обєкта OFFERING

■ Додати ідентифікатор нового обєкта класу TEACHER до відповідного

безлічі всіх викладачів

2 Визначити безліч всіх курсів, які може вести даний викладач, а також задати відповідним чином значення змінної COURSES в новому обєкті класу TEACHER Але тут ці подробиці не наведено

3 Викликати щойно певний метод для кожного обєкта, що описує окремого викладача

Операції вибірки

Перш ніж приступити до докладного опису операцій вибірки, слід зазначити (хоча це і цілком очевидно), що мова OPAL, як і інші обєктні мови в цілому, функціонує за принципом послідовної обробки окремих записів (або, щонайменше, окремих обєктів), а не їх множин Тому для вирішення більшості проблем програміст змушений застосовувати процедурний код Розглянемо лише один приклад – запит: Визначити всі потоки для курсу з номером С001, які організовані у місті New York. Для простоти припустимо, що є змінна OOSOAC, значення якої є ідентифікатором безлічі всіх курсівНижче приведений код для такого запиту

1&nbsp | COURSE_C001 , C001_OFFS , C001_NY_OFFS |

2&nbsp&nbsp&nbsp COURSE_C001

3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp := OOSOAC DETECT : [ :CX | ( CX GET_COURSE# ) = C001 ]

4&nbsp&nbsp&nbsp C001_OFFS

5&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp := COURSE_C001 GET_OFFERINGS

6&nbsp&nbsp&nbsp C001_NY_OFFS

7&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp := C001_OFFS SELECT :

8&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [   :OX   |    (   OX GET_LOCATION  )   =   New York   ]     

9&nbsp ^  C001_NY_OFFS   

Пояснення

1 У рядку 1 оголошені три локальні змінні: COURSE_C001 (яка буде використана для зберігання ідентифікатора обєкта курсу з номером С001), C001_OFFS (яка буде використана для зберігання ідентифікатора обєкта

безлічі всіх потоків для курсу з номером С001) і C001_NY_OFFS (яка буде використана для зберігання ідентифікатора безлічі ідентифікаторів для необхідних потоків, тобто потоків, організованих в Нью-Йорку)

2 У рядках 2 і 3 передається повідомлення обєкту (колекції), позначеному змінної OOSOAC Це повідомлення викликає застосування вбудованого методу DETECT до цієї колекції Формальним параметром методу DETECT є ви ражение в наступній формі

[   : Х|    р {х)]

Тут р (х) – Логічне вираження, що включає змінну х, а х, по суті, являє собою змінну області значень, яка приймає свої значення серед елементів колекції, до яких застосовується метод DETECT (у розглянутому прикладі цей метод застосовується до безлічі обєктів COURSE) В результаті виконання методу DETECT повертається ідентифікатор першого знайденого обєкта х цієї множини, для якого вираз р (Х) приймає значення TRUE (у розглянутому прикладі це – екземпляр обєкта класу COURSE для курсу з номером С001) 12 Потім ідентифікатор цього обєкта класу COURSE присвоюється змінної COURSE_C001

Примітка Фактично також можливо передати методу DETECT замаскований формальний параметр, щоб можна було врахувати той випадку, в якому вираз р (Х) ніколи не приймає значення TRUE Але докладні відомості про це тут не наведено

3 У рядках 4 і 5 змінної C001_OFFS присвоюється ідентифікатор безлічі всіх потоків для курсу з номером С001

4 Рядки 6-8 подібні рядках 2 і 3, оскільки вбудований метод SELECT подібний до методу DETECT, за винятком того, що він повертає ідентифікатор множест ва ідентифікаторів всіх обєктів х (А не просто перший виявлений з таких обєктів), для яких вираз р (Х) приймає значення TRUE У рассматри ваемое прикладі в результаті виконання цього методу змінної C001_NY_OFFS присвоюється ідентифікатор безлічі ідентифікаторів для тих потоків курсу з номером С001, які організовані у місті New York

5 У рядку 9 цей ідентифікатор повертається в точку виклику

Слід звернути увагу на деякі перераховані нижче особливості

■ Логічний вираз р (Х) в методах SELECT і DETECT може містити (в са мом складному випадку) лише деяку кількість простих скалярних операторів порівняння, які зєднуються за допомогою операторів AND, тобто складність ус ловия пошуку обмежена

■ Круглі дужки, навколишні вираз фактичного параметра методів SELECT і DETECT, можна замінити фігурними дужками При використанні фігурних дужок в мові OPAL буде зроблена спроба використовувати індекс

12Вэтомпримереподразумевается,чтотакиеметоды,какGET_COURCE#(аналогметодаGET_EMP#,описанного вище в даному розділі), вже визначені

(Якщо відповідний індекс існує) в ході застосування даного методу, а при використанні круглих дужок індекс використовуватися не буде

■ Умова, згідно з яким метод DETECT повертає ідентифікатор першого знайденого обєкта, для якого значенням вирази р (Х) є TRUE, оз начає, що знайдений обєкт буде першим знайденим при використанні про довільній послідовності пошуку, яка буде обрана в мові OPAL для перегляду безлічі (оскільки безлічі не має притаманних їм властивостей упо рядоченія) У розглянутому прикладі результат не залежить від організації по позову, оскільки перший обєкт, для якого логічне вираження приймає значення TRUE, фактично є єдиним таким обєктом

■ Уважний читач неодмінно помітить широко застосовуються вислови на зразок метод DETECT, хоча, як зазначалося вище, методи в мові OPAL не мають імен Дійсно, DETECT і SELECT не є іменами методів (а тому вислови на зразок метод DETECT, строго кажучи, є непра Вільно) Вони, швидше за все, служать іменами зовнішніх параметрів для деяких вбудованих (і анонімних) методів Але для стислості і простоти далі як імена методів раніше будуть використовуватися назви DETECT і SELECT (а також інші подібні їм назви для інших методів)

■ Крім того, уважний читач помітить, що досить часто використовується ви ражение метод NEW. В даному випадку його не слід вважати неправильним – методи, які не беруть інших формальних параметрів, крім обовязкових це лівих формальних параметрів, є винятком із загального правила в язи ке OPAL, згідно з яким методи повинні бути анонімними

Операції поновлення

Обєктний аналог операції вставки INSERT вже обговорювалося в попередньому підрозділі, а обєктні аналоги операцій оновлення UPDATE і видалення DELETE розглядаються нижче

■&nbsp&nbsp&nbsp&nbsp&nbsp Оновлення Операції поновлення виконуються так само, як операції вибірки,

але замість методів GET_ використовуються методи SET_

■&nbsp&nbsp&nbsp&nbsp Видалення Для видалення обєктів використовується вбудований метод REMOVE Точніше, він використовується для видалення ідентифікатора зазначеного обєкта із зазначеної колекції Якщо на даний обєкт більше не є ніяких посилань, тобто до нього зовсім не може бути здійснений доступ, то в мові OPAL він автоматично уда ляется системним процесом збору сміття Нижче наводиться приклад реалізації операції видалення співробітника з номером Е001 з безлічі всіх співробітників .

Е001: = OID_OF_SET_OF_ALL_EMPS

DETECT : [ : EX | (EX GET_EMP# ) = E001 ] OID_OF_SET_OF_ALL_EMPS REMOVE : E001

Але як у такій ситуації реалізувати правило каскадного видалення ON DELETE CASCADE Наприклад, як при видаленні деякого співробітника одночасно видалити і відомості про всіх потоках, в яких він проходить навчання Для цього, природно, доведеться створити відповідну процедуру

Можна було б прийти до висновку, що механізм реалізації видалення за допомогою процесу збору сміття є всього лише деякою різновидом реалізації правила обмеження видалення ON DELETE RESTRICT, оскільки обєкт не видаляється до тих пір, поки на нього існує хоча б одне посилання Але в даному випадку це не зовсім так Наприклад, обєкти потоків (OFFERING) не містять ідентифікаторів відповідного обєкта курсу (COURSE), тому потоки не накладають обмежень на видалення обєктів курсів (В ієрархіях вкладення неявно мається на увазі деяка різновид правила каскадного видалення ON DELETE CASCADE, крім випадків, коли користувач виконує наступне: або включає ідентифікатор батьківського обєкта в дочірній обєкт або включає ідентифікатор дочірнього обєкта в якийсь інший обєкт, що зберігається в базі даних А в таких ситуаціях інтерпретація на основі ієрархії вкладення більше не має ніякого сенсу У наступному розділі це питання буде розглянуто при обговоренні зворотних змінних)

На закінчення відзначимо, що операція видалення REMOVE може бути використана для емуляції реляційної операції DROP, наприклад, для видалення всього класу ENROLLMENT Подробиці залишаємо читачеві як вправи

Джерело: Дейт К Дж, Введення в системи баз даних, 8-е видання: Пер з англ – М: Видавничий дім «Вільямс», 2005 – 1328 с: Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*