Khi nào chúng ta cần sử dụng mẫu Adapter? Nếu có thể cho tôi một ví dụ thế giới thực phù hợp với mô hình mà ...khi nào chúng ta cần mẫu Adapter?
Trả lời
Tôi đã làm việc trên một hệ thống cần thiết để giao tiếp với DVR bên ngoài. Đối với hầu hết các phần, tất cả các DVR có chức năng cơ bản giống nhau: bắt đầu ghi từ một nguồn video nhất định; ngừng ghi; bắt đầu phát lại từ một thời điểm nhất định; dừng phát lại, vv
Mỗi nhà sản xuất DVR cung cấp thư viện phần mềm, cho phép chúng tôi viết mã để điều khiển thiết bị của họ (vì mục đích của cuộc thảo luận này, tôi sẽ gọi nó là SDK). Mặc dù mọi SDK cung cấp API cho tất cả các chức năng cơ bản, nhưng không có chức năng nào trong số chúng hoàn toàn giống nhau. Đây là một ví dụ rất thô, nhưng bạn có ý tưởng:
- BeginPlayback (DateTime startTime);
- StartPlayback (long startTimeTicks);
- Phát lại (chuỗi startDate, chuỗi startTime);
Phần mềm của chúng tôi cần để có thể tương tác với tất cả DVR. Vì vậy, thay vì viết chuyển đổi khủng khiếp/trường hợp cho từng SDK khác nhau, chúng tôi đã tạo giao diện IDVRController chung của riêng mình và viết tất cả mã hệ thống của chúng tôi tới giao diện đó:
- Phát lại (DateTime startTime);
Sau đó, chúng tôi đã viết một triển khai bộ điều hợp khác cho mỗi SDK, tất cả đều triển khai giao diện IDVRController của chúng tôi. Chúng tôi đã sử dụng tệp cấu hình để chỉ định loại DVR mà hệ thống sẽ kết nối và mẫu Nhà máy để khởi tạo đúng trình cài đặt IDVRController cho DVR đó.
Theo cách đó, mẫu bộ điều hợp đã làm cho mã hệ thống của chúng tôi đơn giản hơn: chúng tôi luôn mã hóa IDVRController.Và nó cho phép chúng tôi triển khai các bộ điều hợp cho việc triển khai sau khi triển khai SDK mới (Nhà máy của chúng tôi đã sử dụng sự phản chiếu để khởi tạo phiên bản IDVRController chính xác).
Ví dụ thực tế đời sống tuyệt vời. Nó đã giúp tôi hiểu được mục đích thực sự của mô hình này. Tôi đã thấy rằng mô hình này chủ yếu được sử dụng cùng với Dịch vụ Locater hoặc Nhà máy mẫu. – NoobDeveloper
Trong lập trình máy tính, Adapter Pattern (thường được gọi là mô hình wrapper hoặc đơn giản là một wrapper) là một mẫu thiết kế mà dịch một giao diện cho một lớp học thành giao diện tương thích . Bộ điều hợp cho phép các lớp hoạt động cùng nhau mà thường không thể do giao diện không tương thích, bằng cách cung cấp giao diện cho khách hàng khi sử dụng giao diện gốc . Bộ điều hợp dịch các cuộc gọi đến giao diện của nó thành cuộc gọi đến giao diện ban đầu và số lượng mã cần thiết để thực hiện điều này thường nhỏ. Bộ điều hợp cũng chịu trách nhiệm chuyển đổi dữ liệu thành các biểu mẫu thích hợp. Đối với Ví dụ, nếu nhiều giá trị boolean được lưu trữ như một số nguyên duy nhất nhưng tiêu dùng của bạn đòi hỏi một 'true'/'false', adapter sẽ chịu trách nhiệm về chiết xuất giá trị thích hợp từ số nguyên giá trị .
Wikipedia !!!
mẫu Adaptor là cần thiết trong tình huống sau:
Giả sử bạn đã xác định một giao diện I1
với phương pháp M1
và M2
C1
và C2
thực hiện giao diện này I1
, bây giờ cho C1
trong khi thực hiện M1
và M2
bạn có tìm thấy không có sự giúp đỡ từ các lớp học hiện có khác, do đó bạn cần phải viết tất cả các logic của chính mình.
Bây giờ trong khi thực hiện lớp C2
bạn đã đi qua lớp C3
với các phương pháp M3
và M4
có thể được sử dụng để thực hiện M1
và M2
cho C2
như vậy để tận dụng những M3
và M4
trong lớp C2
bạn mở rộng lớp C3
và sử dụng M3
và M4
của C3
.
Trong ví dụ này C2
trở thành Adapter class
và C3
trở thành adaptee
package com.design.patterns;
public class AdapterExample {
public static void main(String[] args) {
Shape line = new LineShape();
line.draw();
Shape text = new TextShape();
text.draw();
}
}
//==Start from here
interface Shape{
public void draw();
}
class LineShape implements Shape{
@Override
public void draw() {
System.out.println("write some logic and draw line");
}
}
//Adapter
class TextShape extends TextView implements Shape{
@Override
public void draw() {
System.out.println("logic is already there in class TextView");
drawText();
}
}
// Adaptee
class TextView{
public void drawText() {
System.out.println("Drawing Text Shape");
}
}
hiện Interface
interface Shape {
public int calculateArea(int r);
}
thực hiện hiện tại cho giao diện Shape
class Square implements Shape {
@Override
public int calculateArea(int r) {
return r * r;
}
}
Bây giờ xem xét rằng bạn muốn lớp Vòng tròn thích ứng với giao diện hiện tại của chúng tôi mà không có cách nào chúng tôi có thể sửa đổi (Được viết bởi bên thứ ba).
class Circle {
public double calculateCircularArea (int r) {
return 3.14 * r * r;
}
}
Bây giờ chúng tôi đã điều chỉnh triển khai Vòng kết nối sang giao diện Hình dạng của chúng tôi. Vì vậy, chúng tôi cần một bộ điều hợp vì chúng không tương thích.
class CirCleAdaptor extends Circle implements Shape {
@Override
public int calculateArea(int r) {
return (int) calculateCircularArea(r);
}
}
CircleAdaptor - Là Adapter cho Vòng
Circle - Là Adaptee
Shape - Là giao diện Target
public class AdapterPattern {
public static void main(String[] args) {
Shape circle = new CirCleAdaptor();
System.out.println("Circle Area " + circle.calculateArea(5));
Shape square = new Square();
System.out.println("Square Area " + square.calculateArea(5));
}
}
Hy vọng điều này đưa ra một ý tưởng tốt hơn về Khi sử dụng nó.
Bạn có thể sử dụng mẫu thiết kế bộ điều hợp khi bạn phải xử lý các giao diện khác nhau với hành vi tương tự (thường có nghĩa là các lớp có hành vi tương tự nhưng với các phương pháp khác nhau). Một ví dụ về nó sẽ là một lớp học để kết nối với TV Samsung và một lớp khác để kết nối với TV Sony. Họ sẽ chia sẻ hành vi chung như menu mở, bắt đầu phát lại, kết nối với mạng và vv nhưng mỗi thư viện sẽ có một triển khai khác nhau của nó (với các tên và chữ ký khác nhau). Các triển khai cụ thể của nhà cung cấp khác nhau này được gọi là Adaptee trong biểu đồ UML.
Vì vậy, trong mã của bạn (gọi tắt là Khách hàng trong sơ đồ UML), thay vì cứng mã các cuộc gọi phương pháp của từng nhà cung cấp (hoặc Adaptee), sau đó bạn có thể tạo ra một giao diện chung (gọi tắt là Target trong Các sơ đồ UML) để bọc các hành vi tương tự này và chỉ làm việc với một loại đối tượng.
Các Adapters sau đó sẽ thực hiện giao diện Target ủy phương pháp của nó gọi đến Adaptees được truyền cho Adapters qua constructor.
Để bạn nhận ra điều này trong mã Java, tôi đã viết một dự án rất đơn giản, sử dụng chính xác ví dụ được đề cập ở trên bằng cách sử dụng bộ điều hợp để xử lý nhiều giao diện TV thông minh. Mã nhỏ, được ghi chép và tự giải thích để tìm hiểu về cách thực hiện thế giới thực như thế nào.
Chỉ cần tải xuống mã và nhập mã đó vào Eclipse (hoặc IDE yêu thích của bạn) làm dự án Maven. Bạn có thể thực thi mã bằng cách chạy org.example.Main.java. Hãy nhớ rằng điều quan trọng ở đây là để hiểu cách các lớp và các giao diện được ghép lại với nhau để thiết kế mẫu. Tôi cũng đã tạo một số đối tượng giả Adaptees trong gói com.thirdparty.libs. Hy vọng nó giúp!
Một ví dụ rất phổ biến của Adapter Pattern được thực hiện thông qua Service Provider Interface và thường được sử dụng trong rất nhiều khuôn khổ Java EE.
Lý do cho việc này là cho phép các triển khai khác nhau của Java EE nhưng các lập trình viên chỉ đơn giản là mã hóa cho đặc tả Java EE chứ không phải là một cái gì đó thực hiện cụ thể.
Trái ngược với một cái gì đó như mã hóa trực tiếp bằng cách sử dụng các lớp WebSphere mà khóa bạn vào sử dụng WebSphere.
Hoặc tồi tệ hơn (từ kinh nghiệm của tôi), Apache HTTP Client và tìm hiểu sau đó bởi vì bạn mã hóa để thực hiện thay vì HttpUrlConnection bình thường bạn phải thực hiện rất nhiều việc mã hóa vì nó không hỗ trợ phiên bản TLS hiện tại có thể tránh được nếu nhà phát triển ban đầu được mã hóa thành một API ổn định hơn và chúng tôi chỉ cần nâng cấp thời gian chạy Java.
- 1. Khi nào chúng ta cần mẫu trang trí?
- 2. MVC: tại sao chúng ta cần "điều khiển", hoặc khi nào chúng ta nên sử dụng mẫu này?
- 3. Chúng ta có cần mfence khi sử dụng xchg
- 4. Khi nào chúng ta nên sử dụng lớp học và khi chúng ta không nên
- 5. Chúng ta vẫn cần AsyncEnumerator của Richter?
- 6. Tại sao chúng ta cần strdup()?
- 7. Khi nào chúng ta sử dụng ANTLR
- 8. Khi nào chúng ta nên đóng EntityManagerFactory?
- 9. Tại sao chúng ta cần sợi
- 10. Tại sao chúng ta cần ng-click?
- 11. Tại sao chúng ta cần một thẻ fieldset?
- 12. Khi nào chúng ta nên sử dụng mutex và khi nào chúng ta nên sử dụng semaphore
- 13. Trình tự (Cơ sở dữ liệu) là gì? Khi nào chúng ta cần nó?
- 14. Tại sao chúng ta cần `Các gói đã nhập 'khi chúng ta có` Các trình cắm thêm cần thiết` trong các phụ thuộc trình cắm thêm eclipse?
- 15. Mẫu lưu trữ - Tại sao chính xác chúng ta cần Giao diện?
- 16. Khi nào chúng ta sẽ sử dụng applicationContext.xml trong Spring?
- 17. Trong trường hợp nào chúng ta sử dụng Mẫu Nhà máy và trong đó Mẫu Singleton?
- 18. Tại sao chúng ta cần các Dịch vụ Web RESTful?
- 19. flexbox vs bảng, tại sao chúng ta cần flexbox?
- 20. chúng ta cần thuộc tính Serializable cho enums
- 21. Chúng ta có cần dấu chấm phẩy ở cuối?
- 22. Tại sao chúng ta cần funcall trong Lisp?
- 23. Tại sao chúng ta cần các nhà thầu tĩnh?
- 24. Tại sao chúng ta cần đặt khoảng trống trước% c?
- 25. Tại sao chúng ta cần ssh không mật khẩu Hadoop?
- 26. Tại sao chúng ta cần toán tử "delete []"?
- 27. Lịch add() vs roll() khi nào chúng ta sử dụng?
- 28. Tại sao chúng ta nên sử dụng mã hóa ui khi chúng ta có Specflow?
- 29. Chúng ta có nên đóng HttpPostedFile.Inputstream, khi chúng ta đã hoàn thành việc sử dụng nó?
- 30. Tại sao chúng ta cần giao diện trong Java?
Bạn có dự định xem toàn bộ cuốn sách GoF và hỏi khi nào bạn cần mẫu X không? –
Miễn là nó cho anh ta tất cả những người upvotes, nếu tôi là anh ta tôi sẽ hỏi về mỗi và mọi mẫu thiết kế :-P –
@Thomas Owens: Tất cả tôi tìm kiếm là một ví dụ thế giới thực tốt sẽ giúp tôi tìm hiểu về mô hình đó . – brainless