Szolgáltatáskereső minta és Java implementáció
1. Bemutatkozás
Ebben az oktatóanyagban megismerkedünk a Service Locator tervezési mintája Java-ban.
Leírjuk a koncepciót, megvalósítunk egy példát, és rávilágítunk a használatának előnyeire és hátrányaira.
2. A minta megértése
A Service Locator minta célja a szolgáltatáspéldányok igény szerinti visszaadása. Ez hasznos a szolgáltatás fogyasztóinak elválasztásához a konkrét osztályoktól.
A megvalósítás a következő összetevőkből áll:
- Ügyfél - az ügyfélobjektum szolgáltatásfogyasztó. Felelős a szolgáltatáskereső kérésének meghívásáért
- Szolgáltatáskereső - egy kommunikációs belépési pont a szolgáltatások visszaállításához a gyorsítótárból
- Gyorsítótár - a szolgáltatás referenciáinak tárolására szolgáló objektum későbbi újrafelhasználás céljából
- Inicializáló - létrehozza és regisztrálja a gyorsítótárban található szolgáltatások hivatkozásait
- Szolgáltatás - a Szolgáltatás összetevő képviseli az eredeti szolgáltatásokat vagy azok megvalósítását
Az eredeti szolgáltatási objektumot a helymeghatározó keresi meg, és igény szerint visszaküldi.
3. Végrehajtás
Nézzük át a gyakorlatot, és egy példán keresztül nézzük meg a fogalmakat.
Először létrehozunk egy MessagingService interfész üzenetek küldéséhez különböző módon:
nyilvános felület MessagingService {String getMessageBody (); Karakterlánc getServiceName (); }
Ezután meghatározzuk a fenti felület két megvalósítását, amelyek e-mailben és SMS-ben küldenek üzeneteket:
public class EmailService megvalósítja a MessagingService {public String getMessageBody () {return "email message"; } public String getServiceName () {return "EmailService"; }}
A SMSService osztály definíciója hasonló a EmailService osztály.
A két szolgáltatás meghatározása után meg kell határoznunk az inicializálás logikáját:
public class InitialContext {public Object lookup (String serviceName) {if (serviceName.equalsIgnoreCase ("EmailService")) {{return new EmailService (); } else if (serviceName.equalsIgnoreCase ("SMSService")) {return new SMSService (); } return null; }}
Az utolsó összetevő, amelyre a szolgáltatás-lokátor objektum összerakása előtt szükségünk van, a gyorsítótár.
Példánkban ez egy egyszerű osztály a Lista ingatlan:
public class Cache {private List services = new ArrayList (); public MessagingService getService (String serviceName) {// beolvasás a listából} public void addService (MessagingService newService) {// hozzáadás a listához}}
Végül megvalósíthatjuk szolgáltatáskereső osztályunkat:
public class ServiceLocator {private static Cache cache = új gyorsítótár (); nyilvános statikus MessagingService getService (String serviceName) {MessagingService service = cache.getService (serviceName); if (szolgáltatás! = null) {visszatérési szolgáltatás; } InitialContext context = új InitialContext (); MessagingService service1 = (MessagingService) kontextus .lookup (serviceName); cache.addService (szolgáltatás1); visszatérési szolgáltatás1; }}
A logika itt meglehetősen egyszerű.
Az osztály rendelkezik a Gyorsítótár. Aztán a getService () módszerrel, először a szolgáltatás egyik példányának gyorsítótárát ellenőrzi.
Akkor, ha ez van nulla, meghívja az inicializálási logikát, és hozzáadja az új objektumot a gyorsítótárhoz.
4. Tesztelés
Nézzük meg, hogyan szerezhetünk példányokat most:
MessagingService service = ServiceLocator.getService ("EmailService"); Karakterlánc e-mail = service.getMessageBody (); MessagingService smsService = ServiceLocator.getService ("SMSService"); Karakterlánc sms = smsService.getMessageBody (); MessagingService emailService = ServiceLocator.getService ("EmailService"); String newEmail = emailService.getMessageBody ();
Először kapjuk meg a EmailService tól ServiceLocator új példány jön létre és ad vissza. Aztán miután legközelebb felhívta a EmailService visszatér a gyorsítótárból.
5. Szolgáltatáskereső vs függőségi injekció
Első ránézésre a Service Locator minta hasonló lehet egy másik jól ismert mintához - nevezetesen a Dependency Injection.
Először is fontos megjegyezni mind a Dependency Injection, mind a Service Locator minta az Inversion of Control koncepció megvalósításai.
Mielőtt továbblépne, többet megtudhat a Függőség injekcióról ebben az írásban.
A legfontosabb különbség itt az, hogy az ügyfélobjektum továbbra is létrehozza függőségeit. Ehhez csak a lokátort használja, vagyis hivatkozásra van szüksége a lokátor objektumra.
Összehasonlításképpen: a függőségi injekció használatakor az osztály megkapja a függőségeket. Az injektort indításkor csak egyszer hívják be, hogy függőségeket juttasson az osztályba.
Végül vegyünk fontolóra néhány okot a Service Locator minta használatának elkerülésére.
Az egyik érv ellene az, hogy megnehezíti az egység tesztelését. A függőségi injekcióval átadhatjuk a függő osztályba tartozó csúfolt objektumokat a tesztelt példánynak. Másrészt ez egy szűk keresztmetszet a Service Locator mintával.
Más kérdés, hogy bonyolultabb az API-k használata ezen a mintán. Ennek az az oka, hogy a függőségek el vannak rejtve az osztályban, és csak futás közben ellenőrizhetők.
Mindezek ellenére a Service Locator minta könnyen kódolható és érthető, és nagyszerű választás lehet kis alkalmazásokhoz.
6. Következtetés
Ez az útmutató bemutatja, hogyan és miért kell használni a Service Locator tervezési mintát. Megbeszéli a Service Locator tervezési mintája és a Dependency Injection koncepció közötti legfontosabb különbségeket.
Általában a fejlesztő feladata, hogy kiválassza az osztályok kialakítását az alkalmazásban.
A szolgáltatáskereső minta egy egyszerű minta a kód leválasztására. Abban az esetben, ha az osztályokat több alkalmazásban alkalmazzák, a függőség-injektálás helyes választás.
Szokás szerint a teljes kód elérhető a Github projektben.