栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式のService Locator Pattern

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式のService Locator Pattern

文章目录
  • Service Locator Pattern
    • service Locator
    • InitialContext
    • ServiceFactory
    • BusinessService
    • 图例
    • java code demo
      • 服务接口
      • 服务提供商类
      • 容器类
      • 缓存类
      • ServiceLocator 类
      • 测试类
    • 优点
    • 缺点
    • 总结

Service Locator Pattern

geeksforgeeks的原文 ,我理解性的翻译了下,添加了些自己的理解。

用 抽象层 封装 获取服务 的过程,是IOC模式的一种实现,有别于DI。

使用一个被称为 service locator的中心注册表,service locator 根据请求返回执行具体任务所需要的的信息。

当服务消费者请求服务实例时,serviceLocator负责返回对应的服务实例。


service Locator

service locator 将 查找服务的API、服务提供者依赖、查找的复杂性以及业务对象的创建做了抽象,仅对服务消费者暴露一个简单的接口,这样将复杂封装在自己内部,使得客户端变的简单。


InitialContext

初始化上下文,类似于 spring里面的容器概念。如果对容器的概念也不清楚,那就只可意会不可言传了。

是整个服务查找和创建过程的起点。将所有的服务提供商放进这个容器里面,如果,后续有新的服务提供商加入进来,也需要将它们放进这个InitialContext容器来。

InitialContext 根据具体的业务对象类型返回具体服务对象。


ServiceFactory

服务工厂对象负责管理 业务服务对象 的生命周期,何时实例化,何时销毁等。


BusinessService

业务服务对象,是一个角色,由客户端需求的服务对象来扮演。所以说,就是具体的服务提供商对象。

业务服务对象 由 服务工厂创建、查找、删除


图例

以前的类关系

服务消费者和服务提供商,绑定在一起,增加或删除服务提供商,都需要更改服务消费者中的代码。

在编译的时候,具体的服务提供商的类就需要存在。


Service Locator Pattern 模式的类关系

服务提供商和服务消费者之间的耦合,转移到 locator 里面

在编译的时候,具体的服务提供商的类不需要存在。增加或修改服务提供商,服务消费者也不需要改代码。


java code demo 服务接口
interface Service {
	public String getName();
	public void execute();
}
服务提供商类
// 具体的服务提供商 one
class ServiceOne implements Service {
	public void execute()
	{
		System.out.println("Executing ServiceOne");
	}

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

// 具体的服务提供商 two 
class ServiceTwo implements Service {
	public void execute()
	{
		System.out.println("Executing ServiceTwo");
	}

	@Override
	public String getName()
	{
		return "ServiceTwo";
	}
}
容器类
class InitialContext {
    
    // 这里面的代码,简单化了
    // 业务复杂的话,这里面应该抽象出一个 ServiceFactory 类,复杂具体服务的创建
	public Object lookup(String name)
	{
		if (name.equalsIgnoreCase("ServiceOne")) {
			System.out.println("Creating a new ServiceOne object");
			return new ServiceOne();
		}
		else if (name.equalsIgnoreCase("ServiceTwo")) {
			System.out.println("Creating a new ServiceTwo object");
			return new ServiceTwo();
		}
		return null;
	}
}
缓存类

搭配上面的 InitialContext 更像容器。

class Cache {
	private List services;

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

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

	public void addService(Service newService)
	{
		boolean exists = false;
		for (Service service : services) {
			if (service.getName().equalsIgnoreCase(newService.getName())) {
				exists = true;
			}
		}
		if (!exists) {
			services.add(newService);
		}
	}
}
ServiceLocator 类
// Locator class
class ServiceLocator {
	private static Cache cache;

	static
	{
		cache = new Cache();
	}

	public static Service getService(String name)
	{
		Service service = cache.getService(name);

		if (service != null) {
			return service;
		}
		// 越看越像 spring里面的 ApplicationContext 
		InitialContext context = new InitialContext();
        // getBean 方法
		Service ServiceOne = (Service)context.lookup(name);
		cache.addService(ServiceOne);
		return ServiceOne;
	}
}
测试类
// Driver class
class ServiceLocatorPatternDemo {
	public static void main(String[] args)
	{
		Service service = ServiceLocator.getService("ServiceOne");
		service.execute();

		service = ServiceLocator.getService("ServiceTwo");
		service.execute();

		service = ServiceLocator.getService("ServiceOne");
		service.execute();

		service = ServiceLocator.getService("ServiceTwo");
		service.execute();
	}
}


优点
  1. `ServiceLocator` 配合 `cache`,完成了`service`的单例模式。并不需要具体的`service`自己实现单例模式,通过`cache` 完成了单例的需求。这在某些场景下,很实用,假如考虑,创建具体的服务提供商对象很占用资源,但是具体的服务又是第三方提供的,这时候就可以用这种思路实现单例,缓存起来。
  2. 程序可以在运行时动态调整依赖
  3. 解耦合,服务消费者和服务提供者之间并没有之间的联系,所有的联系都在注册表中

缺点
  1. 如果服务提供商不存在,本来应该在编译期间就会被发现的,因为是直接依赖。现在转移到运行期间才能发现。(其实算不得缺点,将依赖耦合解耦了,就这样)

总结

最后,设计模式不能完全理解,或者想不到对应的案列,是正常的。毕竟设计模式是总结会来的经验性准则,需要一定的阅历或者说经历过类似的坑,才能感同身受。

就像后来的我们学 spring 框架,永远也不会多么深刻的理spring的轻量级,轻量在哪里。但是如果你是从EJB 时代过来的,你就会 会心一笑。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/389777.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号