Cách tiếp cận tốt nhất để sử dụng Enum như một singleton trong Java là gì?


85

Xây dựng dựa trên những gì đã được viết trong câu hỏi SO Triển khai Singleton tốt nhất trong Java - cụ thể là về việc sử dụng enum để tạo một singleton - sự khác biệt / ưu / nhược điểm giữa (phương thức khởi tạo bị bỏ qua)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

và sau đó gọi Elvis.INSTANCE.getAge()

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

và sau đó gọi Elvis.getAge()

Câu trả lời:


96

Giả sử bạn đang liên kết với một thứ gì đó sẽ sử dụng các thuộc tính của bất kỳ đối tượng nào mà nó được cung cấp - bạn có thể vượt qua Elvis.INSTANCE rất dễ dàng, nhưng bạn không thể vượt qua Elvis.class và mong đợi nó tìm thấy thuộc tính (trừ khi nó được mã hóa cố tình để tìm thuộc tính tĩnh của các lớp).

Về cơ bản, bạn chỉ sử dụng mẫu singleton khi bạn muốn một thể hiện. Nếu các phương thức tĩnh hoạt động tốt với bạn, thì chỉ cần sử dụng những phương thức đó và đừng bận tâm đến enum.


1
Tại sao không bận tâm với enum? Có cách nào tốt hơn để thực hiện singeltons trong java5 + không?
jontro

4
@jontro (lại) đọc câu trả lời; ông nói để sử dụng enums khi bạn phải có một singleton nhưng để tránh singleton nếu bạn có thể làm gì với phương pháp tĩnh
Biến khốn khổ

@MiserableVariable Tôi đã nhận xét về điều này hơn một năm trước. Cant thực sự nhớ bối cảnh mà tôi đang đề cập đến.
jontro

không trả lời câu hỏi hỏi
Thufir

2
@Thufir: Nó trả lời phần "sự khác biệt là gì" - có vẻ là điều mà OP quan tâm nhất, vì câu trả lời đã được chấp nhận.
Jon Skeet

69

Một lợi thế lớn là khi singleton của bạn phải cài đặt một giao diện. Theo ví dụ của bạn:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

Với:

public interface HasAge {
    public int getAge();
}

Nó không thể được thực hiện với tĩnh ...


1
Nó có thể được thực hiện với statics ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {return age; }}; ... vì vậy tôi vẫn đang tự hỏi điều gì là tốt hoặc tốt hơn về phương pháp enum. Tôi cho rằng nếu bạn cần thực hiện hai giao diện?
Sean Adkinson

9

(Trạng thái) Singleton thường được sử dụng để giả vờ không sử dụng các biến tĩnh. Nếu bạn không thực sự sử dụng biến tĩnh công khai thì bạn sẽ đánh lừa được ít người hơn.


8

Tôi sẽ chọn tùy chọn đơn giản nhất và rõ ràng nhất. Điều này hơi chủ quan, nhưng nếu bạn không biết điều gì rõ ràng nhất, hãy chọn lựa chọn ngắn nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.