[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的重用性。)

下载

范例程序代码:点此下载

posted @ 2014-06-15 20:30  Clark159  阅读(200)  评论(0编辑  收藏  举报