Injection of functional dependencies using inversion of control container
Prombles in programming 2014; 4: 33-39
Gespeichert in:
| Datum: | 2019 |
|---|---|
| Hauptverfasser: | , |
| Format: | Artikel |
| Sprache: | Ukrainian |
| Veröffentlicht: |
PROBLEMS IN PROGRAMMING
2019
|
| Schlagworte: | |
| Online Zugang: | https://pp.isofts.kiev.ua/index.php/ojs1/article/view/681 |
| Tags: |
Tag hinzufügen
Keine Tags, Fügen Sie den ersten Tag hinzu!
|
| Назва журналу: | Problems in programming |
| Завантажити файл: | |
Institution
Problems in programming| id |
pp_isofts_kiev_ua-article-681 |
|---|---|
| record_format |
ojs |
| resource_txt_mv |
ppisoftskievua/cf/c47de0f98afe23759f661a08304a71cf.pdf |
| spelling |
pp_isofts_kiev_ua-article-6812025-02-12T23:28:28Z Injection of functional dependencies using inversion of control container Ін’єкція функціональних залежностей у контейнері інверсії керування Glybovets, M.M. Fedorchenko, V.M. UDC 004.4'242 УДК 004.4'242 Prombles in programming 2014; 4: 33-39 У статті розглянуто використання функціональних інтерфейсів для зменшення зв’язності в компонентних ОО-системах та підвищення рівня повторного використання компонентів. Запропоновано і реалізовано механізм ін’єкції функціональних залежностей між компонентами в контейнерах інверсії керування з підтримкою автоматичного узгодження сигнатур.Prombles in programming 2014; 4: 33-39 PROBLEMS IN PROGRAMMING ПРОБЛЕМЫ ПРОГРАММИРОВАНИЯ ПРОБЛЕМИ ПРОГРАМУВАННЯ 2019-03-27 Article Article application/pdf https://pp.isofts.kiev.ua/index.php/ojs1/article/view/681 PROBLEMS IN PROGRAMMING; No 4 (2014); 33-39 ПРОБЛЕМЫ ПРОГРАММИРОВАНИЯ; No 4 (2014); 33-39 ПРОБЛЕМИ ПРОГРАМУВАННЯ; No 4 (2014); 33-39 1727-4907 uk https://pp.isofts.kiev.ua/index.php/ojs1/article/view/681/733 Copyright (c) 2025 PROBLEMS IN PROGRAMMING |
| institution |
Problems in programming |
| baseUrl_str |
https://pp.isofts.kiev.ua/index.php/ojs1/oai |
| datestamp_date |
2025-02-12T23:28:28Z |
| collection |
OJS |
| language |
Ukrainian |
| topic |
UDC 004.4'242 |
| spellingShingle |
UDC 004.4'242 Glybovets, M.M. Fedorchenko, V.M. Injection of functional dependencies using inversion of control container |
| topic_facet |
UDC 004.4'242 УДК 004.4'242 |
| format |
Article |
| author |
Glybovets, M.M. Fedorchenko, V.M. |
| author_facet |
Glybovets, M.M. Fedorchenko, V.M. |
| author_sort |
Glybovets, M.M. |
| title |
Injection of functional dependencies using inversion of control container |
| title_short |
Injection of functional dependencies using inversion of control container |
| title_full |
Injection of functional dependencies using inversion of control container |
| title_fullStr |
Injection of functional dependencies using inversion of control container |
| title_full_unstemmed |
Injection of functional dependencies using inversion of control container |
| title_sort |
injection of functional dependencies using inversion of control container |
| title_alt |
Ін’єкція функціональних залежностей у контейнері інверсії керування |
| description |
Prombles in programming 2014; 4: 33-39 |
| publisher |
PROBLEMS IN PROGRAMMING |
| publishDate |
2019 |
| url |
https://pp.isofts.kiev.ua/index.php/ojs1/article/view/681 |
| work_keys_str_mv |
AT glybovetsmm injectionoffunctionaldependenciesusinginversionofcontrolcontainer AT fedorchenkovm injectionoffunctionaldependenciesusinginversionofcontrolcontainer AT glybovetsmm ínêkcíâfunkcíonalʹnihzaležnostejukontejneríínversííkeruvannâ AT fedorchenkovm ínêkcíâfunkcíonalʹnihzaležnostejukontejneríínversííkeruvannâ |
| first_indexed |
2025-07-17T09:47:46Z |
| last_indexed |
2025-07-17T09:47:46Z |
| _version_ |
1850409859612147712 |
| fulltext |
Методи та засоби програмної інженерії
© М.М. Глибовець, В.М. Федорченко, 2014
ISSN 1727-4907. Проблеми програмування. 2014. № 4 33
УДК 004.4'242
М.М. Глибовець, В.М. Федорченко
ІН’ЄКЦІЯ ФУНКЦІОНАЛЬНИХ ЗАЛЕЖНОСТЕЙ У
КОНТЕЙНЕРІ ІНВЕРСІЇ КЕРУВАННЯ
У статті розглянуто використання функціональних інтерфейсів для зменшення зв’язності в компонент-
них ОО-системах та підвищення рівня повторного використання компонентів. Запропоновано і реалізо-
вано механізм ін’єкції функціональних залежностей між компонентами в контейнерах інверсії керуван-
ня з підтримкою автоматичного узгодження сигнатур.
Вступ
Залежність між компонентами є ва-
жливою характеристикою компонентної
системи, що впливає на важливі параметри
програмного коду: гнучкість, ефективність
супроводу та можливість повторного ви-
користання. Компонент – це блок, що має
здатність до композиції з визначеними ін-
терфейсами взаємодії та явно описаним
контекстом залежностей [1]. В цій роботі
під компонентом будемо розуміти клас
(або множину класів) з чітко визначеними
інтерфейсами взаємодії та явною деклара-
цією залежностей від інших компонентів.
Залежність між компонентами ви-
значається типом залежного компонента та
типом зв’язності. Останній визначає міру
взаємодії між компонентами. Традиційно
виділяють такі типи зв’язності: загальна
зв’язність шляхом прямого доступу до спі-
льних даних (змінних), зв’язність через
наслідування та зв’язність через параметри
[2]. Для об’єктно-орієнтованих компонен-
тів (ООК) характерною є зв’язність ком-
понентів через параметри, тобто коли ком-
поненти взаємодіють шляхом виклику ме-
тодів один одного.
Чим менша зв’язність між компо-
нентами, тим більш гнучкою та стабіль-
ною є компонентна система по відношен-
ню як до змін у самих компонентах, так і
їх конфігурації між собою. Низький рівень
зв’язності зменшує кількість помилок, до-
зволяє легше змінювати компоненти і як
наслідок, підвищує загальну якість про-
грамного забезпечення [3].
Наразі розроблено велику кількість
формальних способів визначення міри
зв’язності в об’єктно-орієнтованих (ОО)
системах, але більшість з них сформульо-
вані виключно на теоретичних засадах, не
враховують емпіричні та експериментальні
моделі програмної інженерії і не мають
практичного обґрунтування [4]. Як наслі-
док, використання запропонованих форма-
льних метрик для обрахування зменшення
декларативного рівня зв’язності (що має
практичний та економічно доцільний
ефект) фактично неможливо. Наприклад,
практично обґрунтований спосіб змен-
шення декларативної зв’язності компонен-
тів системи через використання ін’єкції
залежностей фактично не змінює форма-
льно визначених метрик зв’язності (CBO,
RFC, LCOM) [5]. Дійсно, ці метрики опе-
рують низькорівневими параметрами
(факт виклику методів та типів парамет-
рів), і не враховують архітектурних аспек-
тів (дизайну) організації цих зв’язків.
Поняття слабкої зв’язності є фун-
даментальним при проектуванні програм-
них систем [6] і має суттєвий вплив на су-
часну архітектуру об’єктно-орієнтованого
програмного забезпечення [7, 8]. Одним з
найуживаніших практичних способів зме-
ншення зв’язності між об’єктами є вико-
ристання принципу інверсії залежностей
(dependency inversion principle [9]). За цим
принципом, високорівневі модулі не ма-
ють залежати від низькорівневих і будь-які
модулі мають залежати від абстракцій. Але
абстракції не мають залежати від деталей
реалізації; навпаки, деталі мають визнача-
тися абстракціями.
Принцип інверсії залежностей
знайшов відтворення у багатьох відомих
шаблонах проектування: абстрактна фаб-
рика, адаптер, локатор сервісу, ін’єкція
залежностей та інші. В загальному випа-
Моделі та засоби систем баз даних і знань
34
дку, розрив прямої залежності між кла-
сами A і B можливий шляхом абстрагу-
вання залежності через інтерфейс взає-
модії I , та виділення ще одного компо-
нента C для інкапсуляції зв’язування
конкретних екземплярів класів A та B .
Останнє дозволяє зменшити зв’язності
між конкретними компонентами A та B
через формування непрямої залежності
через інтерфейс I . Компоненти залиша-
ються зв’язаними через залежність від
спільного інтерфейсу [10].
В цій роботі визначаються залеж-
ності між об’єктно-орієнтованими ком-
понентами через функціональні інтер-
фейси з метою зменшення декларативної
зв’язності між ними. Запропоновано ме-
ханізм ін’єкції таких функціональних за-
лежностей в контейнері інверсії керуван-
ня, реалізація якого передбачає автомати-
чне узгодження типів та сигнатур під час
ін’єкції.
Контейнер інверсії керування
Одним із розповсюджених варіантів
реалізації шаблона ін’єкції залежностей є
контейнер інверсії керування (inversion of
control container) [11]. Контейнер – це ком-
понент, який відповідає за створення та
визначення залежностей об’єктно-
орієнтованого компонента через посилан-
ня на інші компоненти контейнера. IoC-
контейнер не потребує, щоб компоненти
мали будь-яку залежність від нього (тому
такі контейнери ще називають легкими).
Контейнер інверсії керування є фа-
брикою, що може створювати об’єкти різ-
них типів відповідно до зовнішньої конфі-
гурації; при цьому така фабрика є повно-
цінним компонентним контейнером, оскі-
льки також визначає і життєвий цикл ком-
понентів: створення, визначення взаємодій
та знищення.
Зауважимо, що саме використання
IoC-контейнера не призводить до змен-
шення залежностей між компонентами.
Разом з тим, легкість зміни конфігурації
контейнера та акцент на абстрактному
визначенні залежностей компонента (че-
рез інтерфейси) дозволяють зменшити за-
гальний рівень зв’язності системи, а та-
кож дозволяють ефективно реорганізову-
вати компоненти з метою подальшої де-
композиції та подрібнення компонентів
(що може призводити до зменшення зале-
жностей та дублювання коду). Формаль-
ний опис конфігурації компонентів (у ви-
гляді XML) дозволяє ефективно викорис-
товувати IoC-контейнер для складального
програмування [12], а також як інфра-
структуру для модель-орієнтованого про-
грамування [13].
Розглянемо приклад, яким чином
реорганізація компонентів в IoC-
контейнері може призвести до зменшення
фактичної залежності між компонентами A
і B, які вже мають зв’язок через інтерфейс
I . Нехай інтерфейс I містить множину
абстрактних методів IM , а компонент A
використовує лише деяку підмножину ме-
тодів II MM 1 . Декларативна залежність
між компонентами A та B може бути
зменшена, оскільки в контексті конкретної
взаємодії між цими компонентами інтер-
фейс I є надлишковим; для цього треба
виділити новий інтерфейс 1I (що містить
всі необхідні для A методи
1
IM ), і змінити
залежність компонента A з I на 1I . У ві-
дповідності до шаблону проектування ада-
птер створимо новий компонент C, який
реалізує інтерфейс 1I та має залежність від
компонента B через інтерфейс I . Таким
чином, міра декларативної залежності між
компонентами A і B зменшилася, оскіль-
ки вони більше не пов’язані спільним інте-
рфейсом I . Роль контейнера інверсії керу-
вання полягає у ізоляції всіх інших компо-
нентів системи від наслідків такої реорга-
нізації: ні компонент A , ні компонент B
не змінили свої публічні контракти; зміна
зв’язку між ними потребує лише локальної
зміни конфігурації контейнера.
Зазначимо, що у вищенаведеному
прикладі декларативний зв’язок між A та
B опосередковано існує через компонент
C, який пов’язаний з обома інтерфейсами
I та 1I . Подальше використання різнома-
нітних шаблонів об’єктно-орієнтованого
дизайну може збільшити кількість ланок
абстракції, але не може повністю ізолюва-
ти компонент A від компоненту B .
Методи та засоби програмної інженерії
35
Функціональні інтерфейси
Функціональний інтерфейс – це ін-
терфейс, який визначає тільки один абст-
рактний метод (Single Abstract Method
interface). Важливою властивістю SAM-
інтерфейсів є концептуальна можливість
їх реалізації через посилання на метод
об’єкту, інший функціональний інтерфейс
з сумісною сигнатурою або лямбда-вираз.
Функціональні інтерфейси дозволяють
гармонійно інтегрувати шаблони функці-
онального програмування в об’єктно-
орієнтованих мовах програмування [14].
Інваріантність функціональних ін-
терфейсів дозволяє у деяких випадках по-
вністю розірвати декларативну залежність
між компонентами, зберігаючи фактичну
здатність цих компонентів до взаємодії.
Це справджується для багатьох відомих
шаблонів проектування: абстрактна фаб-
рика (інтерфейс фабрики створення
об’єкта можна звести до функціонально-
го, тому реалізація фабрики може бути
повністю незалежною від компонентів,
що її використовують), відвідувач (інтер-
фейс відвідувача можна звести до функці-
онального з одним методом visit), ко-
манда (інтерфейс команди є функціональ-
ним з одним методом execute, реаліза-
ції різних команд можуть бути декларати-
вно незалежними від компонентів оброб-
ки команд) тощо. В корпоративних сис-
темах функціональні інтерфейси зустрі-
чаються в компонентах бізнес-правил, до-
ступу до даних, операцій тощо.
Розглянемо підхід до повного роз-
риву декларативної залежності. Компонент
A залежить від компонента B через інтер-
фейс I , що складається з множини абст-
рактних методів 1,..., nI = m m . Завжди
можлива заміна залежність від інтерфейсу
I на множину інтерфейсів 1,..., kI I , яка
повністю або частково складається з фун-
кціональних інтерфейсів. Дійсно, в загаль-
ному випадку:
1,
1
...
n
n k
k
I = m ,m = m
.
Як наслідок, компонент A може
декларувати залежність від локальних фу-
нкціональних інтерфейсів kI , а компонент
B – визначати сервіси за допомогою ін-
ших локальних інтерфейсів або у вигляді
публічних методів; компоненти A та B
наразі не мають спільного інтерфейсу, що
їх пов’язує, оскільки при зв’язуванні ком-
понентів A та B можливе автоматичне
узгодження функціональних інтерфейсів
контейнером інверсії керування.
Практична доцільність такого под-
рібнення інтерфейсу I з метою розриву
декларативної залежності визначається ха-
рактером взаємодії та контексту методів
1,..., nm m . Наш досвід розробки корпора-
тивних систем свідчить, що у багатьох ви-
падках таке подрібнення інтерфейсів приз-
водить до інкапсуляції бізнес-логіки у
окремих компонентах, що значно спрощує
їх підтримку та модифікацію у майбут-
ньому. Виділення таких атомарних компо-
нентів, які можуть взаємодіяти через фун-
кціональні інтерфейси, сприяє їх повтор-
ному використанню та значно підвищує їх
здатність до композиції [15].
Ін’єкція функціональних
залежностей
Сучасні ОО-мови мають засоби під-
тримки функціональних інтерфейсів. На-
приклад, в очікуваній Java 8 компілятор
автоматично має узгоджувати 2 різні
SAM-інтерфейси, якщо сигнатури методів
збігаються за кількістю і порядком пара-
метрів, типи вихідних параметрів коваріа-
нтні, а типи вхідних – контраваріантні. В
MS.NET не підтримується автоматичне
узгодження SAM-інтерфейсів, але є особ-
ливий тип (делегат), який визначається си-
гнатурою метода і використовується для
декларації функціональної залежності.
Розглянемо технологічний аспект
ін’єкції функціональних залежностей для
платформи .NET. Оскільки є дві різні фор-
ми декларації таких залежностей (SAM-
інтерфейс і делегат), постає проблема уз-
годження типів при ін’єкції у контейнері
інверсії керування. Маємо чотири можливі
випадки: делегат → делегат, делегат →
SAM-інтерфейс, SAM-інтерфейс → деле-
гат, SAM-інтерфейс → SAM-інтерфейс.
Оскільки делегат і SAM-інтерфейс визна-
Моделі та засоби систем баз даних і знань
36
чаються сигнатурою метода, фактично по-
трібно реалізувати такі перетворення: ме-
тод → делегат, метод → SAM-інтерфейс.
Середовище .NET дозволяє створю-
вати делегат потрібного типу за методом
об’єкта, що має сумісну сигнатуру:
var toDelegate =
Delegate.CreateDelegate(toType,
fromObject, fromMethod, false);
Для сумісності сигнатур мають за-
довольнятися умови коваріантності для
вихідних і контраваріантності для вихід-
них параметрів [16]. Більш складним є ви-
падок ін’єкції SAM-інтерфейсу, оскільки у
цьому випадку необхідно якимось чином
реалізувати зазначений інтерфейс. В рам-
ках технологічних можливостей платфор-
ми .NET реалізувати автоматичне перетво-
рення метод → SAM-інтерфейс можливо
декількома способами.
Універсальним є варіант, коли про-
граміст заздалегідь підготує компонент-
конвертор та проксі-імплементацію для
функціонального інтерфейсу у відповідно-
сті до компонентної моделі .NET:
[TypeConverter(typeof(PermissionCheck
erConverter))]
public interface IPermissionChecker {
bool Check(int accountId, string
operation, object context);
}
public class PermissionCheckerProxy :
IPermissionChecker {
Delegate F;
public
PermissionCheckerProxy(Delegate f) {
F = f; }
public bool Check(int accountId,
string operation, object context) {
return (bool)F.DynamicInvoke(new
object[]
{accountId,operation,context});
}
}
public class
PermissionCheckerConverter :
TypeConverter {
public override object
ConvertFrom(ITypeDescriptorContext
context,
CultureInfo culture, object value) {
if (value is Delegate)
return new PermissionCheckerProxy(
(Delegate)value );
return
base.ConvertFrom(context,culture,valu
e);
}
}
Для узгодження такого SAM-
інтерфейсу треба скористатись загальною
інфраструктою перетворення типів компо-
нентної моделі .NET:
var toTypeConv =
TypeDescriptor.GetConverter(typeof(IP
ermissionChecker));
if
(toTypeConv.CanConvertFrom(delegateTy
pe)) {
return
toTypeConv.ConvertFrom(delegate);
}
Суттєвим недоліком цього варіанту
є створення спеціального класу-конвер-
тора та проксі класу для кожного функціо-
нального інтерфейсу.
У .NET існує спосіб реалізації будь-
якого інтерфейсу через наслідування особ-
ливого класу System.Runtime.
Remoting.Proxies.RealProxy. Цей
клас призначений для організації віддале-
них викликів .NET Remoting і дозволяє об-
робляти виклики методів інтерфейсу у ви-
гляді повідомлень. Подібний механізм
можна використати для локальних викли-
ків, і таким чином визначити універсаль-
ний проксі для будь-якого SAM-
інтерфейсу:
class InterfaceAdapter :
System.Runtime.Remoting.Proxies.RealP
roxy {
Delegate F;
public override IMessage
Invoke(IMessage m) {
if (m is IMethodCallMessage) {
var methodCall =
(IMethodCallMessage)m;
var response = F.DynamicInvoke(
methodCall.Args );
return new ReturnMessage(response,
null, 0, null, methodCall);
}
throw new
NotImplementedException();
}
}
Недоліком такої реалізації є суттєві
накладні витрати, що спричиняє RealProxy.
Методи та засоби програмної інженерії
37
Результати тестування свідчать, що такий
проксі-об’єкт працює у 7 разів повільніше
за попередній варіант. Тим не менше, для
переважної більшості застосувань (коли
залежність від SAM-інтерфейсу виклика-
ється обмежену кількість разів) викорис-
тання RealProxy є цілком виправданим.
Для збереження можливості впли-
вати на реалізацію проксі класу ми пропо-
нуємо комбінований варіант. Спочатку пе-
ревіряється, чи має інтерфейс власний
компонент-конвертор для створення прок-
сі-об’єкта за делегатом. Якщо конвертор
явно не визначений, використовується уні-
версальний проксі на основі RealProxy.
Узгодження сигнатур
функціональних інтерфейсів
Ін’єкція функціональної залежності
(у вигляді SAM-інтерфейсу чи типу деле-
гата) передбачає використання повністю
сумісної сигнатури. Наприклад, нехай є
деякий інтерфейс:
public interface ITest {
string DoSomething(string s,
bool b);
}
Залежність від ITest може бути
визначена за делегатом з типом
Func<string,bool,string>, але
спроба ін’єкції делегата типу
Func<string,bool,int> призведе до
помилки, оскільки результат int не може
бути приведений до string. У таких ви-
падках розробник вимушений створювати
надлишкові методи-синхронізатори, на-
приклад:
public string DoSomethingStr(string
s, bool b) {
return origDelegate(s,b).ToString();
}
Подібні синхронізатори у тривіаль-
них випадках перетворень типів призво-
дять до великої кількості надлишкового
коду та ускладнюють конфігурацію ком-
понентів з використанням ін’єкції функці-
ональних залежностей. Цього можна уни-
кнути, якщо при узгодженні таких залеж-
ностей перевіряти контраваріантність ти-
пів аргументів та коваріантність типу ре-
зультату, та виконувати додаткове перет-
ворення при потребі. У випадку ін’єкції
SAM-інтерфейса у InterfaceAdapter
для цього треба дещо ускладнити обробку
виклику метода:
public override IMessage
Invoke(IMessage m) {
if (m is IMethodCallMessage) {
var methodCall =
(IMethodCallMessage)m;
var args =
(object[])methodCall.Args.Clone();
// check args contravariance
var mParams =
Method.GetParameters();
for (int i = 0; i < args.Length;
i++) {
if (args[i] != null) {
if (mParams.Length > i &&
!mParams[i].ParameterType.IsAssignabl
eFrom(args[i].GetType())) {
args[i] =
ConvertManager.ChangeType(args[i],
mParams[i].ParameterType);
}
}
}
var response =
Method.Invoke(Target, args);
if (response != null &&
InterfaceMethod.ReturnType !=
typeof(void) &&
!InterfaceMethod.ReturnType.IsAssigna
bleFrom(response.GetType())) {
response =
ConvertManager.ChangeType(response,
InterfaceMethod.ReturnType);
}
return new ReturnMessage(response,
null, 0, null, methodCall);
}
throw new NotImplementedException();
}
При узгодженні сигнатур делегатів
ситуація дещо складніша, оскільки як ар-
гумент Delegate.CreateDelegate
очікує метод з сумісною сигнатурою. Як-
що сигнатура не є сумісною, потрібне ви-
користання особливого проксі-метода су-
місної сигнатури.
Розглянемо технічні особливості
реалізації такого проксі-метода. Аргумен-
ти можуть мати тип object, оскільки він
є контраваріантним до будь-якого типу в
.NET. Підтримку різної кількості аргумен-
Моделі та засоби систем баз даних і знань
38
тів забезпечимо визначенням N -методів,
що мають N0.. аргументів (для практич-
ного застосування 15N виглядає цілком
прийнятним обмеженням). Для забезпе-
чення коваріантного типу результату, ми
скористаємось шаблонними методами:
class DelegateAdapter {
object Target;
MethodInfo Method;
protected object Invoke(params
object[] args) {
var mParams =
Method.GetParameters();
for (int i = 0; i < args.Length;
i++) {
if (args[i]!=null) {
if (mParams.Length > i &&
!mParams[i].ParameterType.IsAssignabl
eFrom(args[i].GetType())) {
args[i] =
ConvertManager.ChangeType(args[i],
mParams[i].ParameterType);
}
}
}
return Method.Invoke(Target, args);
}
public T Invoke<T>() {
return
(T)ConvertManager.ChangeType(Invoke()
, typeof(T));
}
public T Invoke<T>(object arg1) {
return
(T)ConvertManager.ChangeType(Invoke(a
rg1), typeof(T));
}
public T Invoke<T>(object arg1,
object arg2) {
return
(T)ConvertManager.ChangeType(Invoke(a
rg1,arg2), typeof(T));
}
/* ... */
}
Для створення делегату потрібного
типу при ін’єкції залежності маємо знайти
шаблонний метод Invoke з потрібною
кількістю аргументів та сконструювати
метод з необхідним типом результату:
var adapter = new
DelegateAdapter(fromObject,
fromMethod);
foreach (var adapterMethod in
adapter.GetType().GetMethods()) {
if (adapterMethod.Name == "Invoke"
&&
adapterMethod.GetParameters().Length
== toMethodParamCount) {
var resType =
toMethodInfo.ReturnType !=
typeof(void) ?
toMethodInfo.ReturnType :
typeof(object);
var typedInvokeMethod =
adapterMethod.MakeGenericMethod(resTy
pe);
return
Delegate.CreateDelegate(toType,
adapter, typedInvokeMethod, true);
}
}
Повну реалізацію узгодження фун-
кціональних інтерфейсів та делегатів у ви-
гляді окремого компонента можна знайти
за адресою Помилка! Неприпустимий
об'єкт гіперпосилання.. Компонент приз-
начений для інтеграції з контейнером інве-
рсії керування Winter4Net, але його мож-
ливо використовувати і з іншими контей-
нерами, наприклад, Spring.NET.
Висновки
Компонентна розробка передбачає,
що програмне забезпечення збирається з
бібліотек вже написаних компонентів, а
процес збирання може бути в значній мірі
автоматизований у вигляді фабрик про-
грам. Програмні компоненти мають різні
форми і механізми взаємодії, тому про-
блема узгодження їх взаємодії залишається
актуальною. Вирішення цієї задачі полягає
як у площині розвитку теорії об’єктного й
компонентного програмування, так і у від-
повідній технологічній підтримці компо-
нентних середовищ [17].
В рамках такої технологічної підт-
римки у цій роботі ми розглянули викори-
стання функціональних залежностей між
ОО-компонентами, які дозволяють повніс-
тю абстрагувати компоненти один від од-
ного, при збереженні їх здатності до взає-
модії і композиції. Підтримка ін’єкції та-
ких залежностей в контейнерах інверсії
керування потребує особливого механізму
узгодження типів, і ми розглянули техно-
логічні аспекти такого узгодження для
платформи MS.NET. Була запропонована
реалізація механізму, який дозволяє авто-
Методи та засоби програмної інженерії
39
матично узгоджувати делегати та SAM-
інтерфейси. Узгодження можливе навіть
при формально несумісних типах парамет-
рів (при наявності формально визначених
правил перетворення типів), що надзви-
чайно важливо для автоматичного збиран-
ня конфігурацій компонентів у фабриках
програм.
1. Szyperski Clemens. Component Software:
Beyond Object-Oriented Programming. – 2nd
edition. – Boston, MA, USA: Addison-Wesley
Longman Publishing Co., Inc., 2002.
2. Yu Li-Guo, Ramaswamy Srini. Component
Dependency in Object-Oriented Software //
Journal of Computer Science and Technology.
– 2007. – Vol. 22, N 3. – P. 379–386.
3. Arisholm Erik, Briand Lionel C., Foyen
Audun. Dynamic Coupling Measurement for
Object-Oriented Software // IEEE Trans.
Softw. Eng. – 2004. – August. – Vol. 30, N 8.
– P. 491–506.
4. Briand Lionel C., Daly John W., Wust Jurgen K.
A Unified Framework for Coupling
Measurement in Object-Oriented Systems //
IEEE Trans. Softw. Eng. – 1999. – Vol. 25,
N 1. – P. 91–121.
5. Razina Ekaterina, Janzen David. Effects of
dependency injection on maintainability //
Proceedings of the 11th IASTED International
Conference on Software Engineering and
Applications. – SEA '07. – Anaheim, CA,
USA: ACTA Press, 2007. – P. 7–12.
6. Stevens W. P., Myers G. J., Constantine L.L.
Structured design // IBM Syst. J. – 1974. –
June. – Vol. 13, N 2. – P. 115–139.
7. Booch Grady. Object-oriented analysis and
design with applications (2nd ed.). –
Redwood City, CA, USA: Benjamin-
Cummings Publishing Co., Inc., 1994.
8. Coad Peter, Yourdon Edward. Object-oriented
analysis (2nd ed.). – Upper Saddle River, NJ,
USA: Yourdon Press, 1991.
9. Martin Robert C. The Dependency Inversion
Principle // C++ Report. – 1996. – May. –
Vol. 8.
10. Fowler Martin. Reducing Coupling // IEEE
Software. – 2001. – Vol. 18, N 4. –
P. 102–104.
11. Walls Craig, Breidenbach Ryan. Spring in
action. – Greenwich, CT, USA: Manning Pub-
lications Co., 2007.
12. Федорченко В.М. Каркас для підтримки
модель-орієнтованої розробки на основі
спрощеної інфраструктури трансформації
XML-моделей // Наукові записки. Том 86,
Комп’ютерні науки. Національний універ-
ситет "Києво-Могилянська академія". –
2008. – Т. 83. – P. 61–65.
13. Glibovets N.N., Fedorchenko V.M. Simplified
infrastructure for the transformation of XML
models // Cybernetics and Sys. Anal. – 2010.
– January. – Vol. 46, N 1. – P. 93–97.
14. Kuhne Thomas. Higher order objects in pure
object-oriented languages // SIGPLAN Not. –
1994. – July. – Vol. 29, N 7. – P. 15–20.
15. Elizondo Perla Velasco, Ndjatchi Mbe Koua
Christophe. Deriving functional interface
specifications for composite components //
Proceedings of the 10th international con-
ference on Software composition. – SC'11. –
Berlin, Heidelberg: Springer-Verlag, 2011. –
P. 1–17.
16. Svendsen Kasper, Birkedal Lars, Parkinson
Matthew. Verifying generics and delegates //
Proceedings of the 24th European conference
on Object-oriented program-ming. –
ECOOP'10. – Berlin, Heidelberg: Springer-
Verlag, 2010. – P. 175–199.
17. Андон П., Лавріщева К. Розвиток фабрик
програм в інформаційному світі // Вісник
НАН України. – 2010. – № 10. – P. 15–41.
Одержано 09.12.2013
Про авторів:
Глибовець Микола Миколайович,
доктор фізико-математичних наук,
професор,
декан факультету інформатики НаУКМА,
Федорченко Віталій Михайлович,
аспірант.
Місце роботи авторів:
Національний університет
«Києво-Могилянська Академія»,
04655, Київ-70,
вул. Г. Сковороди 2.
Тел. (067) 209 0740.
Факс (044) 416 4515.
E-mail: glib@ukma.kiev.ua
|