Sự khác biệt giữa mẫu cầu và mẫu bộ điều hợp


125

Sự khác biệt giữa các mẫu cầu và bộ điều hợp là gì?


Có lẽ xem xét việc cung cấp một chỉnh sửa làm rõ để hướng dẫn cuộc thảo luận về nơi bạn tin rằng bạn cần sử dụng cái này hay cái khác.
Jeff Wilcox


Không có lời giải thích nào ở đây sẽ thay thế việc đọc các Mẫu thiết kế: Các yếu tố của phần mềm hướng đối tượng có thể tái sử dụng
lealceldeiro

Câu trả lời:


173

"Bộ điều hợp làm cho mọi thứ hoạt động sau khi chúng được thiết kế; Bridge làm cho chúng hoạt động trước khi chúng hoạt động. [GoF, p219]"

Thực tế, mẫu Adaptor rất hữu ích khi bạn có mã hiện tại, có thể là bên thứ ba hoặc trong nhà, nhưng ngoài tầm kiểm soát của bạn hoặc không thể thay đổi để đáp ứng hoàn toàn giao diện bạn cần. Chẳng hạn, chúng ta có SuperWeaponsArray có thể điều khiển một loạt các thiết bị ngày tận thế.

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}

Tuyệt quá. Ngoại trừ chúng tôi nhận ra rằng chúng tôi có một thiết bị hạt nhân trong kho vũ khí của chúng tôi trước khi chuyển đổi sang giao diện Weapon. Nhưng chúng tôi thực sự muốn nó hoạt động ở đây ... vậy chúng tôi làm gì ... nêm nó vào!

NukeWeaponsAdaptor - dựa trên lớp Nuke của chúng tôi, nhưng xuất giao diện Weapon. Ngọt ngào, bây giờ chúng ta chắc chắn có thể phá hủy thế giới. Nó có vẻ giống như một chút bùn, nhưng nó làm cho mọi thứ hoạt động.


Mẫu cầu là thứ bạn triển khai trước - nếu bạn biết bạn có hai cấu trúc phân cấp trực giao, nó cung cấp một cách để tách rời giao diện và cách triển khai theo cách mà bạn không có được số lượng lớp điên rồ. Hãy nói rằng bạn có:

Các loại đối tượng tệp MemoryMappedFile và DirectReadFile. Giả sử bạn muốn có thể đọc các tệp từ nhiều nguồn khác nhau (Có thể là Linux so với triển khai Windows, v.v.). Cầu giúp bạn tránh quanh co với:

Bộ nhớMappedWindowsFile Bộ nhớMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile


9
hạ cấp, bạn có thể sử dụng một danh sách mã trừu tượng hơn? ví dụ quá cụ thể và khó hiểu

36
@omouse upvote, ví dụ thực sự không phải là những gì làm cho câu trả lời này đến điểm. Đối với người đọc cẩn thận, có đủ con trỏ để bắt đầu phân biệt các mẫu, vì vậy tất cả trong tất cả - đó một câu trả lời tốt.
Victor Farazdagi

15
bạn có thể cung cấp một số ví dụ mã thực tế cho mẫu cầu?
Jaime Hablutzel

2
Tôi tưởng tượng nhiều người đến câu hỏi này giống như tôi đã làm - có lẽ họ đã xem mã cho hai mẫu, nhưng nhận ra một số điểm tương đồng và nhận ra sự hiểu biết của họ có thể được củng cố thêm bằng cách ghép hai mẫu. Dòng về cầu nối giúp bạn tránh gặp khó khăn với các tệp cụ thể của Windows và Linux, ít nhất là đối với tôi, là công cụ để hiểu "Trình triển khai" của Bridge Pattern ( dofactory.com/net/bridge-design-potype ) khác với "Bộ chuyển đổi".
Jordan

