Singleton giới hạn class chỉ có đúng 1 instance trong app, cung cấp điểm truy cập toàn cục. Dùng cho: logger, config, DB connection pool, cache.
Các cách implement, từ đơn giản đến tốt nhất:
1. Eager — đơn giản, thread-safe nhờ JVM. Nhược: tạo cả khi không dùng.
private static final Logger INSTANCE = new Logger();
public static Logger getInstance() { return INSTANCE; }**2.
Bill Pugh — initialization-on-demand holder (khuyến nghị):**
private static class Holder { static final Logger INSTANCE = new Logger(); }
public static Logger getInstance() { return Holder.INSTANCE; }Lazy thật sự + thread-safe nhờ JVM + không sync overhead.
3. Enum singleton (tốt nhất theo Effective Java):
public enum Logger { INSTANCE; public void log(String m) {} }
Logger.INSTANCE.log("hi");Chống reflection + serialization attack mặc định. Nhược: không lazy.
Nhược điểm của Singleton:
- Khó test: global state, khó mock — cần mockStatic (chậm).
- Hidden dependency: getInstance() không khai báo phụ thuộc.
- Tight coupling vào concrete class.
2026: dùng DI container (Spring) — bean ngầm singleton scope trong container, vẫn truyền qua constructor injection nên test mock được. Đừng tự viết Singleton trừ khi không có lựa chọn.