工具类用依赖注入来引用资源,而非使用static方法

 假设工具类为拼写检查器,它工作需要依赖字典,下面是工具类的一种常用写法:

public class SpellChecker {

    private static final Dictionary DICTIONARY = new Dictionary();

    private SpellChecker() {
        throw new UnsupportedOperationException();
    }

    public static boolean isVaild(String word) {
        // ......
    }

    public static String correct() {
        // ......
    }
    // ......
}

class Dictionary {
    // ......
}

或者采用单例模式:

public class SpellChecker {

    private final Dictionary DICTIONARY = new Dictionary();

    private SpellChecker() {}

    public static SpellChecker INSTANCE = new SpellChecker();

    public boolean isVaild(String word) {
        // ......
    }

    public String correct() {
        // ......
    }
    // ......
}

class Dictionary {
    // ......
}

这两种方法并不理想,因为他们内部的词典都为final域,实际上词典有很多种,想用一本词典满足所有需求是不切实际的。修改方案为:设DICTIONARY域为nonfinal,并添加一个方法用来修改词典。但是这样修改会显得很笨拙,并且在多线程环境下无法正常工作。

静态工具类和单例类不适合于需要引用底层资源的类

这里需要的是能够创建多个实例,每个实例都使用客户端指定的资源。满足该需求最简单的模式是:

当创建一个新的实例时,就将该资源传到构造器中

这就是依赖注入。

将示例代码改为依赖注入:

public class SpellChecker {

    private final Dictionary dictionary;

    public SpellChecker(Dictionary dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }

    public boolean isVaild(String word) {
        // ......
    }

    public String correct() {
        // ......
    }
    // ......
}

interface Dictionary {
    // ......
}

class ChineseDictionary implements Dictionary {
    // ......
}

class EnglishDictionary implements Dictionary {
    // ......
}

 

依赖注入的一个变体是,将资源工厂传给构造器。实现Supplier接口最适合用于表示工厂。

比如生产一个SpellChecker的方法:

SpellChecker creat(Supplier factory);

 

 

 

 

 

 

你可能感兴趣的:(effective,Java)