3
"Bộ điều hợp làm cho mọi thứ hoạt động sau khi chúng được thiết kế; Bridge làm cho chúng hoạt động trước khi chúng hoạt động." không được chỉ định trong cuốn sách tôi đọc, vì vậy thật khó để phân biệt hai cuốn sách này. Tôi đoán đọc GOF là giá trị nỗ lực sau tất cả ...
Alexander Derck

15

http://en.wikipedia.org/wiki/AdOG_potype

Mẫu Adaptor liên quan nhiều hơn đến việc giúp mã hiện tại của bạn hoạt động với hệ thống hoặc giao diện mới hơn.

Nếu bạn có một bộ API dịch vụ web tiêu chuẩn của công ty mà bạn muốn cung cấp cho giao diện mở rộng hiện có của ứng dụng khác, bạn có thể cân nhắc viết một bộ các bộ điều hợp để thực hiện việc này. Lưu ý rằng có một khu vực màu xám và đây là về cách bạn xác định kỹ thuật mẫu, vì các mẫu khác như mặt tiền là tương tự nhau.

http://en.wikipedia.org/wiki/Bridge_potype

Mẫu cầu sẽ cho phép bạn có thể có các triển khai thay thế của thuật toán hoặc hệ thống.

Mặc dù không phải là một ví dụ mẫu cầu cổ điển, hãy tưởng tượng nếu bạn có một vài triển khai của kho lưu trữ dữ liệu: một là hiệu quả trong không gian, một là hiệu quả về hiệu suất thô ... và bạn có một trường hợp kinh doanh để cung cấp cả trong ứng dụng hoặc khung của bạn .

Về câu hỏi của bạn, "nơi tôi có thể sử dụng mẫu nào", câu trả lời là, bất cứ nơi nào nó có ý nghĩa cho dự án của bạn! Có lẽ xem xét việc cung cấp một chỉnh sửa làm rõ để hướng dẫn cuộc thảo luận về nơi bạn tin rằng bạn cần sử dụng cái này hay cái khác.


14

Bộ chuyển đổi:

  1. Nó là một mô hình cấu trúc
  2. Nó rất hữu ích để làm việc với hai giao diện không tương thích

Sơ đồ UML: từ bài viết dofactory :

nhập mô tả hình ảnh ở đây

Target : xác định giao diện miền cụ thể mà Client sử dụng.

Bộ điều hợp: điều chỉnh giao diện Adaptee với giao diện Target.

Adaptee : định nghĩa một giao diện hiện có cần điều chỉnh.

Máy khách : cộng tác với các đối tượng phù hợp với giao diện Target.

Thí dụ:

Hình vuông và Hình chữ nhật là hai hình dạng khác nhau và diện tích () của mỗi hình này đòi hỏi các phương pháp khác nhau. Nhưng Square vẫn hoạt động trên giao diện Hình chữ nhật với việc chuyển đổi một số thuộc tính.

public class AdapterDemo{
    public static void main(String args[]){
        SquareArea s = new SquareArea(4);
        System.out.println("Square area :"+s.getArea());
    }
}

class RectangleArea {
    public int getArea(int length, int width){
        return length * width;
    }
}

class SquareArea extends RectangleArea {

    int length;
    public SquareArea(int length){
        this.length = length;
    }
    public int getArea(){
        return getArea(length,length);
    }
}

Cầu:

  1. Đó là mô hình cấu trúc
  2. nó tách rời sự trừu tượng khỏi việc thực hiện và cả hai có thể thay đổi độc lập
  3. Có thể vì thành phần đã được sử dụng thay cho thừa kế

EDIT: (theo đề xuất của @quasoft)

Bạn có bốn thành phần trong mô hình này.

  1. Trừu tượng : Nó xác định một giao diện

  2. Tinh chỉnh Hoạt động : Nó thực hiện trừu tượng hóa:

  3. Người triển khai : Nó xác định một giao diện để thực hiện

  4. ConcreteImcellencor : Nó thực hiện giao diện Triển khai.

