.Net服务定位器之反模式

为更好理解依赖注入模式,特意去了解服务定位器模式,今日留下一文笔记,以助巩固。

Martin Fowler提出的服务器定位器概念实际上是一种反模式,简单而言,服务器隐藏了类之间依赖关系,(注意是隐藏了,隐藏了),因为藏得深,所以不易见,从而不清晰,增加了维护难度。

服务定位器实现代码如下:

public static class Locator
{
    //定位器服务集合
    private readonly static Dictionary<Type, Func<object>>
        services = new Dictionary<Type, Func<object>>();

     //往定位器的服务塞东西  -注册服务
    public static void Register<T>(Func<T> resolver)   
    {
        Locator.services[typeof(T)] = () => resolver();
    }
    
    //根据参数从定位器的服务里拿东西  -解析 
    public static T Resolve<T>()       
    {
        return (T)Locator.services[typeof(T)]();
    }
    
    //清空定位器的服务 
    public static void Reset()
    {
        Locator.services.Clear();
    }
}

真正的服务定位器代码实现比这个要复杂,但是这个实现已经抓住了重点。(不要过于纠结于此,先理解是关键)。

现在创建订单处理对象,对象里使用上面的静态的服务定位器,代码如下:

public class OrderProcessor : IOrderProcessor
{
    public void Process(Order order)
    {
        //从定位器里拿出注册该接口的服务   (定位器不一定有注册了该接口的服务,运行时可能抛异常,编译时是不能知道有没有这个服务的。
        var validator = Locator.Resolve<IOrderValidator>();  
        if (validator.Validate(order))
        {
            //从定位器里拿出注册该接口的服务   (定位器不一定有注册了该接口的服务,运行时可能抛异常,编译时是不能知道有没有这个服务的。
            var shipper = Locator.Resolve<IOrderShipper>();
            shipper.Ship(order);
        }
    }
}

现在假设我们是上面订单的消费者,如何处理订单的接口都外包给第三方做了,我们并不清楚处理订单的源码。我们创建订单(通过IDE的代码提示我们清楚有这么个订单对象),代码如下:

var dealOrder = new OrderProcessor();

创建订单,调用处理订单方法,代码如下:

var order = new Order();
var dealOrder   = new OrderProcessor();
sut.Process(order);

运行这段代码(即运行时)抛出了一个KeyNotFoundException(主键找不到异常),因为IOrderValidator从来没有在定位器上注册过,通过仔细阅读源代码或查阅文档,又或问第三方技术支持者,我们可能最终会发现,在运行代码之前,我们需要用服务定位器给IOrderValidator接口注册一个服务,该服务是一个静态类。

烦躁,这种开发体验并不是那么友好!之前都没有告诉要注册这个服务,等我执行后才告诉我去补工作。气呀!

更令人郁闷的是,如果我运行成功了,不抛异常,我所调用的服务会不会在别的地方(我不知道的地方,毕竟大部分公司都是团队开发项目)注册的,而这个服务又不是我真的想要的。

上面的服务定位器里多处用到static关键字:静态类、静态成员,这个东西用不好真会扰人好梦。 static关键字学习

服务定位器使用静态类会产生如下弊端
1、因为类是静态类,所以到处的订单处理对象实例都是共用一个服务定位器对象。到处都可以注册服务,多危险呀。当前对象会不会一不小心用到了不该用的服务呢?

2、如果想扩展服务定位器的成员方法,例如代码如下:

public void Process(Order order)
{
    var validator = Locator.Resolve<IOrderValidator>();
    if (validator.Validate(order))
    {
        //多用了个服务
        var collector = Locator.Resolve<IOrderCollector>();  
        collector.Collect(order);
        var shipper = Locator.Resolve<IOrderShipper>();
        shipper.Ship(order);
    }
}

会不会在扩展'增加使用多一个IOrderCollector的服务'之前,就有别处给这个定位器注册这个服务,而这个服务又不是某个订单处理调用Process方法想要的结果,难道我还要加个修改已经注册了服务的方法,那我修改某个注册的服务,就不会别的处理对象实例产生影响吗?岂不糟糕透了!

窟窿有了就要补,我们是高级动物,得学会思考解决问题。

如果不使用静态了,类不用静态修饰,成员不用静态修饰。把服务定位器成为一个注入点(依赖注入),结果会怎样呢?

我的理解,若追根溯源,详看大牛讲解文章
下篇服务定位器之依赖注入模式,继续分享~
☆☆☆ 如有错漏之处,希望大家不吝指出。如果喜欢,希望大家多多点赞。笔芯!☆☆☆

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,300评论 8 265
  • 鹊桥相会泪濛濛,爱恨情缘叠梦中。 暗渡银河影相顾,初衷不改作孤鸿。
    亁乾阅读 286评论 2 3
  • 每次听到《团结就是力量》这首歌,我总是会感慨万千。特别是在运动会之后,体会更是深刻。 锣鼓喧天的运动会...
    童言无忌DYQ阅读 397评论 0 1
  • ――(一)薛宝钗 金钗覆雪拂还满,蘅芜冷香落阑珊。 纵有好风频借力,青云深处梦犹寒。
    禾卿阅读 350评论 0 0