0
0
Lập trình
Admin Team
Admin Teamtechmely

Mẫu thiết kế State trong C++ với Timer và Thông báo

Đăng vào 4 ngày trước

• 6 phút đọc

Mẫu thiết kế State trong C++ với Timer và Thông báo

Mẫu thiết kế State là một trong những mẫu thiết kế phổ biến trong lập trình hướng đối tượng. Qua bài viết này, chúng ta sẽ tìm hiểu cách triển khai mẫu thiết kế State trong C++ với việc sử dụng Timer và thông báo. Bài viết sẽ cung cấp cho bạn những kiến thức cần thiết để áp dụng mẫu thiết kế này vào các dự án thực tế.

Mục lục

Giới thiệu

Mẫu thiết kế State cho phép bạn đóng gói hành vi của một đối tượng dựa trên trạng thái nội tại của nó. Điều này giúp tăng tính mở rộng và khả năng bảo trì của mã nguồn. Ở bài viết này, chúng ta sẽ khám phá cách thực hiện mẫu thiết kế State trong C++ thông qua một ví dụ thực tế về quy trình nấu ăn.

Các thành phần chính của mẫu thiết kế State

Mẫu thiết kế State bao gồm ba thành phần chính:

  1. Context: Đối tượng này đại diện cho thực thể trải qua các thay đổi trạng thái. Nó giữ tham chiếu đến đối tượng trạng thái hiện tại và cung cấp giao diện cho các tương tác bên ngoài.
  2. State: Đây là các lớp cụ thể đại diện cho mỗi trạng thái mà đối tượng có thể có. Mỗi lớp trạng thái định nghĩa hành vi riêng của nó để phản hồi các sự kiện và chuyển tiếp.
  3. Transitions: Các chuyển tiếp này xác định cách mà đối tượng có thể chuyển từ trạng thái này sang trạng thái khác. Chúng có thể được kích hoạt bởi các sự kiện, hành động của người dùng hoặc các điều kiện nội bộ.

Ví dụ thực tế: Quy trình nấu ăn

Trong ví dụ của chúng ta, chúng ta sẽ xem xét quy trình nấu ăn một con gà. Các trạng thái của gà sẽ thay đổi từ trạng thái chưa rửa, đến trạng thái đã rửa, đã ướp gia vị, đã nấu chín, và cuối cùng là phục vụ cho khách.

Các trạng thái trong quy trình nấu ăn:

  • UncleanedState: Trạng thái gà chưa rửa.
  • CleanedState: Trạng thái gà đã rửa.
  • MarinatedState: Trạng thái gà đã ướp gia vị.
  • CookedState: Trạng thái gà đã nấu chín.

Thực hành: Triển khai mã nguồn

Dưới đây là mã nguồn chi tiết cho việc triển khai mẫu thiết kế State với quy trình nấu ăn:

cpp Copy
/*
 * Callback.h
 *
 * Created on: May 5, 2022
 * Author: som
 */

#ifndef CALLBACK_H_
#define CALLBACK_H_

class Callback {
public:
    virtual void goToNextStateFromCallback() = 0;
    virtual ~Callback() {}
};

#endif /* CALLBACK_H_ */

---

#ifndef CHICKENSTATE_H_
#define CHICKENSTATE_H_

#include <iostream>
#include <string>
#include <cstring>
#include "Mamma.h"
#include "timer.h"

using namespace std;

class Mamma;

class ChickenState {
public:
    ChickenState() {}

    virtual ~ChickenState() {
        cout << "Gà đã hoàn thành... mọi người hãy thưởng thức" << endl;
    }

    virtual void wash(int periodForDisplayMessage, int theTotalTimeNeeded) = 0;
    virtual void marinate(int periodForDisplayMessage, int theTotalTimeNeeded) = 0;
    virtual void cook(int periodForDisplayMessage, int theTotalTimeNeeded) = 0;
    virtual void serve(int periodForDisplayMessage, int theTotalTimeNeeded) = 0;
    virtual void setMamma() = 0;
    virtual void goToNextState() = 0;
    virtual char* getTag() = 0;
};

#endif

---

#ifndef UNCLEANEDSTATE_H_
#define UNCLEANEDSTATE_H_

#include "Mamma.h"
#include "CleanedState.h"
#include "Callback.h"

class UncleanedState: public ChickenState {
private:
    Mamma* mamma;
    char* tag;

public:
    UncleanedState(Mamma* inMamma) {
        tag = new char[40];
        mamma = inMamma;
        strcpy(tag, "Uncleaned");
    }