Đoạn mã:

Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();

gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();

Bài liên quan:

Khi nào bạn sử dụng Mẫu cầu? Nó khác với mẫu Adaptor như thế nào?

Sự khác biệt chính: từ bài viết chua

  1. Bộ điều hợp làm cho mọi thứ hoạt động sau khi chúng được thiết kế; Cầu làm cho họ làm việc trước khi họ đang có.
  2. Cầu được thiết kế lên phía trước để cho sự trừu tượng và việc thực hiện thay đổi độc lập. Bộ điều hợp được trang bị thêm để làm cho các lớp không liên quan làm việc cùng nhau.

Bao gồm ví dụ về xe hơi / xe tải / thiết bị từ các tài liệu trong câu trả lời. Ví dụ tuyệt vời và tương tự.
quasoft

8

Bài đăng này đã được khoảng một thời gian. Tuy nhiên, điều quan trọng là phải hiểu rằng mặt tiền có phần giống với bộ chuyển đổi nhưng nó không hoàn toàn giống nhau. Một bộ điều hợp "điều chỉnh" một lớp hiện có thành một lớp máy khách thường không tương thích. Giả sử bạn có một hệ thống dòng công việc cũ mà ứng dụng của bạn đang sử dụng như một máy khách. Công ty của bạn có thể có thể thay thế hệ thống quy trình làm việc bằng một hệ thống "không tương thích" mới (về giao diện). Trong hầu hết các trường hợp, bạn có thể sử dụng mẫu bộ điều hợp và viết mã thực sự gọi các giao diện của công cụ dòng công việc mới. Một cây cầu thường được sử dụng theo một cách khác. Nếu bạn thực sự có một hệ thống cần làm việc với các hệ thống tệp khác nhau (ví dụ như đĩa cục bộ, NFS, v.v.), bạn có thể sử dụng mẫu cầu nối và tạo một lớp trừu tượng để làm việc với tất cả các hệ thống tệp của mình. Điều này về cơ bản sẽ là một trường hợp sử dụng đơn giản cho mẫu cầu. Mặt tiền và bộ chuyển đổi có chung một số thuộc tính nhưngmặt tiền thường được sử dụng để đơn giản hóa một giao diện / lớp hiện có . Trong những ngày đầu của EJB, không có cuộc gọi địa phương nào cho EJB. Các nhà phát triển luôn thu được sơ khai, thu hẹp nó và gọi nó là "giả từ xa". Điều này thường gây ra vấn đề về hiệu suất (đặc biệt khi thực sự được gọi qua dây). Các nhà phát triển có kinh nghiệm sẽ sử dụng mô hình mặt tiền để cung cấp giao diện chi tiết rất thô cho khách hàng. Mặt tiền này sau đó sẽ lần lượt thực hiện nhiều cuộc gọi đến các phương pháp chi tiết hơn. Nói chung, điều này làm giảm đáng kể số lượng cuộc gọi phương thức cần thiết và tăng hiệu suất.


Mặc dù, dường như nằm ngoài phạm vi của câu hỏi này, Bộ điều hợp & Cầu nối với Mặt tiền có thể rất phù hợp.
Cody

1

Cầu được cải tiến Adaptor. Cầu bao gồm bộ chuyển đổi và thêm linh hoạt cho nó. Đây là cách các yếu tố từ bản đồ câu trả lời của Ravindra giữa các mẫu:

      Adapter  |    Bridge
    -----------|---------------
    Target     | Abstraction
    -----------|---------------
               | RefinedAbstraction
               |
               |   This element is Bridge specific. If there is a group of 
               |   implementations that share the same logic, the logic can be placed here.
               |   For example, all cars split into two large groups: manual and auto. 
               |   So, there will be two RefinedAbstraction classes.
    -----------|--------------- 
    Adapter    | Implementor
    -----------|---------------
    Adaptee    | ConcreteImplementor

