2009-05-15 24 views
11

Tôi có một số lớp được sử dụng làm Singletons. Họ chia sẻ một số chức năng cơ bản và mở rộng cùng một tổ tiên từ một thư viện mà lần lượt không thường được sử dụng như một Singleton.Làm thế nào tôi có thể có một Singleton có nguồn gốc từ một loại cơ sở trừu tượng trong Java?

Nếu tôi đặt chức năng chung trong một lớp cơ sở kế thừa từ tổ tiên chung, tôi nhận được một lớp không có ý nghĩa để khởi tạo, vì vậy tôi đã làm cho nó trừu tượng. Ngoài ra, vì tất cả các lớp đều được sử dụng như là Singletons, tất cả chúng nên có phương thức init() và getInstance(), cả hai đều là tĩnh. Tất cả các nhà thầu đều không phải là công khai.

Bây giờ, kể từ khi static là một modifier bất hợp pháp cho các phương pháp trừu tượng, sau đây không làm việc, mặc dù điều này sẽ được chính xác những gì tôi muốn:

class Base extends LibraryClass { 
    protected Base() { 
     // ... constructor 
    } 

    // ... common methods 

    // ILLEGAL! 
    public static abstract void init(); 
    public static abstract <T extends Base>T getInstance(); 
} 

class A extends Base { 
    private static A _INSTANCE; 

    private A() { 
     super(); 
    } 

    public static void init() { 
     _INSTANCE = new A(); 
    } 

    public static A getInstance() { 
     return _INSTANCE; 
    } 
} 

Tôi chỉ có thể bỏ qua các dòng bất hợp pháp ở cơ sở và được thực hiện với nó. Nhưng làm thế nào để tôi thể hiện rằng mọi trẻ em của Base phải đều có những phương pháp này?

Trả lời

14

Điều này là không thể trong Java. Không thể thực thi các phương pháp của static; không phải bởi abstract cũng không bằng cách sử dụng interface.

Giải pháp của tôi là sử dụng IoC theo cách: Tôi đã tạo một lớp nhà máy cho người độc thân. Nó sẽ cứu những người độc thân trong một bản đồ. Chìa khóa sẽ là lớp học. Bằng cách này, tôi có thể nói:

A singleton = Factory.create (A.class); 

Ưu điểm chính của thiết kế này: Tôi có thể tạo ra một phương pháp Factory.replace() nơi trường hợp thử nghiệm có thể ghi đè lên độc thân.

+0

Tại sao chúng ta cần Singleton mặc dù chúng ta đã có Static hoặc Final trong Java? sự từ chức chính/nguyên nhân buộc chúng tôi phải chấp nhận "Singleton" thay vì "tĩnh, cuối cùng"? Mặc dù để đạt được Singleton chúng tôi sử dụng tĩnh.Tôi không thể hiểu câu đố này. Vui lòng chuyển nhận xét của bạn. –

+0

tĩnh cuối cùng là cho các hằng số được tạo ra háo hức. Một singleton thường được tạo ra lười biếng (chỉ khi nó là cần thiết). Ngoài ra, tĩnh cuối cùng không cho phép thay thế "hằng số" bằng mockup. Vì vậy, họ làm cho thử nghiệm cứng hoặc thậm chí không thể. –

+0

Xem http://stackoverflow.com/questions/11831/singletons-good-design-or-a-crutch –

2

Bạn không thể biểu thị rằng các lớp con có các phương thức tĩnh cụ thể.

Thực tế không cần phải làm điều này vì các phương thức tĩnh sẽ chỉ được gọi trực tiếp trên các lớp con (A.init()A.getInstance() trong ví dụ của bạn) và không bao giờ tham chiếu đến lớp cơ sở (tức là phương pháp tĩnh không hỗ trợ đa hình).

1

Tại sao bạn không đi tất cả các cách và làm cho nhà máy của bạn (trong lớp cơ sở) vượt qua trong một tham số cho biết lớp phụ bạn muốn nó quay trở lại. Có rất nhiều lợi thế để thực hiện theo cách đó và một số nhược điểm.

Cách bạn đang cố gắng thực hiện điều đó không có nhiều ý nghĩa vì các phương pháp tĩnh không xử lý thừa kế theo cách tương tự như các phương thức thông thường.

3

Một cách phổ biến để giải quyết việc thêm ngữ nghĩa singleton vào một lớp mà nó có thể bất tiện khi thêm ngữ nghĩa một cách chính xác là triển khai thực hiện hàm singleton trong lớp trình bao bọc. Ví dụ:

public class UsefulThing { 

} 

public final class SingletonOfUsefulThing { 
    private static UsefulThing instance; 

    private SingletonOfUsefulThing() {} 

    public UsefulThing getInstance() { 
     if (instance == null) { 
      instance = new UsefulThing(); 
     } 

     return instance; 
    } 
} 

này cho phép bạn để cung cấp cho một số lợi ích singleton tiểu học đến một lớp học mà không cần một số những hậu quả mà việc thực hiện các ngữ nghĩa singleton trong lớp trực tiếp buộc bạn phải đối phó với và cho phép một số phòng để thay đổi loại cụ thể của lớp bạn đang trưng bày như một singleton (thông qua việc sử dụng một nhà máy để tạo cá thể, ví dụ, thay vì new.

+0

Tôi đoán phương thức 'getInstance()' của bạn phải là 'static'. – Koen

Các vấn đề liên quan