GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Design pattern Structuaral Pattern Hướng dẫn Java Design Pattern – Adapter

Hướng dẫn Java Design Pattern – Adapter

Đăng vào 15/10/2018 . Được đăng bởi GP Coder . 61545 Lượt xem . Toàn màn hình

Trong các bài viết trước chúng ta đã cùng tìm hiểu về các Pattern thuộc nhóm Creational Design Pattern. Trong bài này, chúng ta sẽ tìm hiểu qua một Pattern khác thuộc nhóm Structural Design Pattern là Adpater Pattern.

Nội dung

  • 1 Adapter Pattern là gì?
  • 2 Cài đặt Adapter Pattern như thế nào?
  • 3 Lợi ích của Adapter Pattern là gì?
  • 4 Sử dụng Adapter Pattern khi nào?

Adapter Pattern là gì?

Adapter Pattern is a structural design pattern that convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.

Adapter Pattern (Người chuyển đổi) là một trong những Pattern thuộc nhóm cấu trúc (Structural Pattern). Adapter Pattern cho phép các inteface (giao diện) không liên quan tới nhau có thể làm việc cùng nhau. Đối tượng giúp kết nối các interface gọi là Adapter.

Adapter Pattern giữ vai trò trung gian giữa hai lớp, chuyển đổi interface của một hay nhiều lớp có sẵn thành một interface khác, thích hợp cho lớp đang viết. Điều này cho phép các lớp có các interface khác nhau có thể dễ dàng giao tiếp tốt với nhau thông qua interface trung gian, không cần thay đổi code của lớp có sẵn cũng như lớp đang viết.

Adapter Pattern còn gọi là Wrapper Pattern do cung cấp một interface “bọc ngoài” tương thích cho một hệ thống có sẵn, có dữ liệu và hành vi phù hợp nhưng có interface không tương thích với lớp đang viết.

Ví dụ:

  • Cái phích cắm điện có 3 chân nhưng ổ điện chỉ có 2 lỗ thì phải dùng thêm 1 cái bộ chuyển để chuyển từ 3 chân sang 2 chân – bộ chuyển này cũng được gọi là Adapter.

  • Một ví dụ khác là laptop không sử dụng nguồn điện xoay chiều 224V, nên để laptop có thể sử dụng được nguồn điện 224V cần có một adapter làm cầu nối trung gian để chuyển nguồn điện xoay chiều 224V thành nguồn điện 1 chiều 12V.

Cài đặt Adapter Pattern như thế nào?

Một Adapter Pattern bao gồm các thành phần cơ bản sau:

  • Adaptee: định nghĩa interface không tương thích, cần được tích hợp vào.
  • Adapter: lớp tích hợp, giúp interface không tương thích tích hợp được với interface đang làm việc. Thực hiện việc chuyển đổi interface cho Adaptee và kết nối Adaptee với Client.
  • Target: một interface chứa các chức năng được sử dụng bởi Client (domain specific).
  • Client: lớp sử dụng các đối tượng có interface Target.

Có hai cách để thực hiện Adapter Pattern dựa theo cách cài đặt (implement) của chúng:

  • Object Adapter – Composition (Chứa trong): trong mô hình này, một lớp mới (Adapter) sẽ tham chiếu đến một (hoặc nhiều) đối tượng của lớp có sẵn với interface không tương thích (Adaptee), đồng thời cài đặt interface mà người dùng mong muốn (Target). Trong lớp mới này, khi cài đặt các phương thức của interface người dùng mong muốn, sẽ gọi phương thức cần thiết thông qua đối tượng thuộc lớp có interface không tương thích.

  • Class Adapter – Inheritance (Kế thừa) : trong mô hình này, một lớp mới (Adapter) sẽ kế thừa lớp có sẵn với interface không tương thích (Adaptee), đồng thời cài đặt interface mà người dùng mong muốn (Target). Trong lớp mới, khi cài đặt các phương thức của interface người dùng mong muốn, phương thức này sẽ gọi các phương thức cần thiết mà nó thừa kế được từ lớp có interface không tương thích.

So sánh Class Adapter với Object Adapter:

  • Sự khác biệt chính là Class Adapter sử dụng Inheritance (kế thừa) để kết nối Adapter và Adaptee trong khi Object Adapter sử dụng Composition (chứa trong) để kết nối Adapter và Adaptee.
  • Trong cách tiếp cận Class Adapter, nếu một Adaptee là một class và không phải là một interface thì Adapter sẽ là một lớp con của Adaptee. Do đó, nó sẽ không phục vụ tất cả các lớp con khác theo cùng một cách vì Adapter là một lớp phụ cụ thể của Adaptee.

Tại sao Object Adapter lại tốt hơn?

  • Nó sử dụng Composition để giữ một thể hiện của Adaptee, cho phép một Adapter hoạt động với nhiều Adaptee nếu cần thiết.

Ví dụ Adapter Pattern với ứng dụng Translation

Một người Việt muốn trao đổi với một người Nhật. Tuy nhiên, 2 người này không biết ngôn ngữ của nhau nên cần phải có một người để chuyển đổi từ ngôn ngữ tiếng Việt sang ngôn ngữ tiếng Nhật. Chúng ta sẽ mô hình hóa trường hợp này với Adapter Pattern như sau:

  • Client: người Việt sẽ là Client trong ví dụ này,vì anh ta cần gửi một số message cho người Nhật.
  • Target: đây là nội dung message được Client cung cấp cho thông dịch viên (Translator / Adapter).
  • Adapter: thông dịch viên (Translator) sẽ là Adapter, nhận message tiếng Việt từ Client và chuyển đổi nó sang tiếng Nhật trước khi gởi cho người Nhật.
  • Adaptee: đây là interface hoặc class được người Nhật sử dụng để nhận message được chuyển đổi từ thông dịch viên (Translator).

