Command Pattern trong Java

0 0 0

Người đăng: Ông Huy Thắng

Theo Viblo Asia

Design Pattern Command là một trong những mẫu thiết kế hành vi (Behavioral Design Pattern), cho phép bạn đóng gói một yêu cầu dưới dạng một đối tượng, từ đó bạn có thể:

  • Tham số hóa các đối tượng với các yêu cầu khác nhau.
  • Xếp hàng hoặc lưu trữ lịch sử các lệnh (ví dụ: undo/redo).
  • Tách người gửi lệnh (invoker) khỏi người thực thi lệnh (receiver).

Cấu trúc của Command Pattern

Command pattern gồm các thành phần:

  1. Command (interface):

    • Khai báo phương thức execute().
  2. ConcreteCommand:

    • Cài đặt interface Command, liên kết với Receiver.
    • Gọi phương thức cụ thể trên Receiver trong execute().
  3. Receiver:

    • Thực thi hành động thực tế.
  4. Invoker:

    • Gọi command.execute() khi cần.
  5. Client:

    • Tạo command, gán receiver, và giao cho invoker thực hiện.

Ví dụ đơn giản bằng Java

// Command
public interface Command { void execute();
} // Receiver
public class Light { public void turnOn() { System.out.println("Light is ON"); } public void turnOff() { System.out.println("Light is OFF"); }
} // Concrete Command
public class TurnOnLightCommand implements Command { private Light light; public TurnOnLightCommand(Light light) { this.light = light; } public void execute() { light.turnOn(); }
} // Invoker
public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); }
} // Client
public class CommandPatternDemo { public static void main(String[] args) { Light light = new Light(); Command lightOn = new TurnOnLightCommand(light); RemoteControl remote = new RemoteControl(); remote.setCommand(lightOn); remote.pressButton(); // Output: Light is ON }
}

Ứng dụng thực tế trong Spring Boot

Bối cảnh: Mở tài khoản ngân hàng online

Quy trình gồm 3 bước:

  • Kiểm tra giấy tờ tùy thân
  • Kiểm tra độ tuổi
  • Gửi email xác nhận

Cách triển khai Command Pattern kết hợp Chain of Responsibility (cũng là 1 Behavioral pattern), thường được dùng trong xử lý nghiệp vụ tuần tự

1. Interface Command chung:

public interface Command { boolean execute(Context context);
}

2. Context dùng để chia sẻ dữ liệu giữa các bước:

public class Context { public String customerName; public int age; public boolean hasValidId; public boolean resultOk = true; public String message;
}

3. Các bước xử lý cụ thể (command):

// Kiểm tra giấy tờ:
public class CheckIdCommand implements Command { public boolean execute(Context context) { if (!context.hasValidId) { context.resultOk = false; context.message = "ID is not valid."; return false; } return true; }
} // Kiểm tra tuổi:
public class CheckAgeCommand implements Command { public boolean execute(Context context) { if (context.age < 18) { context.resultOk = false; context.message = "Customer must be at least 18 years old."; return false; } return true; }
} // Gửi email
public class SendEmailCommand implements Command { public boolean execute(Context context) { System.out.println("Sending email to " + context.customerName); return true; }
} 

4. CommandExecutor – nơi chạy toàn bộ quy trình:

public class CommandExecutor { private final List<Command> commands; public CommandExecutor(List<Command> commands) { this.commands = commands; } public void execute(Context context) { for (Command command : commands) { if (!command.execute(context)) { System.out.println("Stopped: " + context.message); return; } } System.out.println("All steps completed successfully."); }
}

5 Sử dụng

public class Main { public static void main(String[] args) { Context ctx = new Context(); ctx.customerName = "Nguyen Van A"; ctx.age = 17; ctx.hasValidId = true; List<Command> commandList = List.of( new CheckIdCommand(), new CheckAgeCommand(), new SendEmailCommand() ); CommandExecutor executor = new CommandExecutor(commandList); executor.execute(ctx); }
}

Kết quả:

Stopped: Customer must be at least 18 years old. // Nếu sửa lại tuổi = 20
Sending email to Nguyen Van A
All steps completed successfully.

Các bạn có thể sử dụng thư viện commons-chain của Apache để không cần phải triển khai. Mình sẽ sử dụng nó trong bài Chain of Responsibility Pattern nhé.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tổng hợp các bài hướng dẫn về Design Pattern - 23 mẫu cơ bản của GoF

Link bài viết gốc: https://gpcoder.com/4164-gioi-thieu-design-patterns/. Design Patterns là gì. Design Patterns không phải là ngôn ngữ cụ thể nào cả.

0 0 313

- vừa được xem lúc

Giới thiệu về Builder Design Pattern

Nguồn: refactoring.guru. Builder. Ý đồ.

0 0 47

- vừa được xem lúc

Một ví dụ nhỏ về Factory method

Trong bài viết trước mình đã giới thiệu tới các bạn về Abstract Factory pattern, các bạn quan tâm có thể theo dõi lại tại đây. Để tiếp tục về chủ đề design pattern trong bài viết này mình sẽ trình bày những khái niệm, ưu nhược điểm và các sử dụng của một creational design pattern khác đó là Factory

0 0 41

- vừa được xem lúc

Tôi đã dùng Service Pattern trong NuxtJS như thế nào ?

Giới thiệu. Trong quá trình làm VueJS NuxtJS hay thậm chí là Laravel mình cũng hay áp dụng các pattern như Service hoặc Repository.

0 0 75

- vừa được xem lúc

Hướng dẫn Adapter Design Pattern

Trong bài viết này, chúng ta sẽ cùng tìm hiểu về Adapter Design Pattern qua cấu trúc, cánh triển khai, ví dụ, ưu điểm nhược điểm và ứng dụng của nó. Đây là bài viết đầu tiên của mình nên sẽ không trán

1 1 71

- vừa được xem lúc

Giới thiệu về Prototype Design Pattern

Ý đồ. Prototype là một creational design pattern cho phép bạn sao chép các object hiện có mà không làm cho code của bạn phụ thuộc vào các class của chúng.

0 0 55