A közvetlen függőségek felváltása üzenetküldéssel

Előfordul, hogy egy modulnak csak értesítenie kell másokat, hogy bizonyos események/módosítások történtek benne, és nem mindegy, hogy később mi történik ezzel az információval.

Ebben az esetben a moduloknak egyáltalán nem kell „tudniuk egymásról”, azaz közvetlen hivatkozásokat kell tartalmazniuk és közvetlenül interakcióba lépniük, hanem elég csak üzeneteket (üzeneteket) vagy eseményeket (események) váltani.

Néha úgy tűnik, hogy a modulok üzenetküldéses kommunikációja sokkal gyengébb, mint a közvetlen függőség. Valójában, mivel a metódusok nincsenek meghívva, nincs információ az osztályokról. De ez nem más, mint illúzió.

A metódusnevek helyett a logika az üzenettípusokhoz, azok paramétereihez és a továbbított adatokhoz kötődik. Az ilyen modulok csatlakoztathatósága elkenődött.

Régebben úgy volt, hogy metódusokat hívunk - kapcsolat van, metódusokat nem hívunk - nincs kapcsolat. Most képzeljük el, hogy az A modul kissé eltérő adatokat kezdett küldeni az üzeneteiben. Ugyanakkor az ezektől az üzenetektől függő összes modul nem fog megfelelően működni.

Tegyük fel, hogy korábban egy új felhasználó hozzáadásakor az engedélyezési modul a USER_ADDED üzenetet küldte, majd a frissítés után ezt az üzenetet kezdte el küldeni, amikor megpróbált regisztrálni, és emellett jelezte a sikeres regisztrációt vagy nem a paraméterekben.

Ezért nagyon fontos az üzenetmechanizmus nagyon hozzáértő megvalósítása. Ehhez különféle sablonok léteznek.

Megfigyelő. Egy a többhez való függőség esetén használják, amikor sok modul függ egy - a fő - állapotától. Levelezési mechanizmust használ, ami azt jelenti, hogy a fő modul egyszerűen ugyanazokat az üzeneteket küldi el minden előfizetőjének, az ezen információk iránt érdeklődő modulok pedig megvalósítják az „előfizetői” felületet és feliratkoznak a levelezőlistára.

Ezt a megközelítést széles körben alkalmazzák felhasználói felülettel rendelkező rendszerekben, lehetővé téve, hogy az alkalmazás (modell) magja független maradjon, miközben tájékoztatja a kapcsolódó felületeket, hogy valami megváltozott és frissítésre szorul.

Itt az üzenetformátum az operációs rendszer szintjén szabványosított, amelynek fejlesztőinek gondoskodniuk kell a visszafelé kompatibilitásról és a jó dokumentációról.

Az üzenetek terjesztésén keresztül történő interakció megszervezésének van egy további „bónusza” - az „előfizetők” opcionális létezése a „közzétett” (vagyis kiküldött) üzenetekre. Egy ilyen jól megtervezett rendszer lehetővé teszi a modulok bármikor történő hozzáadását/eltávolítását.

Üzenetküldő busz

Az üzenetváltást megszervezheti, és ehhez más módon használhatja a Mediator mintát .

Akkor használatos, ha a modulok között sok-sok függőség van. A közvetítő közvetítőként működik a modulok közötti kommunikációban, kommunikációs központként működik, és nincs szükség arra, hogy a modulok kifejezetten hivatkozzanak egymásra.

Ennek eredményeként a modulok egymás közötti interakcióját („minden mindenkivel”) felváltja a modulok interakciója csak egy közvetítővel („egy mindennel”). A közvetítőről azt mondják, hogy több modul közötti interakciót zárja be.

Üzenetküldő busz

Ez az úgynevezett intelligens közvetítő . A fejlesztők leggyakrabban itt kezdik hozzá a mankóikat, amelyek bizonyos üzenetek fogadásának be- és kikapcsolásával befolyásolják az egyes modulok viselkedését.

Tipikus valós példa a repülőtéri forgalomirányítás. A repülőgépekről érkező összes üzenet a vezérlő irányítótornyába kerül, ahelyett, hogy közvetlenül a repülőgépek között küldenék el őket. Az irányító pedig már dönt arról, hogy mely gépek szállhatnak fel vagy szállhatnak fel, és viszont üzeneteket küld a gépeknek.

Fontos! A modulok nem csak egyszerű üzeneteket, hanem parancsobjektumokat is küldhetnek egymásnak. Az ilyen interakciót a Command sablon írja le. A lényeg az, hogy egy adott művelet végrehajtására irányuló kérést külön objektumként kell beágyazni.

Valójában ez az objektum egyetlen execute() metódust tartalmaz, amely lehetővé teszi, hogy ezt a műveletet paraméterként átadja más moduloknak végrehajtásra, és általában minden olyan műveletet végrehajtson a parancsobjektummal, amely a közönséges objektumokon végrehajtható.

Demeter törvénye

A Demeter törvénye tiltja az implicit függőségek használatát: "Az A objektum nem férhet hozzá közvetlenül a C objektumhoz, ha A objektum hozzáfér B objektumhoz, és B objektum hozzáfér a C objektumhoz."

Ez azt jelenti, hogy a kódban lévő összes függőségnek „explicitnek” kell lennie – az osztályok/modulok csak „függőségeiket” használhatják munkájuk során, és nem mászhatnak át rajtuk mások felé. Jó példa erre a háromszintű architektúra. Az interfész rétegnek működnie kell a logikai réteggel, de nem szabad közvetlenül az adatbázisréteggel kölcsönhatásba lépnie.

Röviden, ez az elv is így van megfogalmazva: "Csak a közvetlen barátokkal lépj kapcsolatba, és ne a barátok barátaival." Ezáltal kisebb a kód koherenciája, valamint a tervezés nagyobb láthatósága és átláthatósága.

Demeter törvénye megvalósítja a már említett „minimális tudás elvét”, amely a laza csatolás alapja, és abból áll, hogy egy objektum/modul a lehető legkevesebb részletet ismerje más objektumok/modulok szerkezetéről, tulajdonságairól, ill. általában bármit, beleértve a saját összetevőit is .

Hasonlat az életből: ha azt akarod, hogy a kutya szaladgáljon, hülyeség parancsolni a mancsainak, jobb, ha a kutyának adjuk ki a parancsot, és ő maga fog megbirkózni a mancsával.

Öröklés helyett összetétel

Ez egy nagyon nagy és érdekes téma, és legalább egy külön előadást megérdemel. Rengeteg példány tört fel ebben a témában az interneten, amíg konszenzusra nem jutottak - az öröklődést minimálisan, az összetételt - maximálisan használjuk.

A lényeg az, hogy valójában az öröklődés biztosítja a legerősebb kapcsolatot az osztályok között, ezért ezt kerülni kell. Ezt a témát jól tárgyalja Herb Sutter „ A kompozíció előnyben részesítése az öröklődés helyett ” című cikke.

Amikor elkezdi megtanulni a tervezési mintákat, egy csomó mintával fog találkozni, amelyek irányítják egy objektum létrehozását vagy belső szerkezetét. Egyébként azt tudom tanácsolni ebben az összefüggésben, hogy figyeljen a Delegate / Delegate mintára és a Component mintára, amelyek a játékokból származtak .

A mintákról kicsit később fogunk még beszélni.

undefined
3
Опрос
Software architecture, client-server architecture, MVC,  14 уровень,  9 лекция
недоступен
Software architecture, client-server architecture, MVC
Software architecture, client-server architecture, MVC