Đang tải...

Bài 5: Ưu tiên dependency injection thay vì hardcode resource

08/06/2026
4 phút đọc
Bài 5: Ưu tiên dependency injection thay vì hardcode resource
## Bad practice thường gặp (làm theo hướng cũ) ```java public class SpellChecker { private final Lexicon dictionary = new FileLexicon("/etc/dict.txt"); public boolean isValid(String word) { ...

Bad practice thường gặp (làm theo hướng cũ)

public class SpellChecker {
 private final Lexicon dictionary = new FileLexicon("/etc/dict.txt");

 public boolean isValid(String word) {
 return dictionary.contains(word);
 }
}

Vấn đề của cách này:

  • SpellChecker bị khóa cứng vào FileLexicon.
  • Khó test vì không thể thay bằng mock/fake dependency.
  • Đổi nguồn dữ liệu là phải sửa code class lõi.

Khi một class phụ thuộc vào một resource (ví dụ: dictionary, config source, database client, clock), đừng hardcode resource đó vào bên trong class hoặc buộc class tự tạo resource. Thay vào đó, hãy truyền dependency từ bên ngoài vào (dependency injection), thường qua constructor.

Vì sao cách hardcode dễ gây vấn đề

  • Class trở nên kém linh hoạt: chỉ dùng được với đúng một implementation.
  • Khó test: không thể thay bằng mock hoặc fake dependency.
  • Dễ vi phạm single responsibility: class vừa xử lý nghiệp vụ vừa tự quản lý vòng đời resource.
  • Khó mở rộng: khi cần đổi behavior theo môi trường (dev/staging/prod) phải sửa code lõi.

Cách làm đúng

  • Thiết kế class nhận dependency qua constructor.
  • Dùng interface hoặc type abstraction cho dependency thay vì bám chặt implementation cụ thể.
  • Validate input trong constructor (ví dụ Objects.requireNonNull(...)) để fail fast.
  • Với dependency nặng hoặc tốn tài nguyên, để composition root (hoặc DI container) quản lý lifecycle.

Ví dụ Java

import java.util.*;

public class SpellChecker {
 private final Lexicon dictionary;

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

 public boolean isValid(String word) {
 return dictionary.contains(word);
 }

 public List<String> suggestions(String typo) {
 return dictionary.suggest(typo);
 }
}

interface Lexicon {
 boolean contains(String word);
 List<String> suggest(String typo);
}

Ý chính của ví dụ:

  • SpellChecker không biết dependency đến từ đâu.
  • Bạn có thể truyền InMemoryLexicon, FileLexicon, hoặc RemoteLexicon tùy ngữ cảnh.
  • Unit test có thể truyền fake implementation rất nhẹ.

Khi nào dùng DI framework

  • Dự án nhỏ: constructor injection thủ công là đủ, rõ ràng và dễ đọc.
  • Dự án lớn: dùng framework (Spring, Guice, Dagger, ...) giúp wiring dependency tự động.
  • Dù dùng framework, tư duy cốt lõi vẫn là: dependency đi từ ngoài vào class.

Những sai lầm phổ biến

  • Dùng global singleton cho mọi thứ để “tiện”, khiến test khó và state khó kiểm soát.
  • Lạm dụng service locator thay cho dependency injection thật sự.
  • Inject quá nhiều dependency vào một class (dấu hiệu class đang ôm quá nhiều trách nhiệm).

Checklist áp dụng nhanh

  • Class của mình có đang new trực tiếp dependency chính không?
  • Có thể thay dependency bằng interface không?
  • Constructor đã kiểm tra null chưa?
  • Unit test có thể inject fake/mock dependency mà không cần môi trường thật không?

Tóm lại: dependency injection làm code modular hơn, testable hơn và dễ thay đổi hơn nhiều so với hardcode resource.

📚 Nguồn: Viblo

Bình luận

0 bình luận

Email không hiển thị công khai.

Chưa có bình luận nào. Hãy là người đầu tiên bình luận.

Chia sẻ bài viết

Cần tư vấn?

Liên hệ với chúng tôi để được hỗ trợ

Liên hệ ngay

Bài viết liên quan

Proxy hoạt động ở tầng nào trong mô hình TCP/IP? HTTP Proxy Và SOCKS5 nằm ở đâu?
09/06/2026

Proxy hoạt động ở tầng nào trong mô hình TCP/IP? HTTP Proxy Và SOCKS5 nằm ở đâu?

Proxy hoạt động ở tầng nào? Sau khi đã đi qua các tầng mạng như Physical Layer, Data Link Layer, Internet Layer, Transport Layer và Application Layer, ta có thể nhìn Proxy rõ ...

Đọc thêm
Red Team RAG: Khi mỗi pipeline là một đường hầm tối – Phần 2: Đầu độc dòng chảy – Từ ingestion đến sụp đổ
09/06/2026

Red Team RAG: Khi mỗi pipeline là một đường hầm tối – Phần 2: Đầu độc dòng chảy – Từ ingestion đến sụp đổ

## Lời mở đầu: Bạn đã vào hầm. Bây giờ, hãy đầu độc dòng nước. Ở phần 1, chúng ta đã đứng trước **cửa hầm**, học cách đọc bản đồ pipeline RAG, v...

Đọc thêm
Vì sao giá trị truyền thống luôn được đặt lên hàng đầu
09/06/2026

Vì sao giá trị truyền thống luôn được đặt lên hàng đầu

Giá trị truyền thống không chỉ là yếu tố mang tính hoài niệm, mà còn đóng vai trò nền tảng trong việc định hình bản sắc và chiều sâu của một công trình ...

Đọc thêm

Bắt đầu dự án của bạn

Hãy để Flash Dev đồng hành cùng bạn

Liên hệ ngay