    virtual ~UncleanedState() {
        delete[] tag;
    }

    void wash(int periodForDisplayMessage, int theTotalTimeNeeded) {
        cout << "Quá trình nấu ăn đang bắt đầu... hãy thưởng thức..." << endl;
        cout << "Gà đang được rửa.... vui lòng chờ..." << endl;
        (mamma->t).setTimeout([&]() {
            goToNextState();
        }, theTotalTimeNeeded);
    }

    void marinate(int periodForDisplayMessage, int theTotalTimeNeeded) {
        // Không có hành động
    }

    void cook(int periodForDisplayMessage, int theTotalTimeNeeded) {
        // Không có hành động
    }

    void serve(int periodForDisplayMessage, int theTotalTimeNeeded) {
        // Không có hành động
    }

    void goToNextState() {
        mamma->isUncleanedStateDone = true;
        (mamma->t).stop();
    }

    char* getTag() {
        return tag;
    }
};

#endif

---

// Tiếp tục với các lớp CleanedState, MarinatedState, CookedState và Mamma như trong mã nguồn ban đầu...

// ...

int main() {
    unique_ptr<Mamma> mamma = make_unique<Mamma>();
    mamma->startPreparation(true);
    return 0;
}

Phân tích mã nguồn

Mã nguồn trên cho thấy cách mà các trạng thái của gà được quản lý thông qua các lớp khác nhau. Với mỗi trạng thái, chúng ta có thể thực hiện các hành động khác nhau như rửa, ướp gia vị, nấu và phục vụ. Bằng cách này, mã nguồn trở nên dễ hiểu và dễ bảo trì hơn.

Thực tiễn tốt nhất

  • Giữ mã nguồn rõ ràng: Đảm bảo rằng các lớp trạng thái được định nghĩa rõ ràng với các hành động cụ thể.
  • Sử dụng tên lớp có ý nghĩa: Tên lớp nên phản ánh trạng thái mà nó đại diện để tăng tính dễ đọc.
  • Kiểm tra kỹ lưỡng: Thực hiện các bài kiểm tra để đảm bảo rằng các trạng thái chuyển đổi một cách chính xác.

Cạm bẫy thường gặp

  • Chuyển tiếp trạng thái không rõ ràng: Đảm bảo rằng các điều kiện chuyển tiếp giữa các trạng thái rõ ràng và dễ hiểu.
  • Thiếu xử lý sự cố: Cần có các biện pháp xử lý sự cố cho các tình huống bất ngờ xảy ra trong quy trình.

Mẹo hiệu suất

  • Tối ưu hóa thời gian chờ: Sử dụng các kỹ thuật tối ưu hóa để giảm thiểu thời gian chờ giữa các trạng thái.
  • Giảm thiểu tài nguyên tiêu thụ: Đảm bảo rằng các đối tượng được giải phóng sau khi không còn cần thiết để tiết kiệm tài nguyên.

Khắc phục sự cố

Nếu bạn gặp bất kỳ vấn đề nào với mã nguồn của mình, hãy kiểm tra các điều kiện chuyển tiếp giữa các trạng thái. Đảm bảo rằng các hàm được gọi đúng cách và không có bất kỳ lỗi biên dịch hoặc lỗi logic nào.

FAQ

Q: Mẫu thiết kế State có thể áp dụng ở đâu?
A: Mẫu thiết kế State có thể được áp dụng trong nhiều lĩnh vực, chẳng hạn như trò chơi, ứng dụng GUI, và các hệ thống điều khiển.

Q: Có cách nào khác để thực hiện quản lý trạng thái không?
A: Có, bạn có thể sử dụng các mẫu thiết kế khác như Mẫu thiết kế Strategy hoặc Mẫu thiết kế Observer tùy thuộc vào yêu cầu của ứng dụng.

Kết luận

Mẫu thiết kế State là một công cụ mạnh mẽ giúp quản lý hành vi của các đối tượng trong lập trình hướng đối tượng. Qua bài viết này, hy vọng bạn đã có thêm kiến thức và có thể áp dụng mẫu thiết kế này vào các dự án của mình. Đừng quên thử nghiệm và tìm hiểu thêm về các mẫu thiết kế khác để nâng cao kỹ năng lập trình của bạn!

Hãy chia sẻ những trải nghiệm của bạn với mẫu thiết kế State trong phần bình luận bên dưới!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào