设计模式之服务定位模式

2024-06-14 1387阅读

文章目录

  • 服务定位器模式
    • 概要
      • 意图
      • 主要解决的问题
      • 使用场景
      • 实现方式
      • 关键代码
      • 应用实例
        • 优点
        • 缺点
        • 使用建议
        • 注意事项
        • 包含的几个主要角色
        • 代码实现

          服务定位器模式

          服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。

          设计模式之服务定位模式
          (图片来源网络,侵删)
          • 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
          • Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
          • 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
          • 缓存(Cache) - 缓存存储服务的引用,以便复用它们。(实际编程可省略,用Map替代)
          • 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。

            概要

            意图

            用于在应用程序中提供一个中心化的服务访问点,用以获取各种服务或资源。

            主要解决的问题

            解决在应用程序中需要访问各种服务或资源时,避免硬编码服务访问逻辑的问题。

            使用场景

            当应用程序需要访问多个外部服务或资源,并且希望将这些访问逻辑集中管理时。

            实现方式

            • 服务定位器接口:定义获取服务的方法。
            • 服务定位器实现:实现服务定位器接口,封装服务的查找和访问逻辑。
            • 服务接口:定义服务的接口或契约。
            • 具体服务:实现服务接口,提供具体的服务功能。

              关键代码

              服务定位器:包含逻辑以查找和返回请求的服务实例。

              服务接口:定义服务的抽象表示。

              应用实例

              企业应用程序:应用程序使用服务定位器来访问数据库服务、消息队列服务等。

              优点
              • 解耦服务访问:将服务访问逻辑与使用服务的业务逻辑分离。
              • 集中管理:服务的访问点集中管理,便于维护和扩展。
              • 灵活性:易于添加、修改或替换服务。
                缺点
                • 性能问题:服务定位器可能引入性能开销,特别是在每次服务请求都进行查找时。
                • 过度使用:可能导致设计模式的滥用,从而隐藏系统结构。

                  使用建议

                  当应用程序需要以一种灵活且可维护的方式访问多个服务时,考虑使用服务定位器模式。

                  注意事项

                  避免过度依赖服务定位器,因为它可能掩盖系统的依赖关系,使得调试和优化变得困难。

                  包含的几个主要角色

                  • 服务定位器接口(Service Locator Interface): 定义获取服务的方法。
                  • 服务定位器实现(Service Locator Implementation): 实现服务定位器接口,封装服务的查找和访问逻辑。
                  • 服务接口(Service Interface): 定义服务的抽象表示。
                  • 具体服务(Concrete Service): 实现服务接口,提供具体的服务功能。
                  • 客户端(Client): 使用服务定位器来访问所需的服务。
                  • Context /初始的Context - 初始化服务对象并提供对象索引。

                    服务定位器模式通过提供一个集中的服务访问点,有助于简化服务访问逻辑,并提高应用程序的灵活性和可维护性。

                    代码实现

                    这里以Spring的BeanFactory的逻辑举例,不涉及具体的xml的具体实现,只是把代码的结构表达出来

                    首先定义BeanFactory接口,相当于服务定位模式中的服务定位器(Service Locator)角色

                    public interface BeanFactory {
                        Object getBean(String beanName);
                         T getBean(String beanName,Class clzss);
                    }
                    

                    然后定义对象注入接口,Spring框架中ApplicationContext,相当于服务定位模式中的Context

                    public interface ApplicationContext {
                        //spring-beans.xml 配置文件的路径
                        void init(String context);
                    }
                    

                    具体实现Xml解析初始化,按照服务定位模式来说需要一个服务定位器(Service Locator)的角色的实现,也就是这里的BeanFatory的实现,但是Spring在实现中,通过一个实现两个接口同实现两个功能。

                    public class XmlApplicationContext implements ApplicationContext,BeanFactory{
                        private Map cache = new HashMap();
                        public XmlApplicationContext(String context){
                            init(context);
                        }
                        @Override
                        public void init(String context) {
                            //根据context 读取xml配置文件,初始化cache
                            // 这里直接创建
                            cache.put("userController",new UserController());
                        }
                        @Override
                        public Object getBean(String beanName) {
                            return cache.get(beanName);
                        }
                        @Override
                        @SuppressWarnings("unchecked")
                        public  T getBean(String beanName, Class clzss) {
                            return (T) cache.get(beanName);
                        }
                    }
                    

                    定义服务角色

                    public interface Controller {
                        void handle();
                    }
                    public class UserController implements Controller{
                        @Override
                        public void handle() {
                            System.out.println("处理请求");
                        }
                    }
                    

                    实际使用的过程

                    public class Client {
                        public static void main(String[] args) {
                            XmlApplicationContext xmlApplicationContext = new XmlApplicationContext("classpath:spring-beans.xml");
                            Controller b = xmlApplicationContext.getBean("userController", Controller.class);
                        }
                    }
                    
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]