• [Architecture Pattern] Singleton Locator


    [Architecture Pattern] Singleton Locator

    目的

    组件自己提供Service Locator模式,用来降低组件的耦合度。

    情景

    在开发系统时,底层的Infrastructure Context、或是核心的Domain Context这些共享对象生成之后,会在系统的许多地方被使用。为了减少共享对象初始生成、参考传递所造成的困扰,可以在系统内套用Service Locator模式,提供统一的静态参考点来生成、存取这些共享对象。

    Service Locator模式确实减少共享对象初始生成、参考传递所造成的困扰,但在实作的过程中却会发现Service Locator模式,很容易为系统中的组件引入额外相依性。以下列这个范例项目来说,Client对象经由ServiceLocator对象,取得DataContext对象在执行过程中存取数据。

    • 物件图

      情景02

    在实作的过程中为了能够重用程序代码,通常会将ServiceLocator对象封装为Infrastructure组件内容,而DataContext对象封装成为Domain组件内容、Client对象则是封装为Host组件。

    • 组件图

      情景03

    一般来说Infrastructure组件内会包含许多基础对象,不会单纯只封装ServiceLocator对象。当这些基础对象引用其他参考时,也就是间接的增加了Host组件的相依性、增加了Host组件对于其他组件的耦合。

    • 组件图

      情景04

    这时可以考虑将ServiceLocator对象设计为独立组件,让组件里只包含一个对象以避免不必要的相依性。但是当这样的设计一多的时候,很容易就会让组件的设计过于破碎。

    • 组件图

      情景05

    为了降低组件耦合的问题,回过头思考Client对象、DataContext对象、ServiceLocator对象三者之间的关系。会发现Client对象需要的是ServiceLocator对象所提供的对象生成、静态参考等功能,而不是真的需要一个ServiceLocator对象。

    这时开发人员可以将ServiceLocator对象所提供的对象生成、静态参考等功能,建立在DataContext对象自己本身之上,透过DataContext对象自己提供对象生成、静态参考等功能。也就是说经由这样的设计,将ServiceLocator对象从系统中移除、也就是把Infrastructure组件从系统中移除,进而降低了Host组件的相依性、降低了Host组件对于其他组件的耦合。

    • 组件图

      情景06

    结构

    • 物件图

      结构01

    参与者

    Service

    • 提供自身服务功能。

    • 提供自身静态参考,用于参考定位、外部生成。

    • 提供自身生成功能,用于内部生成。

    Client

    • 使用Context功能的对象。

    • 外部生成的使用情景中,生成Context并且注入Context静态参考。

    合作方式

    • 外部生成

      合作方式01

    • 内部生成

      合作方式02

    (为了简化说明,Service生成模式采用直接建立的方式来示意。实际项目可以采用各种IoC Framework来做生成注入,或是套用各种Factory pattern,这些都能提高Service的重用性。)

    实作

    • 类别图

      实作01

    • Service

      public partial class Service
      {
          // Locator
          private static Service _current;
      
          public static Service Current
          {
              get
              {
                  if (_current == null)
                  {
                      _current = new Service("内部生成");
                  }
                  return _current;
              }
              set
              {
                  _current = value;
              }
          }
      }
      
      public partial class Service
      {
          // Constructors
          public Service(string message)
          {
              // Arguments
              this.Message = message;
          }
      
      
          // Properties
          public string Message { get; set; }
      
      
          // Methods
          public void Execute()
          {
              Console.WriteLine(this.Message);
          }
      }
      
    • 外部生成

      class Program
      {
          static void Main(string[] args)
          {
              // Init
              Init();
      
              // Execute
              Service.Current.Execute();
              Console.WriteLine();
      
              // End           
              Console.WriteLine("End...");
              Console.ReadLine();
          }
      
          static void Init()
          {
              // Service
              Service.Current = new Service("外部生成");
          }
      }
      

      实作02

    • 内部生成

      class Program
      {
          static void Main(string[] args)
          {
              // Init
              Init();
      
              // Execute
              Service.Current.Execute();
              Console.WriteLine();
      
              // End           
              Console.WriteLine("End...");
              Console.ReadLine();
          }
      
          static void Init()
          {
              // Service
      
          }
      }
      

      实作03

    (为了简化说明,Service生成模式采用直接建立的方式来示意。实际项目可以采用各种IoC Framework来做生成注入,或是套用各种Factory pattern,这些都能提高Service的重用性。)

    下载

    范例程序代码:点此下载

  • 相关阅读:
    面向对象之继承
    面向对象
    Python—文件和内建函数 open(),file()
    如何在命令行打开文件夹?
    Anaconda在win10下的安装
    Python—for循环和range()内建函数
    python—基础练习2
    python—数据类型
    python—字符编码
    python—基础练习1
  • 原文地址:https://www.cnblogs.com/clark159/p/3789873.html
Copyright © 2020-2023  润新知