1

Trong câu trả lời hàng đầu, @James trích dẫn một câu từ GoF, trang 219. Tôi nghĩ rằng nó đáng để tái tạo lời giải thích đầy đủ ở đây.

Bộ chuyển đổi so với cầu

Các mẫu Adaptor và Bridge có một số thuộc tính phổ biến. Cả hai đều thúc đẩy tính linh hoạt bằng cách cung cấp một mức độ gián tiếp cho một đối tượng khác. Cả hai đều liên quan đến các yêu cầu chuyển tiếp đến đối tượng này từ một giao diện khác ngoài giao diện của nó.

Sự khác biệt chính giữa các mẫu này nằm ở ý định của chúng. Adaptor tập trung vào giải quyết sự không tương thích giữa hai giao diện hiện có. Nó không tập trung vào cách các giao diện đó được thực hiện, cũng như không xem xét cách chúng có thể phát triển độc lập. Đó là một cách để làm cho hai lớp được thiết kế độc lập làm việc cùng nhau mà không cần thực hiện lại cái này hay cái kia. Cầu, mặt khác, cầu một sự trừu tượng và triển khai (có khả năng rất nhiều) của nó. Nó cung cấp một giao diện ổn định cho các máy khách ngay cả khi nó cho phép bạn thay đổi các lớp thực hiện nó. Nó cũng cung cấp các triển khai mới khi hệ thống phát triển.

Do những khác biệt này, Adaptor và Bridge thường được sử dụng tại các điểm khác nhau trong vòng đời của phần mềm. Một bộ điều hợp thường trở nên cần thiết khi bạn phát hiện ra rằng hai lớp không tương thích sẽ hoạt động cùng nhau, thường là để tránh sao chép mã. Các khớp nối là không lường trước. Ngược lại, người sử dụng một cây cầu hiểu trước rằng một sự trừu tượng phải có một vài triển khai và cả hai có thể phát triển độc lập. Mẫu Adaptor làm cho mọi thứ hoạt động sau khi chúng được thiết kế; Cầu làm cho họ làm việc trước khi họ đang có. Điều đó không có nghĩa là Adaptor kém hơn Bridge; mỗi mẫu chỉ giải quyết một vấn đề khác nhau.


0

Giả sử bạn có một lớp Hình dạng trừu tượng với chức năng vẽ (chung / trừu tượng) và Vòng tròn thực hiện Hình dạng. Mẫu cầu chỉ đơn giản là một cách tiếp cận trừu tượng hai chiều để tách rời việc thực hiện (vẽ trong Circle) và chức năng chung / trừu tượng (vẽ trong lớp Shape).

Nó thực sự có nghĩa là gì? Thoạt nhìn, nó có vẻ như là một thứ gì đó bạn đã làm (bằng cách đảo ngược phụ thuộc). Vì vậy, không phải lo lắng về việc có một cơ sở mã ít mô-đun hoặc mô-đun hơn. Nhưng đó là một triết lý sâu sắc hơn một chút đằng sau nó.

Theo hiểu biết của tôi, nhu cầu về mô hình sử dụng có thể xuất hiện khi tôi cần thêm các lớp mới có liên quan chặt chẽ với hệ thống hiện tại (như RedCircle hoặc GreenCircle) và chúng chỉ khác nhau bởi một chức năng duy nhất (như màu sắc). Và tôi sẽ cần mẫu Cầu đặc biệt nếu các lớp hệ thống hiện tại (Vòng tròn hoặc Hình dạng) thường xuyên được thay đổi và bạn không muốn các lớp mới được thêm bị ảnh hưởng từ những thay đổi đó. Vì vậy, đó là lý do tại sao chức năng vẽ chung được trừu tượng hóa thành một giao diện mới để bạn có thể thay đổi hành vi vẽ độc lập với Hình dạng hoặc Vòng tròn.

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.