2012-04-02 35 views
11

Cách quyết định khi nào nên sử dụng bộ điều hợp đối tượng và khi nào sử dụng bộ điều hợp lớp?Sự khác biệt giữa mẫu bộ điều hợp đối tượng và mẫu bộ điều hợp lớp

Tuyên bố sự cố: Để tạo trang web mạng xã hội và cung cấp chức năng nhập từ facebook, google plus và orkut. Tôi không thể quyết định có nên sử dụng bộ điều hợp đối tượng hoặc bộ điều hợp lớp hay không.

Tôi đã xem Adapter Pattern: Class Adapter vs Object Adapter, nhưng không thể hiểu được bản chất của sự khác biệt. bộ chuyển đổi

Trả lời

24

Sự khác biệt chính:

  • Lớp Adaptor sử dụng thừa kế và chỉ có thể quấn một lớp. Nó không thể bao bọc một giao diện vì theo định nghĩa nó phải xuất phát từ một số lớp cơ sở.

  • Object Adaptor sử dụng phần và có thể bọc lớp hoặc giao diện, hoặc cả hai. Nó có thể làm điều này vì nó chứa, như một thành viên riêng, đóng gói, lớp hoặc giao diện đối tượng dụ nó kết thúc tốt đẹp.

Sự khác biệt là tinh tế. Thông thường các phương pháp sau (ưu composition over inheritance) là một lợi thế như được giải thích trong liên kết mà tôi sẽ trích dẫn ở đây:

thí sinh Object-Oriented Lập trình (OOP) đã quá nổi tiếng với các tái sử dụng các chức năng: Thừa kế (tái sử dụng whitebox) và Thành phần (tái sử dụng hộp đen). Nếu bạn cố gắng sử dụng lại mã bằng cách kế thừa từ một lớp , bạn sẽ làm cho phân lớp phụ thuộc vào lớp cha. Điều này làm cho hệ thống trong nhiều trường hợp không cần thiết phức tạp, ít có thể kiểm tra và làm cho việc trao đổi chức năng tại thời gian chạy không cần thiết khó khăn. Với tư cách là [Nhà phát triển mã sạch] , bạn nên thực hiện theo số Liskov Substitution Principle (LSP) khi bạn cần quyết định xem kế thừa có phù hợp hay không.

Thành phần có nghĩa là một lớp sử dụng một lớp khác. Bạn sẽ tiếp tục quảng bá tách bằng cách xác định giao diện rõ ràng. Điều đó cũng sẽ cung cấp cho bạn lợi thế là việc triển khai có thể dễ dàng được thay thế. Vì vậy, trước khi bạn bắt đầu áp dụng nguyên lý thay thế Liskov, hãy suy nghĩ về khái niệm Thành phần ưu tiên thừa kế và yêu cầu yourselve lý do tại sao bạn không nên thích bố cục ngay lập tức.

"Vì thừa kế cho thấy một lớp con với các chi tiết về việc thực hiện của phụ huynh, nó thường được nói rằng 'phá vỡ kế thừa đóng gói'".(Gang of Four 1995: 19)

4

Object:

$Adapter = new MyEngine(new MyAdapter($options)); 
$Adapter->write('something'); 

Adaptor Lớp

MyAdapter extends BaseAdapter implements AdapterInterface { ... } 
$Adapter = new MyAdapter($options); 
$Adapter->write('something'); 
1

Một bộ chuyển đổi lớp sử dụng nhiều thừa kế để thích nghi với một giao diện khác: (tùy thuộc vào ngôn ngữ lập trình của bạn: Java & C# không hỗ trợ đa kế thừa)

enter image description here

Một adapter đối tượng phụ thuộc vào thành phần đối tượng:

enter image description here

hình ảnh S ource: Thiết kế mẫu (Các yếu tố của Reusable Software Object-Oriented) cuốn sách

4

Nói cách đơn giản, Lớp Adaptor sử dụng subclassing và Object Adaptor sử dụng đoàn bằng cách sử dụng thành phần.

Ví dụ:

class MyExistingServiceClass { 
    public void show() { 
     System.out.println("Inside Service method show()");   
    } 
} 

interface ClientInterface { 
    void display(); 
} 

class MyNewClassAdapter extends MyExistingServiceClass implements ClientInterface { 
    void display() { 
     show(); 
    } 
} 

Trên đây là một ví dụ về lớp Adapter. Chúng tôi đã điều chỉnh MyExistingServiceClass thành ClientInterface bằng cách gọi phương thức show() hiện có từ bên trong thực hiện display().

Để chuyển đổi này để phản đối bộ chuyển đổi, mã sẽ như thế nào:

class MyNewObjectAdapter implements ClientInterface { 

    MyExistingServiceClass existingClassObject; 

    void display() { 
     existingClassObject.show(); 
    } 
} 

Bây giờ khi sử dụng bộ chuyển đổi đối tượng ở vị trí của lớp Adatper,

  1. Khi không có cách nào để phân lớp lớp học sẽ được điều chỉnh theo giao diện của khách hàng. Ví dụ như, khi MyExistingServiceClass được khai báo là cuối cùng.

  2. Khi khách hàng mong đợi một hợp đồng không phải là inteface mà là triển khai lớp trừu tượng. Trong trường hợp này, chúng ta không có cách nào khác hơn là phân lớp lớp mong đợi của máy khách và vì chúng ta không thể phân lớp nhiều hơn một lớp, không có cách nào khác ngoài việc sử dụng lớp để thích nghi như một thành phần.

    abstract class AbstractClientClass { 
        abstract void display(); 
    } 
    
    class MyNewObjectAdapter extends AbstractClientClass { 
    
        MyExistingServiceClass existingClassObject; 
    
        void display() { 
         existingClassObject.show(); 
        } 
    } 
    
  3. Khi bạn cần điều chỉnh nhiều đối tượng. Trường hợp như vậy là khi bạn không trực tiếp làm việc với đối tượng để được điều chỉnh. Một ví dụ điển hình ở đây sẽ là lớp JTable trong javax.swing. Lớp này tạo ra một thành phần bảng GUI (giao diện người dùng đồ họa) chứa đầy thông tin mà bộ điều hợp của bạn cung cấp cho nó. Để hiển thị dữ liệu từ miền của bạn, JTable cung cấp các hàm tạo chấp nhận một cá thể của TableModel được định nghĩa trong javax.swing.table. JDK cung cấp một triển khai trừu tượng hiện có của TableModel với AbstractTableModel.

    class MyTableModel extends AbstractTableModel { 
    
    MyDomainObject[] existingDomainObjects[]; 
    
    public int getColumnCount() { 
        return 4; 
    } 
    
    public int getRowCount() { 
        return existingDomainObjects.length(); 
    } 
    
    public MyDomainObject getValueAt(int i) { 
        return existingDomainObjects[i]; 
    } 
    } 
    

Ở đây, chúng tôi đã thích nghi MyDomainObject để được sử dụng với AbstractTableModel.

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