Mục đích
Chuyển đổi giao diện của một
hay nhiều lớp có sẵn thành một giao diện khác mà client mong muốn.
Adapter cho phép các lớp có các giao diện khác nhau có thể dể dàng giao
tiếp tốt với nhau thông qua giao diện chuyển tiếp trung gian mà không cần thay
đổi code của lớp có sẵn cũng như lớp đang viết.
Cung cấp một giao diện “bọc
ngoài” tương thích cho một hệ thống có sẵn
Đối ứng phù hợp với các
component cũ cho hệ thống mới
Vấn đề
Một component “có sẵn” với
các tính năng đầy đủ có sẵn mà bạn muốn sử dụng lại, nhưng theo quan điểm mới
nó lại không phù hợp với triết lý và kiến trúc của hệ thống đang được phát triển.
Thảo luận
Vấn đề sử dụng lại luôn
khó khăn và mất nhiều công sức. Lý do ở đây là sự rắc rối khi thiết kế một cái
gì đó mới trong khi hoàn toàn có thể sử dụng lại cái cũ. Luôn luôn có một thứ
gì đó không toàn đúng giữa cũ và mới. Nó có thể là kích thước vật lý hoặc sai lệch,
có thể là thời gian hoặc sự đồng bộ hóa. Cũng có thể là giả định không may hoặc
tiêu chuẩn cạnh tranh. Nó giống như vấn đề lắp một cái phích cắm ba chấu loại mới
vào ổ cắm tường 2 chấu cũ, do đó một số công cụ chuyển đổi hoặc trung gian là cần
thiết.
Adapter là việc tạo ra sự
chuyển đổi trừu tượng trung gian, hoặc biểu đồ, hoặc đưa componennt cũ vào hệ
thống mới. Client gọi phương thức của đối tượng Adapter, Adapter chuyển hướng lời
gọi tới các hệ thống cũ. Chiến lược này có thể thực thi thông qua cơ chế kế thừa
(inheritance) hoặc kết tập (aggregation).
Adapter hoạt động giống như một
bộ bao gói (wrapper) hoặc bộ điều chỉnh (modifier) của lớp hiện tại. Nó cung cấp
một cái nhìn khác về dịch vụ đó.
Cấu trúc
Bên dưới, Thành phần
LegacyRectangle với phương thức display() có các tham số đầu vào "x, y, w,
h". Nhưng Client muốn truyền vào "x1, y1, x2, y2". Sự khác
biệt này có thể được dàn xếp bằng cách tạo một đối tượng bổ sung-ví dụ: Đối tượng
Adapter.
Adapter cũng có thể được coi
là một "wrapper".
Ví dụ
Adapter pattern cho phép các
lớp không tương thích làm việc cùng nhau bằng cách chuyển đổi giao diện của một
lớp thành một giao diện mà các client mong đợi. Cái cờ lê là một ví dụ về
Adapter. Ví dụ cần siết một con ốc, với điều kiện kích thước là như nhau. Kích
thước chuẩn của Hoa Kỳ là 1/2 "và 1/4". Rõ ràng, một con ốc cỡ 1/2
"sẽ không khớp với lỗ siết của cờ lê là 1/4" trừ khi sử dụng bộ chuyển
đổi. Bộ chuyển đổi từ 1/2 "đến 1/4" có một đầu nối 1/2 "để lắp
vào con ốc 1/2" và một đầu nối 1/4 "để khớp với lỗ siết của cờ lê
1/4".
Danh sách kiểm tra
- Nhận diện người dùng: Các
thành phần muốn làm cho phù hợp(ví dụ: client), và các thành phần cần chuyển đổi.
- Xác định giao diện mà client
yêu cầu.
- Thiết kế class “wrapper” có
thể đối ứng phù hợp adaptee cho client.
- Class adapter/wrapper “có một”
thể hiện của lớp adaptee.
- Class adapter/wrapper “ánh xạ”
giao diện client đến giao diện adaptee.
- Client sử dụng(được kết hợp với)
giao diện mới.
Qui tắc ngón tay cái:
- Adapter làm cho mọi thứ hoạt
động sau khi chúng được thiết kế; Làm cầu nối.
- Bridge có cấu trúc tương tự, nhưng mục tiêu khác (tách một giao
diện khỏi phần cài đặt). Adapter được trang bị để làm cho các lớp không liên
quan làm việc cùng nhau.
- Adapter cung cấp giao diện
khác nhau cho đối ứng của nó. Proxy Định
nghĩa một giao diện đại diện cho các đối tượng khác mà không làm thay đổi giao
diện của các đối tượng được đại diện, điều này thực hiện được nhờ các Adapter.,
một Adapter sẽ phối hợp hai đối tượng khác nhau. Decorator giao diện nâng cao.
- Adapter có nghĩa là thay đổi
giao diện của một đối tượng hiện có. Decorator bổ sung thêm chức năng nhưng không làm thay đổi giao diện,
trong mẫu thiết kế Decorator
- Facade định nghĩa một giao diện
mới, trong khi Adapter sử dụng lại giao diện cũ. Hãy nhớ rằng Adapter làm cho
hai giao diện hiện tại hoạt động cùng nhau trái ngược với việc định nghĩa một
giao diện hoàn toàn mới.
Ví dụ của việc làm thế nào để
thực hiện mô hình Adapter trong Java
1) Trước
Bởi vì interface giữa 2 đối
tượng Line và Rectangle là không tương thích nên user phải khôi phục lại loại của
shape và tự cung cấp các tham số chính xác.
class Line {
public void draw(int x1, int y1, int x2, int y2) {
System.out.println("Line from point A(" + x1 + ";" +
y1 + "), to point B(" +
x2 + ";" +
y2 + ")");
}
}
class Rectangle {
public void draw(int x, int y, int width, int height) {
System.out.println("Rectangle with coordinate left-down point (" +
x + ";" +
y + "), width: " +
width + ", height: " +
height);
}
}
public class AdapterDemo {
public static void main(String[] args) {
Object[] shapes = {new Line(), new Rectangle()};
int x1 = 10, y1 = 20;
int x2 = 30, y2 = 60;
int width = 40, height = 40;
for (Object shape : shapes) {
if (shape.getClass().getSimpleName().equals("Line")) {
((Line)shape).draw(x1, y1, x2, y2);
} else if (shape.getClass().getSimpleName().equals("Rectangle")) {
((Rectangle)shape).draw(x2, y2, width, height);
}
}
}
}
Kết quả
Line from point A(10;20), to
point B(30;60)
Rectangle with coordinate
left-down point (30;60), width: 40, height: 40
2) Sau
Tạo ra một interface common Shape từ đó các class Adapter có thể thực thi
và ghi đè lại phương thức draw theo mục đích riêng của mình.
interface Shape {
void draw(int x, int y, int z, int j);
}
class Line {
public void draw(int x1, int y1, int x2, int y2) {
System.out.println("Line from point A(" +
x1 + ";" +
y1 + "), to point B(" +
x2 + ";" +
y2 + ")");
}
}
class Rectangle {
public void draw(int x, int y, int width, int height) {
System.out.println("Rectangle with coordinate left-down point (" +
x + ";" +
y + "), width: " +
width + ", height: " +
height);
}
}
class LineAdapter implements Shape {
private Line adaptee;
public LineAdapter(Line line) {
this.adaptee = line;
}
@Override
public void draw(int x1, int y1, int x2, int y2) {
adaptee.draw(x1, y1, x2, y2);
}
}
class RectangleAdapter implements Shape {
private Rectangle adaptee;
public RectangleAdapter(Rectangle rectangle) {
this.adaptee = rectangle;
}
@Override
public void draw(int x1, int y1, int x2, int y2) {
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x2 - x1);
int height = Math.abs(y2 - y1);
adaptee.draw(x, y, width, height);
}
}
public class AdapterDemo {
public static void main(String[] args) {
Shape[] shapes = {new RectangleAdapter(new Rectangle()),
new LineAdapter(new Line())};
int x1 = 10, y1 = 20;
int x2 = 30, y2 = 60;
for (Shape shape : shapes) {
shape.draw(x1, y1, x2, y2);
}
}
}
Kết quả
Rectangle with coordinate
left-down point (10;20), width: 20, height: 40
Line from point A(10;20), to
point B(30;60)
إرسال تعليق