zoukankan      html  css  js  c++  java
  • javax.inject包

    javax.inject包

    java提出的依赖注入标准,有别于以下传统的对象获取方式

    • 构造方法
    • 工厂模式
    • 服务器定位模式(e.g. JNDI)

    开发过程中是会有很多层层依赖的对象的,例如,Stopwatch依赖于TimeSource,为当前对象寻找一个所依赖对象的实例称做解决依赖,若没有实例被找到,则应用执行失败,我们称依赖不满足

    当没有依赖注入时,也有很多解决依赖的方法,例如直接调用构造器

    class Stopwatch {
        final TimeSource timeSource;
        Stopwatch() {
            timeSource = new AtomicClock(...);
        }
        void start() {...}
        void stop() {...}
    }
    

    如果需要更多的灵活性,可以使用工厂方法

    class Stopwatch {
        final TimeSource timeSource;
        Stopwatch() {
            timeSource = DefaultTimeSource.getInstance();
        }
        void start() {...}
        void stop() {...}
    }
    

    我们必须权衡这两种方式:

    • 构造器很简洁,但不灵活
    • 工厂方法虽然从一定程度上解耦了调用方和具体实现,但是需要很多模版代码
    • Service locators方式虽然实现了更好的耦合,但缺少了编译时的类型检查

    而且,这几种方法都限制了单元测试,例如,如果我们使用工厂方法,所有依赖于依赖于工厂类的测试代码都需要模拟出factory,还要记得在用完之后清理掉它

    void testStopwatch() {
        // 先获取原始的实例
        TimeSource original = DefaultTimeSource.getInstance();
        // 用mock数据替换原始实例
        DefaultTimeSource.setInstance(new MockTimeSource());
        try {
            Stopwatch sw = new StopWatch();
            ...
        } finally {
            // 将原始实例放回去以避免一些风险
            DefaultTimeSource.setInstance(original);
        }
    }
    

    实践经验告诉我们,模拟factor会导致大量的模式化代码,大量的模拟和清理将会很快失控。

    依赖注入解决了所有的这些问题

    class Stopwatch {
        final TimeSource timeSource;
        @Inject
        Stopwatch(TimeSource timeSource) {
            this.timeSource = timeSource;
        }
        void start() {...};
        void stop() {...};
    }
    

    构造器进一步的将依赖层层传递,直到满足全部依赖。例如,我们需要构造一个StopwatchWidget实例:

    class StopwatchWidget {
        @Inject
        StopwatchWidget(Stopwatch sw) {...}
    }
    

    构造器做了什么

    1. 找到一个TimeSource
    2. 利用TimeSource构造Stopwatch
    3. 利用Stopwatch构造StopwatchWidget

    这使我们的代码看起来更加简洁和灵活,并从一定程度上弱化了依赖关系

    在测试用例中,我们也可以直接通过像构造器传递模拟数据进行单元测试,再也不需要设置/清理factories了

    void testStopwatch() {
        Stopwatch sw = new Stopwatch(new MockTimeSource());
    }
    
  • 相关阅读:
    [Python]jieba切词 添加字典 去除停用词、单字 python 2020.2.10
    假期学习【十一】Python切词,以及从百度爬取词典
    Cocos2D-x中关于CREATE_FUNC宏的用法
    Cocos2D-x中关于do{}while(0)和CC_BREAK_IF的用法
    Cocos2d-x学习笔记(三十三)之常用的宏
    Cocos2d-x学习笔记(三十二)之图片渲染
    Cocos2d-x学习笔记(三十一)之 内存管理
    Cocos2d-x学习笔记(三十)之 游戏存档
    Cocos2d-x学习笔记(二十九)之 声音
    Cocos2d-x学习笔记(二十八)之 滚动列表类CCListView
  • 原文地址:https://www.cnblogs.com/shiyu404/p/10235957.html
Copyright © 2011-2022 走看看