1. 程式人生 > >設計模式之服務定位器模式(Service Locator Pattern)

設計模式之服務定位器模式(Service Locator Pattern)

服務定位器模式(Service Locator Pattern)用在我們想使用 JNDI 查詢定位各種服務的時候。考慮到為某個服務查詢 JNDI 的代價很高,服務定位器模式充分利用了快取技術。在首次請求某個服務時,服務定位器在 JNDI 中查詢服務,並快取該服務物件。當再次請求相同的服務時,服務定位器會在它的快取中查詢,這樣可以在很大程度上提高應用程式的效能。以下是這種設計模式的實體。
服務(Service) - 實際處理請求的服務。對這種服務的引用可以在 JNDI 伺服器中查詢到。
Context / 初始的 Context - JNDI Context 帶有對要查詢的服務的引用。
服務定位器(Service Locator) - 服務定位器是通過 JNDI 查詢和快取服務來獲取服務的單點接觸。
快取(Cache) - 快取儲存服務的引用,以便複用它們。
客戶端(Client) - Client 是通過 ServiceLocator 呼叫服務的物件。
程式碼:
1.服務介面

public interface Service {
    public String getName();
    public void execute();
}
public class Service1 implements Service{

    @Override
    public String getName() {
        return "service1";
    }

    @Override
    public void execute() {
        System.out.println("執行服務1的服務");
    }

}
public class Service2  implements Service{

    @Override
    public String getName() {
        return "service2";
    }

    @Override
    public void execute() {
        System.out.println("執行服務2的服務");
    }

}

2.為 JNDI 查詢建立 InitialContext

public class InitialContext {
    public Object lookUp(String jndiName) {
        if ("service1".equalsIgnoreCase(jndiName)) {
            System.out.println("Looking up and creating a new Service1 object");
            return new Service1();
        } else if ("service2".equalsIgnoreCase(jndiName)) {
            System.out.println("Looking up and creating a new Service2 object");
            return new Service2();
        }
        return null;
    }
}

3.快取 Cache

public class Cache {
    private List<Service> services;

    public Cache() {
        services = new ArrayList<>();
    }

    public Service getService(String serviceName) {
        for (Service service : services) {
            if (serviceName.equalsIgnoreCase(service.getName())) {
                System.out.println("return cache service...");
                return service;
            }
        }
        return null;
    }

    public void addService(Service service) {
        boolean flag = false;
        for (Service service1 : services) {
            if (service1.getName().equalsIgnoreCase(service.getName()))
                flag = true;
        }
        if (!flag)
            services.add(service);
    }

}

4.服務定位器

public class ServiceLocator {
    private static Cache cache;
    
    static {
        cache=new Cache();
    }
    
    public static Service getService(String jndiName) {
        Service service=cache.getService(jndiName);
        if(service!=null)
            return service;
        InitialContext context=new InitialContext();
        Service service1=(Service) context.lookUp(jndiName);
        cache.addService(service1);
        return service1;
    }
    
}

5.測試

public class Test {
    public static void main(String[] args) {
        Service service=ServiceLocator.getService("service1");
        service.execute();
        service=ServiceLocator.getService("service1");
        service.execute();
        service=ServiceLocator.getService("service2");
        service.execute();
        service=ServiceLocator.getService("service2");
        service.execute();
    }
}

6.測試結果

Looking up and creating a new Service1 object
執行服務1的服務
return cache service...
執行服務1的服務
Looking up and creating a new Service2 object
執行服務2的服務
return cache service...
執行服務2的服務

7.結論
client客戶端通過定位器獲取服務,然後呼叫服務。定位器先去快取裡面取,沒有,去初始化Context中取。

轉載於
http://www.runoob.com/design-pattern/service-locator-pattern.html