![translation](https://cdn.durumis.com/common/trans.png)
Đây là bài viết được dịch bởi AI.
Chọn ngôn ngữ
Văn bản được tóm tắt bởi AI durumis
- Nếu lớp phụ thuộc vào một hoặc nhiều tài nguyên bên trong, nên tránh sử dụng lớp tiện ích tĩnh và lớp singleton, thay vào đó nên sử dụng tiêm phụ thuộc.
- Sử dụng tiêm phụ thuộc có thể cải thiện tính linh hoạt, khả năng tái sử dụng và khả năng kiểm tra của lớp, và tài nguyên có thể được tiêm từ hàm tạo, nhà máy tĩnh, nhà tạo dựng, v.v.
- Tiêm phụ thuộc có thể được sử dụng bằng cách chuyển chính tài nguyên hoặc nhà máy tài nguyên, và trong các dự án có nhiều phụ thuộc, việc sử dụng khung tiêm phụ thuộc là hiệu quả hơn.
Nếu một lớp phụ thuộc vào một hoặc nhiều tài nguyên bên trong và các tài nguyên đó ảnh hưởng đến hành vi của lớp, thì tốt nhất là không sử dụng lớp tiện ích tĩnh hoặc lớp Singleton.
Lớp không nên tự tạo các tài nguyên này, thay vào đó, tốt nhất là chuyển các tài nguyên cần thiết cho lớp tạo trong constructor. Chèn phụ thuộc giúp cải thiện sự linh hoạt, khả năng tái sử dụng và khả năng kiểm tra của lớp.
Ví dụ
Ví dụ về cách sử dụng lớp tiện ích tĩnh
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Logic sử dụng từ điển
}
public static List suggestions(String typo) {
// Logic sử dụng từ điển
}
Lớp tiện ích này giả sử chỉ sử dụng một từ điển. Tuy nhiên, trong thực tế, có thể có nhiều từ điển cho mỗi ngôn ngữ và thậm chí các từ điển riêng biệt cho thuật ngữ chuyên ngành.
Ví dụ về cách sử dụng lớp Singleton
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Logic sử dụng từ điển
}
public static List suggestions(String typo) {
// Logic sử dụng từ điển
}
Lớp Singleton cũng giả sử chỉ sử dụng một từ điển, vì vậy nó gặp phải cùng một nhược điểm như trên.
Giải pháp 1 - Loại bỏ từ khóa final trong trường
public class SpellChecker {
private Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static void changeDictionary(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Logic sử dụng từ điển
}
public static List suggestions(String typo) {
// Logic sử dụng từ điển
}
Bạn có thể loại bỏ từ khóa final khỏi từ điển trong lớp tiện ích tĩnh hoặc lớp Singleton và thiết kế nó để cho phép thay thế từ điển bằng từ điển khác từ bên ngoài. Tuy nhiên, phương pháp này khó sử dụng và có thể dẫn đến vấn đề đồng bộ trong môi trường đa luồng.
Giải pháp 2 - Sử dụng tiêm phụ thuộc
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Logic sử dụng từ điển
}
public static List suggestions(String typo) {
// Logic sử dụng từ điển
}
Thông qua ví dụ trên, bạn có thể nhận thấy rằng lớp tĩnh và lớp Singleton không nên phụ thuộc vào tài nguyên bên trong. Điều này có nghĩa là tài nguyên bên trong tốt hơn là nên được tiêm từ bên ngoài.
Lớp sử dụng tiêm phụ thuộc đảm bảo bất biến nhờ từ khóa final và có lợi thế là hỗ trợ nhiều instance tài nguyên. Ngoài ra, tiêm phụ thuộc có thể được áp dụng cho cả constructor, factory tĩnh và builder.
Tiêm phụ thuộc không chỉ đơn giản là chuyển chính tài nguyên, mà còn thường được sử dụng để chuyển factory tài nguyên. Factory là một đối tượng tạo ra instance của một kiểu cụ thể mỗi khi được gọi. Phương pháp này được gọi là mẫu phương thức Factory và Supplier
public static List create(Supplier extends Car> generator) {
...
Thông thường, kiểu wildcards giới hạn được sử dụng để giới hạn tham số kiểu của factory. Khi sử dụng phương pháp này, client có thể chuyển bất kỳ factory nào là kiểu con của kiểu được chỉ định.
Tiêm phụ thuộc cải thiện tính linh hoạt và khả năng kiểm tra, nhưng có thể khá tốn kém cho các dự án có rất nhiều phụ thuộc. Trong những trường hợp này, bạn có thể sử dụng khung tiêm phụ thuộc (Dagger, Guice, Spring, v.v.) để giảm chi phí.