Design Pattern #4.1

Autor: NathalieOhneHerz GitHub

Das Service Locator Pattern mit Cache


Was ist das Service Locator Pattern mit Cache?

Wie bereits im oben erwähnten Hauptartikel lässt sich das Service Locator Pattern um einen Cache erweitern, was die Performance erhöht, vor allem wenn eine und derselbe Service mehrmals während eines Programmablaufs aufgerufen und genutzt werden soll. Der Cache ist hier simpel gehalten, eine Alternative wäre eine Google Guava Cache.


Modellierung


Implementierung in Java

package de.nathalieoneill.devtek.service.impl; import de.nathalieoneill.devtek.service.Service; /** * @author Nathalie */ public class AccountService implements Service { public void setAccountEmail(String accountName, String accountEmail) { System.out.println("Setting email: " + accountName + " " + accountEmail); } }
package de.nathalieoneill.devtek.service.impl; import de.nathalieoneill.devtek.service.Service; /** * @author Nathalie */ public class UserService implements Service { public void createUser(String name) { System.out.println("Creating User " + name); } }
package de.nathalieoneill.devtek.service; /** * @author Nathalie */ public interface Service { }
package de.nathalieoneill.devtek.service; import java.util.HashMap; import java.util.Map; /** * @author Nathalie */ public class ServiceCache { private final Map<Class<? extends Service>, Service> cachedServices; public ServiceCache() { this.cachedServices = new HashMap<Class<? extends Service>, Service>(); } public Service getService(Class<? extends Service> serviceClass) { return cachedServices.get(serviceClass); } public void put(Service service) { this.cachedServices.put(service.getClass(), service); } }
package de.nathalieoneill.devtek.service; import de.nathalieoneill.devtek.service.impl.AccountService; import de.nathalieoneill.devtek.service.impl.UserService; /** * @author Nathalie */ public class ServiceContext { public Service lookup(Class<? extends Service> serviceClass) { if (serviceClass == AccountService.class) return new AccountService(); else if (serviceClass == UserService.class) return new UserService(); return null; } }
package de.nathalieoneill.devtek.service; /** * @author Nathalie */ public class ServiceLocator { private static final ServiceCache SERVICE_CACHE; static { SERVICE_CACHE = new ServiceCache(); } public static <T extends Service> T getService(Class<? extends Service> clazz) { Service service = SERVICE_CACHE.getService(clazz); if (service != null) return (T) service; service = new ServiceContext().lookup(clazz); SERVICE_CACHE.put(service); return (T) service; } }

Die Verwendung sieht weinterhin so aus:

package de.nathalieoneill.devtek; import de.nathalieoneill.devtek.service.ServiceLocator; import de.nathalieoneill.devtek.service.impl.AccountService; import de.nathalieoneill.devtek.service.impl.UserService; /** * @author Nathalie */ public class DevTek { public static void main(String[] args) { AccountService accountService = ServiceLocator.getService(AccountService.class); accountService.setAccountEmail("Nathalie", "Trash@Tash.tsh"); UserService userService = ServiceLocator.getService(UserService.class); userService.createUser("Nathalie"); } }

Ich hoffe dass ich euch die Verwendung eines Caches beim Service Locator Pattern näher bringen konnte.

Mit freundlichen Grüßen
Nathalie