VietnameseTarget.java


package com.gpcoder.patterns.structural.adapter;

public interface VietnameseTarget {

	void send(String words);

}

JapaneseAdaptee.java


package com.gpcoder.patterns.structural.adapter;

public class JapaneseAdaptee {

	public void receive(String words) {
		System.out.println("Retrieving words from Adapter ...");
		System.out.println(words);
	}
}

TranslatorAdapter.java


package com.gpcoder.patterns.structural.adapter;

public class TranslatorAdapter implements VietnameseTarget {

	private JapaneseAdaptee adaptee;

	public TranslatorAdapter(JapaneseAdaptee adaptee) {
		this.adaptee = adaptee;
	}

	@Override
	public void send(String words) {
		System.out.println("Reading Words ...");
		System.out.println(words);
		String vietnameseWords = this.translate(words);
		System.out.println("Sending Words ...");
		adaptee.receive(vietnameseWords);
	}

	private String translate(String vietnameseWords) {
		System.out.println("Translated!");
		return "こんにちは";
	}
}

VietnameseClient.java


package com.gpcoder.patterns.structural.adapter;

public class VietnameseClient {

	public static void main(String[] args) {
		VietnameseTarget client = new TranslatorAdapter(new JapaneseAdaptee());
		client.send("Xin chào");
	}
}

Output của chương trình trên:


Reading Words ...
Xin chào
Translated!
Sending Words ...
Retrieving words from Adapter ...
こんにちは

Ví dụ Adapter Pattern với BufferedReader


BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your name: ");
String s = br.readLine();

Như bạn thấy:

  • System.in: đây là một Adaptee. System.in là một static instance của lớp InputStream, nó đọc dữ liệu từ Console và trả về 1 byte stream.
  • BufferedReader : đây là Target, nó chấp nhận dữ liệu là một character stream.
  • InputStreamReader : đây là một Adapter ở giữa hai interface không tương thích: System.in và BufferedReader giúp cho chúng có thể hoạt động được với nhau.
  • Client: là ứng dụng sẽ làm việc với Target interface.

Lợi ích của Adapter Pattern là gì?

Việc sử dụng Adapter Pattern đem lại các lợi ích sau:

  • Cho phép nhiều đối tượng có interface giao tiếp khác nhau có thể tương tác và giao tiếp với nhau.
  • Tăng khả năng sử dụng lại thư viện với interface không thay đổi do không có mã nguồn.

Bên cạnh những lợi ích trên, nó cũng nó một số khuyết điểm nhỏ sau:

  • Tất cả các yêu cầu được chuyển tiếp, do đó làm tăng thêm một ít chi phí.
  • Đôi khi có quá nhiều Adapter được thiết kế trong một chuỗi Adapter (chain) trước khi đến được yêu cầu thực sự.

Sử dụng Adapter Pattern khi nào?

Có thể dùng Adapter Pattern trong những trường hợp sau:

  • Adapter Pattern giúp nhiều lớp có thể làm việc với nhau dễ dàng mà bình thường không thể. Một trường hợp thường gặp phải và có thể áp dụng Adapter Pattern là khi không thể kế thừa lớp A, nhưng muốn một lớp B có những xử lý tương tự như lớp A. Khi đó chúng ta có thể cài đặt B theo Object Adapter, các xử lý của B sẽ gọi những xử lý của A khi cần.
  • Khi muốn sử dụng một lớp đã tồn tại trước đó nhưng interface sử dụng không phù hợp như mong muốn.
  • Khi muốn tạo ra những lớp có khả năng sử dụng lại, chúng phối hợp với các lớp không liên quan hay những lớp không thể đoán trước được và những lớp này không có những interface tương thích.
  • Cần phải có sự chuyển đổi interface từ nhiều nguồn khác nhau.
  • Khi cần đảm bảo nguyên tắc Open/ Close trong một ứng dụng.

Một vài class sử dụng Adapter Pattern:

  • java.util.Arrays#asList()
  • java.io.InputStreamReader(InputStream) (returns a Reader)
  • java.io.OutputStreamWriter(OutputStream) (returns a Writer)
  • javax.xml.bind.annotation.adapters.XmlAdapter#marshal() và #unmarshal()

Tài liệu tham khảo:

  • https://sourcemaking.com/design_patterns/adapter
  • https://refactoring.guru/design-patterns/adapter
  • https://www.javatpoint.com/adapter-pattern
  • https://www.tutorialspoint.com/design_pattern/adapter_pattern.htm
  • https://www.javagists.com/adapter-design-pattern
  • https://www.oodesign.com/adapter-pattern.html
4.7
25
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Design pattern, Structuaral Pattern Được gắn thẻ: Design pattern, Structuaral Pattern

Hướng dẫn Java Design Pattern – Object Pool
Hướng dẫn Java Design Pattern – Bridge

Có thể bạn muốn xem:

  • Hướng dẫn Java Design Pattern – Mediator (20/12/2018)
  • Giới thiệu thư viện Apache Commons Chain (01/05/2019)
  • Hướng dẫn Java Design Pattern – Facade (16/11/2018)
  • Hướng dẫn Java Design Pattern – Iterator (17/12/2018)
  • Hướng dẫn Java Design Pattern – Abstract Factory (15/09/2018)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (98055 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97695 lượt xem)
  • Giới thiệu Design Patterns (87756 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (86427 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83828 lượt xem)

Nội dung bài viết

  • 1 Adapter Pattern là gì?
  • 2 Cài đặt Adapter Pattern như thế nào?
  • 3 Lợi ích của Adapter Pattern là gì?
  • 4 Sử dụng Adapter Pattern khi nào?

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link