8.1 Разлагането е всичко
За по-голяма яснота, снимка от добра статия "Разединяване на обектно-ориентирани системи", илюстрираща основните точки, които ще бъдат обсъдени.
Все още ли мислите, че проектирането на архитектура на приложение е лесно?
8.2 Интерфейси, скриване на изпълнението
Основните принципи за намаляване на свързването на системата са принципите на ООП и принципа на капсулиране + абстракция + полиморфизъм зад тях.
Защото:
- Модулите трябва да бъдат "черни кутии" един за друг (капсулиране) . Това означава, че един модул не трябва да се „изкачва“ в друг модул и да знае нещо за вътрешната му структура. Обектите в една подсистема не трябва да имат директен достъп до обекти в друга подсистема.
- Модулите/подсистемите трябва да взаимодействат помежду си само чрез интерфейси (т.е. абстракции , които не зависят от детайлите на изпълнението). Съответно, всеки модул трябва да има добре дефиниран интерфейс or интерфейси за взаимодействие с други модули.
Принципът на "черната кутия" (капсулиране) ни позволява да разгледаме структурата на всяка подсистема независимо от другите подсистеми. Модулът, който представлява "черна кутия", може да се променя относително свободно. Проблеми могат да възникнат само на кръстовището на различни модули (or модул и среда).
И това взаимодействие трябва да бъде описано в най-обща (абстрактна) форма, тоест под формата на интерфейс. В този случай codeът ще работи по същия начин с всяка реализация, която отговаря на договора за интерфейс. Именно тази способност за работа с различни реализации (модули or обекти) чрез унифициран интерфейс се нарича полиморфизъм.
Ето защо Servlet е интерфейс : уеб контейнерът не знае нищо за сервлетите, за него това са някои обекти, които имплементират интерфейса на Servlet и това е. Сервлетите също знаят малко за структурата на контейнера. Интерфейсът на Servlet е този договор, този стандарт, това минимално взаимодействие, което е необходимо, за да могат Java уеб applicationsта да превземат света.
Полиморфизмът изобщо не е преодоляване на методите, Howто понякога погрешно се смята, а на първо място, взаимозаменяемостта на модули / обекти с един и същ интерфейс or „един интерфейс, много реализации“. За да се реализира полиморфизъм, механизмът за наследяване изобщо не е необходим. Това е важно да се разбере, защото наследяването като цяло трябва да се избягва, когато е възможно .
Благодарение на интерфейсите и полиморфизма се постига именно възможността за модифициране и разширяване на codeа, без да се променя вече написаното (Принцип Отворено-Затворено).
Докато взаимодействието на модулите е описано изключително под формата на интерфейси и не е обвързано с конкретни имплементации, вие имате възможност абсолютно „безболезнено“ за системата да замените един модул с всеки друг, който имплементира същия интерфейс, Howто и добавете нов и по този начин разширете функционалността.
Това е като в LEGO конструктора - интерфейсът стандартизира взаимодействието и служи като своеобразен конектор, в който може да се свърже всеки модул с подходящ конектор.
Гъвкавостта на дизайнера се осигурява от факта, че можем просто да заменим един модул or част с друг със същите конектори (със същия интерфейс), Howто и да добавим колкото желаем нови части (в същото време съществуващите частите не са променяни or променяни по ниHowъв начин).
Интерфейсите ви позволяват да изградите по-проста система, като разглеждате всяка подсистема като цяло и пренебрегвате нейната вътрешна структура. Те позволяват на модулите да си взаимодействат и в същото време не знаят нищо за вътрешната структура един на друг, като по този начин напълно прилагат принципа на минималното знание, който е в основата на хлабавото свързване.
Колкото по-общи/абстрактни са дефинирани интерфейсите и колкото по-малко ограничения налагат върху взаимодействието, толкова по-гъвкава е системата. От тук всъщност следва още един от принципите на SOLID – Interface Segregation Principle , който се противопоставя на “дебелите интерфейси”.
Той казва, че големите, обемисти интерфейси трябва да бъдат разделени на по-малки, по-специфични, така че клиентите на малки интерфейси (зависими модули) да знаят само за методите, с които трябва да работят.
Този принцип е формулиран по следния начин: „Клиентите не трябва да зависят от методи (да са наясно с методи), които не използват“ or „Много специализирани интерфейси са по-добри от един универсален“.
Оказва се, че слабата свързаност се осигурява само когато взаимодействието и зависимостите на модулите се описват само с помощта на интерфейси, тоест абстракции, без да се използват знания за тяхната вътрешна структура и структура.И всъщност по този начин се осъществява капсулиране. Освен това имаме способността да разширяваме/променяме поведението на системата чрез добавяне и използване на различни реализации, тоест поради полиморфизъм. Да, отново стигнахме до OOP - Encapsulation, Abstraction, Polymorphism.
8.3 Фасада: модулен интерфейс
Тук един опитен програмист ще попита: ако дизайнът не е на ниво обекти, които сами имплементират съответните интерфейси, а на ниво модули, тогава Howва е имплементацията на интерфейса на модула?
Отговор: говорейки на езика на шаблоните за проектиране, тогава специален обект може да бъде отговорен за внедряването на интерфейса на модула - Фасада . Ако извиквате методи на обект, който съдържа суфикса Gateway (например MobileApiGateway), най-вероятно това е фасада.
Фасадата е интерфейсен обект , който натрупва набор от операции на високо ниво за работа с определена подсистема, скривайки вътрешната си структура и истинската сложност зад нея . Осигурява защита срещу промени в изпълнението на подсистемата. Служи като единична входна точка - "вие ритате фасадата и той знае кой трябва да бъде ритан в тази подсистема, за да получи това, което му трябва."
Току-що се запознахте с един от най-важните шаблони за проектиране, който ви позволява да използвате концепцията за интерфейси, когато проектирате модули и по този начин да ги разделите - "Фасада".
В допълнение, "Фасада" дава възможност да се работи с модули по същия начин, Howто с обикновени обекти и да се прилагат всички полезни принципи и техники, които се използват при проектирането на класове при проектирането на модули.
Забележка : Въпреки че повечето програмисти разбират meaningто на интерфейсите при проектирането на класове (обекти), изглежда, че много откриват идеята за използване на интерфейси и на ниво модул.
GO TO FULL VERSION