Adapter Pattern - Mô hình lập trình Adapter Pattern
Thiết kế theo Adapter Pattern cho phép chuyển đối interface của lớp này thành interface khác mong muốn. Mô hình thiết kế này cho pháp các lớp làm việc cùng nhau mà không bị xung đột về interface. Adapter cho phép sử dụng lại code mà không phải thay đổi. Để rõ hơn về Adapter Pattern xem ví dụ.
Ví dụ diễn tả Adapter Pattern trong Java
Xây dựng một lớp SendMail, giả sử để gửi thông tin tới email người quản lý website:
interface ISendInformation { public void send(); } class SendMail implements ISendInformation { @Override public void send() { System.out.println("Send Email"); } }
Xây dựng một lớp tên SaveStorage, giả sử để lưu thông tin vào đĩa
interface ISaveInformation { public void save(); } class SaveStorage implements ISaveInformation { @Override public void save() { System.out.println("Save to Disk"); } }
Vậy là có 2 lớp SendMail và SaveStorage, nếu sử dụng riêng hai lớp này thì không có vấn đề gì cả. Tuy nhiên có vài trường hợp bạn lại muốn sử dụng chức năng của SendMail (send) nhưng ứng xử của nó lại giống SaveStorage (save).
Ví dụ bạn xây dựng một lớp xử lý đơn hàng người dùng đặt trên website chẳng hạn, phân tích xong thì lưu dữ liệu vào đĩa (hoặc db) bằng SaveStorage, làm lớp đó như sau:
class Order { private String Data; //... các loại code khác public void processData(ISaveInformation iSaveInformation) { iSaveInformation.save(Data); } }
Trường hợp đơn giản sử dụng Order và SaveStorage như sau:
Order order = new Order("Dữ liệu mẫu ... String"); //... SaveStorage saveStorage = new SaveStorage(); order.processData(saveStorage);
Một lúc nào đó, bạn lại muốn Order thay vì lưu dữ liệu vào đĩa bằng SaveStorage, bạn lại muốn nó gửi email tới quản lý bằng SendMail, nhưng lại không muốn sửa một dòng code nào của Order, lúc này bạn xây dựng một lớp mà chức năng của nó là SendMail, nhưng ứng xử lại như SaveStorage để không phải xửa lại Order, làm được việc này chính là bạn đã ứng dụng mô hình lập trình Adapter Patter
Tạo một lớp Adapter như sau
class SendMailAdapter implements ISaveInformation { ISendInformation sendInformation; public SendMailAdapter(ISendInformation sendInformation) { this.sendInformation = sendInformation; } @Override public void save(String Data) { sendInformation.send(Data); } }
Bạn đã tạo ra một lớp, mà ứng xử của nó vẫn như SaveStorage (save), nhưng nó lại thực hiện chức năng của SendMail (send). Quay lại ví dụ trên, bạn đã có thể sử dụng Order để gửi mail thay vì ghi vào đĩa mà mã của Order không bị sửa đổi.
Order order = new Order("Dữ liệu mẫu ... String"); //... SendMail sendMail = new SendMail(); SendMailAdapter adapter = new SendMailAdapter(sendMail); order.processData(adapter);
Ví dụ diễn tả Adapter Pattern trong PHP
Bạn convert code JAVA trên sang PHP
≶?php interface ISendInformation { public function send($Data); } class SendMail implements ISendInformation { public function send($Data) { echo "Send Email"; } } interface ISaveInformation { public function save($Data); } class SaveStorage implements ISaveInformation { public function save($Data) { echo "Save to Disk"; } } class SendMailAdapter implements ISaveInformation { private $sendInformation; public function __construct($_sendInformation) { $this->sendInformation = $_sendInformation; } public function save($Data) { $this->sendInformation->send($Data); } } class Order { private $Data; public function __construct($Data) { $this->Data = $Data; } //... các loại code khác public function processData($iSaveInformation) { //... $iSaveInformation->save($this->Data); } } //Sử dụng CODE $order = new Order("Dữ liệu mẫu ... String"); //... $sendMail = new SendMail(); $adapter = new SendMailAdapter($sendMail); $order->processData($adapter); ?>