-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local
Bước chuyển thông minh
Chắc có lẽ tất cả chúng ta đã từng một lần trong đời sử dụng đến Adapter rồi nhỉ? Đó có thể là một thiết bị chuyển từ ổ cắm 2 chân sang 3 chân, có thể là dây chuyển cổng USB sang Type-C, có thể là thiết bị chuyển đổi điện trong bộ sạc, vân vân và mây mây. và đó đều là những bước chuyển thông minh giúp chúng ta vẫn có thể sử dụng các thiết bị hiện đang có mà vẫn tiết kiệm được chi phí.
Bài toán thực tế
Hãy lấy một bài toán thực tế về chương trình phát nhạc trên máy tính của chúng ta. Từ thời xa xưa, khi máy tình còn sơ khai, thì chúng ta chỉ có thể nghe được audio trên trình phát nhạc. Nhưng thế giới đã thay đổi và máy tính cũng mạnh hơn rất rất nhiều lần, nên giờ chúng ta đã có thể xem cải video trên trình phát nhạc. Vậy phải làm thế nào để chúng ta vẫn sử dụng được trình phát nhạc đó để vừa có thể phát được nhạc như cũ mà vừa có thể tích hợp thêm khả năng xem video? Câu trả lời là chúng ta sẽ tạo ra một bộ chuyển đổi (Adapter) để giúp cho các định dạng video có thể mở được trên trình phát nhạc.
Mục tiêu ra đời
Đúng như tính chất của những bộ chuyển đổi, apdater design pattern ra đời nhằm mục tiêu:
- Chuyển đổi interface của một class sang interface của một class khác: ví dụ chúng ta cần chuyển đổi interface
VideoMediaPlayer
sáng interfaceMediaPlayer
- Cho phép các lớp không cùng interface làm việc với nhau mà không làm phá vỡ quy tắc chung: ví dụ lớp
AudioPlayer
cài đặt interfaceMediaPlayer
có thể làm việc cùng với 2 lớpMP4VideoPlayer
vàVLCVideoPlayer
cài đặt interfaceVideoMediaPlayer
cùng để phát đa phương tiện mà không làm ảnh hưởng đến trình phát nhạc đã có sẵn.
Ví dụ
Trở lại với ví dụ trình phát nhạc, chúng ta sẽ cần thiết kế lớp một chút
Sơ đồ lớp
Chúng ta sẽ có 2 interface và 4 lớp:
- MediaPlayer: là interface đã có từ trước, chúng ta sẽ không động chạm gì đến interface này
- VideoMediaPlayer: là interface mới thêm vào, phục vụ cho tính năng liên quan đến video
- MediaAdapter: là lớp chuyển đổi từ
VideoMediaPlayer
từMediaPlayer
, chính vì thế mà nó phải thừa kếMediaPlayer
- AudioPlayer: là lớp chuyên phát nhạc đã có từ trước, chúng ta sẽ cần thay đổi lớp này một chút để gọi đến
MediaAdapter
trong trường hợp cần phát video - VLCPVideoPlayer: là lớp phục vụ cho phát video liên quan đến vlc
- MP4VideoPlayer : là lớp phục vụ cho phát video liên quan đến mp4
Thiết kế lớp đã xong, giờ chúng ta hãy bắt tay vào viết code.
Code
Code cài đặt cũng tương đối đơn giản:
interface MediaPlayer {
public void play(MediaType mediaType, String fileName);
}
interface VideoMediaPlayer {
public void playVideo(String fileName);
}
class MediaAdapter implements MediaPlayer {
private VideoMediaPlayer vlcMediaPlayer = new VLCPVideoPlayer();
private VideoMediaPlayer mp4MediaPlayer = new MP4VideoPlayer();
@Override
public void play(MediaType mediaType, String fileName) {
if (mediaType == MediaType.VLC) {
vlcMediaPlayer.playVideo(fileName);
}
else {
mp4MediaPlayer.playVideo(fileName);
}
}
}
class AudioPlayer implements MediaPlayer {
private final MediaAdapter mediaAdapter = new MediaAdapter();
@Override
public void play(MediaType mediaType, String fileName) {
if (mediaType == MediaType.MP3) {
System.out.println("Playing MP3 file. Name: " + fileName);
}
else {
mediaAdapter.play(mediaType, fileName);
}
}
}
class VLCPVideoPlayer implements VideoMediaPlayer {
@Override
public void playVideo(String fileName) {
System.out.println("Playing VLC file. Name: " + fileName);
}
}
class MP4VideoPlayer implements VideoMediaPlayer {
@Override
public void playVideo(String fileName) {
System.out.println("Playing MP4 file. Name: " + fileName);
}
}
Và khi sử dụng sẽ thế này:
MediaPlayer audioPlayer = new AudioPlayer();
audioPlayer.play(MediaType.MP3, "bong_hoa_nho.mp3");
audioPlayer.play(MediaType.MP4, "bong_hoa_vua.mp4");
audioPlayer.play(MediaType.VLC, "bong_hoa_to.vlc");
Bạn có thể thấy lớp sử dụng không cần quan tâm đến sự có mặt của các lớp cài đặt VideoMediaPlayer
, đều này đảm bảo chương trình vẫn hoạt động ổn mà không cần sửa đổi gì lớp sử dụng cả. Ví dụ đầy đủ, bạn có thể tham khảo tại Github của tôi
Tham khảo
-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local