2013-02-15 23 views
6

Tôi đang cố che giấu việc triển khai lớp mà tôi không sở hữu. Tôi muốn làm điều này để mở rộng lớp và triển khai giao diện của riêng mình. Đây là cách thể hiện một lớp của lớp tôi cần:Java OO: Điều này có khả thi không?

QueueInfo info = admin.getQueue(queueName); 

QueueInfo là lớp tôi không sở hữu. Để có được một thể hiện của đối tượng này, tôi phải sử dụng một đối tượng quản trị để có được nó. Tôi muốn ẩn việc triển khai này bằng cách làm việc thông qua một giao diện có tên IQueueInfo. IQueueInfo sẽ chỉ cung cấp quyền truy cập vào những gì người tiêu dùng cần từ QueueInfo. Vì vậy, để có được tại QueueInfo này, tôi muốn làm việc thông qua đối tượng của riêng tôi được gọi là EMSQueueInfo. Dưới đây là làm thế nào tôi đã hình dung thiết lập này:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo { 
    //... 
} 

Điều này cho phép người tiêu dùng của mình để làm việc mặc dù giao diện IQueueInfo và nó cho phép các EMSQueueInfo cơ bản để có quyền truy cập vào tất cả mọi thứ QueueInfo có. Vấn đề của tôi nằm với việc nhận một thể hiện "live" của QueueInfo. Để có được một phiên bản thường xuyên của QueueInfo, tôi chỉ có thể nói:

QueueInfo info = new QueueInfo(queueName); 

Ví dụ này không phải là "trực tiếp" vì nó không được tạo bởi đối tượng quản trị. Vì vậy, thực hiện việc này:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo { 

    public EMSQueueInfo(String queueName){ 
     super(queueName); 
    } 

} 

không cho tôi đối tượng "hoạt động". Những gì tôi muốn có thể làm là một cái gì đó như thế này:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo { 

    public EMSQueueInfo(String queueName, Admin admin){ 
     super = admin.getQueue(queueName); 
    } 

} 

Nhưng điều đó là không thể.

Giải pháp duy nhất tôi nhìn thấy được tháo kéo dài từ lớp EMSQueueInfo của tôi và chỉ gói các đối tượng lên bản thân mình, nhận được quyền truy cập vào tất cả các phương pháp thông qua một varialbe tin:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo { 

    private QueueInfo _queueInfo 

    public EMSQueueInfo(String queueName, Admin admin){ 
     _queueInfo = admin.getQueue(queueName); 
    } 

    public int getMessagesOnQueue() { 
     return _queueInfo.getMessagesOnQueue(); 
    } 

} 

giải pháp đó không làm việc nhưng tôi ghét nó. Bất cứ ai có thể nghĩ ra một cách tốt hơn? Tôi chỉ đang cố gắng phá vỡ OO và lạm dụng nó? Một lần nữa, tôi chỉ làm tất cả những điều này bởi vì tôi muốn người tiêu dùng có thể làm việc với IQueueInfo, trong tương lai, IQueueInfo có thể được sử dụng để truy cập vào việc thực hiện JMS của QueueInfo hoặc thực thi MSQQ của QueueInfo. Bất kỳ trợ giúp sẽ là tuyệt vời!

+0

Tôi sẽ cảnh giác với việc mở rộng lớp bạn đang cố gắng ẩn. Tôi không thấy vấn đề với bố cục. –

+0

Phương thức nhà máy của Google – Bohemian

+0

Bạn đã mô tả mẫu 'Adapter': bạn quấn một thứ gì đó để chỉ cho phép truy cập vào một số phần nhất định của nó. Vì vậy, bạn ** muốn ** rằng queueInfo được ẩn. Nếu không, mọi người sẽ có thể truy cập tất cả các trường trên đó và không chỉ những trường bạn muốn. –

Trả lời

5

Những gì bạn đã đề xuất có vẻ hoàn toàn hợp lý - được gọi là mẫu bộ điều hợp (cảm ơn Martinsos).

Sẽ đẹp hơn nếu bạn có thể ẩn đối tượng Admin trong lớp của mình bằng cách nào đó. Ví dụ.

public class EMSQueueInfo implements QueueInfoProvider { 

    private static Admin admin = new Admin(); 
    private QueueInfo queueInfo 

    public EMSQueueInfo(String queueName){ 
     queueInfo = admin.getQueue(queueName); 
    } 

    public int getMessagesOnQueue() { 
     return queueInfo.getMessagesOnQueue(); 
    } 

} 

Tôi đã cố gắng cung cấp cho giao diện của bạn thêm một tên "Java". Hậu tố I rất .NET. Không cần phải mở rộng lớp gốc.

Nó có thể cảm thấy đau đớn để thực hiện khi bạn phải chăm sao chép chỉ các phương pháp thú vị từ QueueInfo vào QueueInfoProvider của bạn, nhưng cơn đau sẽ được giá trị nó cuối cùng.

Cách tiếp cận này tách riêng ứng dụng của bạn khỏi API mà bạn không có quyền kiểm soát trực tiếp. Theo nghĩa đó, nó tương tự như Facade pattern.

+1

Xin lỗi, tôi đến từ .NET. Một lần nữa, tôi không muốn quấn cả lớp. Cách tiếp cận trên là những gì tôi tránh. getMessagesOnQueue đã là một phần của QueueInfo. –

+0

Tốt thôi. Với thiết kế này, bạn có thể chọn phương pháp để bọc. Nếu nó chỉ là một, đó là tốt. –

+0

Tôi nghĩ rằng bạn là chính xác. Tôi chỉ cảm thấy một chút bẩn có phải viết lại tất cả mọi thứ khi mở rộng các lớp cảm thấy như đúng cách để làm điều đó. –

6

Tôi tin rằng giải pháp bạn đang sử dụng mà bạn nói rằng bạn ghét là một giải pháp tốt. Nó không phá vỡ OO hoặc lạm dụng nó.

Những gì bạn đang làm là mẫu nổi tiếng được gọi là Adapter pattern (Object Adapter pattern). Chỉ có điều không cần thiết trong lớp của bạn là mở rộng QueueInfo.

+0

Câu trả lời của bạn cũng chính xác. Lý do duy nhất tôi chấp nhận Duncan của bạn là vì anh ấy cũng cung cấp một ví dụ mã tốt. Cảm ơn bạn đã nhập liệu! –

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