Constructor Injection in Alibaba Java Code Guideline

In the Alibaba Java Code Guideline, it is recommended to use constructor injection to handle dependencies in your code. Constructor injection is a type of dependency injection where dependencies are provided through a class's constructor. This approach promotes loose coupling between classes and makes it easier to test and maintain your code.

Why use Constructor Injection?

Using constructor injection has several benefits:

  1. Explicit Dependencies: With constructor injection, dependencies are clearly defined in the class's constructor. This makes it easier to see what the class depends on and how it is used.

  2. Immutable Dependencies: Once set in the constructor, dependencies cannot be changed or modified. This helps prevent unexpected behavior and makes classes more stable.

  3. Testability: Constructor injection makes it easier to write unit tests for your classes. By providing mock dependencies in the constructor, you can test a class in isolation without relying on external resources.

  4. Flexibility: Constructor injection allows you to easily switch out dependencies by passing in different implementations at runtime. This makes your code more flexible and adaptable to changes.

How to Use Constructor Injection

Let's look at an example to see how constructor injection can be implemented in Java code:

public class UserService {
    private UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void addUser(User user) {
        userRepository.save(user);
    }
}

public interface UserRepository {
    void save(User user);
}

In the UserService class, the UserRepository dependency is passed in through the constructor. This allows the UserService to access the UserRepository without creating a tight coupling between the two classes.

To use the UserService class, you can create an instance of it and pass in a concrete implementation of the UserRepository interface:

public class Main {
    public static void main(String[] args) {
        UserRepository userRepository = new MySQLUserRepository();
        UserService userService = new UserService(userRepository);

        userService.addUser(new User("Alice"));
    }
}

In the above example, we create an instance of MySQLUserRepository and pass it to the UserService constructor. This way, the UserService class can interact with the database through the UserRepository interface without needing to know the specific implementation.

Sequence Diagram

sequenceDiagram
    participant Main
    participant UserService
    participant UserRepository

    Main->>UserService: userService.addUser(new User("Alice"))
    UserService->>UserRepository: userRepository.save(user)

The sequence diagram above shows how the Main class interacts with the UserService and UserRepository classes through constructor injection.

ER Diagram

erDiagram
    USER ||--o| USER_REPOSITORY : has

The entity-relationship diagram above illustrates the relationship between the USER and USER_REPOSITORY entities.

Conclusion

Constructor injection is a powerful technique for managing dependencies in your Java code. By following the Alibaba Java Code Guideline and using constructor injection, you can write more modular, testable, and maintainable code. It encourages good design practices and helps you build robust and flexible applications. So next time you're working on a Java project, consider using constructor injection to improve your code quality and make your life as a developer easier.