5. Effective Java Version III-using dependency injection instead of hard-connected resources

Source: Internet
Author: User

Tips
"Effective Java, third Edition" an English version has been published, the second edition of this book presumably many people have read, known as one of the four major Java books, but the second edition of 2009 published, to now nearly 8 years, but with Java 6, 7, 8, and even 9 of the release, the Java language has undergone profound changes.
In the first time here translated into Chinese version. For everyone to learn to share.

5. Replacing hard-connected resources with Dependency injection (hardwiring Resource)

Many classes depend on one or more underlying resources. For example, the spelling checker relies on dictionaries. It is not uncommon to implement such classes as static utility classes (entry 4):

// Inappropriate use of static utility - inflexible & untestable!public class SpellChecker {    private static final Lexicon dictionary = ...;    private SpellChecker() {} // Noninstantiable    public static boolean isValid(String word) { ... }    public static List<String> suggestions(String typo) { ... }}

Similarly, it is not uncommon to implement them as a singleton (entry 3):

// Inappropriate use of singleton - inflexible & untestable!public class SpellChecker {    private final Lexicon dictionary = ...;    private SpellChecker(...) {}    public static INSTANCE = new SpellChecker(...);    public boolean isValid(String word) { ... }    public List<String> suggestions(String typo) { ... }}

Neither of these methods is satisfactory, as they assume that only one dictionary is worth using. In practice, each language has its own dictionary, and special dictionaries are used for special glossaries. In addition, it is advisable to use a specialized dictionary for testing. It is wishful thinking to assume that a dictionary is enough.

You can dictionary make the spelling checker support multiple dictionaries by setting the property to non and final adding a method to change the dictionary in the existing spelling checker, but in a concurrency environment, this is clumsy, error-prone, and infeasible. static utility classes and Singleton are inappropriate for classes whose behavior is parameterized by the underlying resource .

What is needed is the ability to support multiple instances of a class (in our example, that is SpellChecker ), each using the resources expected by the client (in our case dictionary ). A simple pattern that satisfies this requirement is to pass the resource into the constructor method when creating a new instance. This is a form of dependency injection (Dependency injection): A dictionary is a dependency of the spelling checker that is injected into the spelling checker when it is created.

// Dependency injection provides flexibility and testabilitypublic class SpellChecker {    private final Lexicon dictionary;    public SpellChecker(Lexicon dictionary) {        this.dictionary = Objects.requireNonNull(dictionary);    }    public boolean isValid(String word) { ... }    public List<String> suggestions(String typo) { ... }}

Dependency Injection mode is very simple and many programmers use it for years without knowing that it has a name. Although our spelling checker example has only one resource (dictionary), dependency injection can use any number of resources and arbitrary dependency graphs. It retains immutability (entry 17), so multiple clients can share dependent objects (assuming the customer needs the same underlying resources). Dependency Injection also applies to construction methods, static factories (entry 1), and builder mode (entry 2).

A useful variant of this pattern is to pass the resource factory to the constructor method. A factory is an object that can be called repeatedly to create instances of a type. This factory embodies the factory method pattern (Factory mode) [Gamma95]. The interfaces introduced in Java 8 Supplier <T> are ideal for representing factories. The method used on Supplier<T> the input should normally use the bounded wildcard type (bounded wildcard type) (entry 31) to constrain the factory's type parameters to allow the client to pass in to the factory and create any subtypes of the specified type. For example, here's a way to generate tiles using the client-provided factory:
Mosaic create(Supplier<? extends Tile> tileFactory) { ... }

Although dependency injection greatly improves flexibility and testability, it can confuse large projects, which typically contain thousands of of dependencies. Use a Dependency injection framework (such as Dagger[dagger], Guice[guice], or spring[spring]) to eliminate these clutter. The use of these frameworks is beyond the scope of this book, but be aware that APIs designed for manual dependency injection are well suited to the use of these frameworks.

In summary, do not use a singleton or static utility class to implement a class that relies on one or more underlying resources that behave in a class that affects the behavior of classes, and does not allow classes to create these resources directly. Instead, pass the resource or factory to the construction method (or static factory or builder mode). This practice, called Dependency Injection, will greatly enhance the flexibility, reusability, and testability of classes.

5. Effective Java Version III-using dependency injection instead of hard-connected resources

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.