Mẫu Lệnh (Command Pattern)

Giới thiệu về Mẫu Lệnh

Mẫu Lệnh là một mẫu thiết kế hành vi, giúp đóng gói các tác vụ hoặc yêu cầu thành các đối tượng lệnh riêng biệt. Điều này cho phép các lệnh được lưu trữ, truyền đạt và quản lý một cách linh hoạt, đồng thời tách biệt người gọi và đối tượng thực hiện. Các lệnh được đóng gói sẽ tuân theo giao diện chung hoặc kế thừa lớp cơ sở chung, giúp logic gọi đơn giản hơn và hỗ trợ kết hợp nhiều lệnh hiệu quả.

Các trường hợp áp dụng phổ biến: giao diện người dùng, thao tác tập tin, giao dịch cơ sở dữ liệu, điều khiển từ xa, hệ thống lịch trình, chức năng hủy nhiều cấp, phát triển trò chơi và hệ thống ghi nhật ký.

Cấu trúc Mẫu Lệnh

  1. IAction (Giao diện lệnh): Định nghĩa phương thức thực thi, thường chứa hàm execute.
  2. ActionConcrete (Lệnh cụ thể): Triển khai giao diện lệnh, xử lý tác vụ cụ thể. Thường chứa đối tượng nhận và gọi phương thức của nó.
  3. Client (Người tạo): Tạo đối tượng lệnh cụ thể và liên kết với đối tượng gọi.
  4. Invoker (Đối tượng gọi): Chứa lệnh và kích hoạt thực thi khi cần.
  5. Receiver (Đối tượng nhận): Biết cách thực hiện tác vụ thực tế, là đối tượng được lệnh tác động.

Nguyên lý hoạt động

  1. Người tạo tạo đối tượng lệnh: Tạo lệnh cụ thể và thiết lập đối tượng nhận, đóng gói tác vụ vào lệnh.
  2. Thiết lập lệnh cho đối tượng gọi: Gán lệnh vào đối tượngInvoker để xác định tác vụ cần thực hiện.
  3. Đối tượng gọi thực thi: Khi cần, gọi phương thức execute của lệnh.
  4. Lệnh gọi đối tượng nhận: Lệnh cụ thể thực hiện phương thức của đối tượng nhận để xử lý tác vụ.
  5. Đối tượng nhận thực hiện: Đối tượng nhận biết cách thực hiện tác vụ cụ thể.

Ví dụ mã nguồn (C#)

Lệnh: Action.cs

namespace CommandPattern;

// Giao diện hành động
interface IAction
{
    // Thực thi
    void Execute();
}

// Mở đèn
class TurnOnCommand : IAction
{
    private Lamp lamp; // Đèn

    public TurnOnCommand(Lamp lamp)
    {
        this.lamp = lamp;
    }

    public void Execute()
    {
        lamp.TurnOn();
    }
}

// Tắt đèn
class TurnOffCommand : IAction
{
    private Lamp lamp; // Đèn

    public TurnOffCommand(Lamp lamp)
    {
        this.lamp = lamp;
    }

    public void Execute()
    {
        lamp.TurnOff();
    }
}

Đèn: Lamp.cs

namespace CommandPattern;

// Đèn
class Lamp
{
    // Trạng thái bật
    public bool IsOn { get; private set; }

    // Bật
    public void TurnOn()
    {
        IsOn = true;
        Console.WriteLine("Bật đèn...");
    }

    // Tắt
    public void TurnOff()
    {
        IsOn = false;
        Console.WriteLine("Tắt đèn...");
    }
}

Bộ điều khiển: Controller.cs

namespace CommandPattern;
#pragma warning disable

// Nút điều khiển đèn
class LampController
{
    private IAction action;

    public LampController()
    {
        action = null;
    }

    // Thiết lập hành động khi nhấn nút
    public void SetAction(IAction action)
    {
        this.action = action;
    }

    // Nhấn nút
    public void PressButton()
    {
        if (action != null) action.Execute();
    }
}

Mã kiểm tra: Program.cs

// ************* 19. Kiểm tra Mẫu Lệnh **************
using CommandPattern;

// Tạo đối tượng
Lamp lamp = new Lamp();
TurnOnCommand turnOn = new TurnOnCommand(lamp);
TurnOffCommand turnOff = new TurnOffCommand(lamp);
LampController controller = new LampController();

// Bật đèn
controller.SetAction(turnOn);
controller.PressButton();
Console.WriteLine("Đèn đang bật: " + lamp.IsOn);

// Tắt đèn
controller.SetAction(turnOff);
controller.PressButton();
Console.WriteLine("Đèn đang bật: " + lamp.IsOn);

Giải thích mã nguồn

Mã nguồn mô phỏng thao tác điều khiển đèn qua nút bấm. Đèn có hai trạng thái (bật/tắt), tương ứng với hai lệnh điều khiển. Nút bấm đóng vai trò người gọi, trong khi đèn là đối tượng nhận. Hai lệnh đóng gói logic thay đổi trạng thái và được truyền đến nút bấm, giúp nó thực hiện chức năng bật/tắt đèn.

Thẻ: design patterns C# Object-Oriented Programming

Đăng vào ngày 3 tháng 8 lúc 21:21