Menu
CoddyTech

Pola State

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 100 dari 104.

Pola State memungkinkan sebuah object mengubah perilakunya saat state internalnya berubah, sehingga object tersebut tampak seolah-olah berubah class. Alih-alih menggunakan pernyataan percabangan yang rumit untuk menangani berbagai state, kamu mengenkapsulasi setiap state sebagai class terpisah.

Pola ini terdiri dari Context yang menyimpan referensi ke state saat ini, State interface yang mendefinisikan perilaku khusus untuk setiap state, dan Concrete States yang menerapkan perilaku untuk setiap state:

#include <iostream>
#include <memory>

class Document;  // Deklarasi awal

// Antarmuka State
class DocumentState {
public:
    virtual void publish(Document& doc) = 0;
    virtual std::string getName() const = 0;
    virtual ~DocumentState() = default;
};

// Konteks
class Document {
    std::unique_ptr<DocumentState> state;
public:
    Document();
    void setState(std::unique_ptr<DocumentState> newState) {
        state = std::move(newState);
    }
    void publish() { state->publish(*this); }
    std::string getStateName() const { return state->getName(); }
};

// State konkret
class Draft : public DocumentState {
public:
    void publish(Document& doc) override;
    std::string getName() const override { return "Draft"; }
};

class Review : public DocumentState {
public:
    void publish(Document& doc) override;
    std::string getName() const override { return "Review"; }
};

class Published : public DocumentState {
public:
    void publish(Document& doc) override {
        std::cout << "Already published\n";
    }
    std::string getName() const override { return "Published"; }
};

void Draft::publish(Document& doc) {
    std::cout << "Moving to review\n";
    doc.setState(std::make_unique<Review>());
}

void Review::publish(Document& doc) {
    std::cout << "Publishing document\n";
    doc.setState(std::make_unique<Published>());
}

Document::Document() : state(std::make_unique<Draft>()) {}

Setiap state menangani aksi publish() dengan cara yang berbeda dan bertanggung jawab untuk beralih ke state berikutnya. Document tidak perlu mengetahui logika transisi, Document hanya meneruskannya ke state saat ini. Ini menghilangkan pernyataan switch yang besar dan memudahkan penambahan state baru.

Gunakan State saat perilaku object sangat bergantung pada statusnya dan kamu memiliki banyak pernyataan percabangan yang memilih berdasarkan status object.

challenge icon

Tantangan

Mudah

Mari buat Pengendali Lampu Lalu Lintas menggunakan pola State. Kamu akan membuat sistem yang membuat lampu lalu lintas berputar melalui berbagai state (Red, Yellow, Green), dengan setiap state menentukan apa yang terjadi saat lampu berubah dan pesan apa yang ditampilkan. Ini adalah contoh klasik pola State: perilaku lampu lalu lintas sepenuhnya bergantung pada state-nya saat ini.

Kamu akan menyusun kodemu dalam tiga file:

  • TrafficLightState.h: Definisikan antarmuka state dan semua class state konkret.

    Buat class abstrak TrafficLightState dengan:

    • method virtual murni change(TrafficLight& light) yang menangani perpindahan ke state berikutnya
    • method virtual murni getColor() yang mengembalikan warna saat ini sebagai string
    • method virtual murni getAction() yang mengembalikan tindakan yang harus dilakukan pengemudi (misalnya, "Stop", "Caution", "Go")
    • destruktor virtual

    Implementasikan tiga state konkret:

    • RedState: warnanya "Red", tindakannya "Stop", berubah menjadi Green
    • YellowState: warnanya "Yellow", tindakannya "Caution", berubah menjadi Red
    • GreenState: warnanya "Green", tindakannya "Go", berubah menjadi Yellow

    Kamu memerlukan deklarasi awal untuk TrafficLight karena state-state tersebut merujuknya.

  • TrafficLight.h: Buat class konteks yang mempertahankan state saat ini.

    Class TrafficLight milikmu harus menyimpan std::unique_ptr<TrafficLightState> dan secara default dimulai dalam state Red. Implementasikan:

    • setState(std::unique_ptr<TrafficLightState> newState): mengubah state saat ini
    • change(): meneruskan pemanggilan ke method change pada state saat ini
    • display(): mencetak status lampu dengan format: [Color]: [Action]
  • main.cpp: Tunjukkan lampu lalu lintas yang berputar melalui berbagai state.

    Baca satu input: jumlah perubahan state yang harus dilakukan (bilangan bulat).

    Buat TrafficLight dan tampilkan state awalnya. Kemudian lakukan jumlah perubahan yang ditentukan, dengan menampilkan state setelah setiap perubahan.

Contohnya, dengan input 3:

Red: Stop
Green: Go
Yellow: Caution
Red: Stop

Dengan input 6:

Red: Stop
Green: Go
Yellow: Caution
Red: Stop
Green: Go
Yellow: Caution
Red: Stop

Perhatikan bagaimana lampu lalu lintas berputar melalui state-state-nya dalam pola yang dapat diprediksi: Red → Green → Yellow → Red. Setiap state mengetahui state mana yang berikutnya dan menangani transisinya sendiri. Class TrafficLight tidak memerlukan logika percabangan untuk menentukan apa yang terjadi. Class tersebut cukup meneruskan pemanggilan ke state yang sedang aktif.

Coba sendiri

#include <iostream>
#include "TrafficLight.h"

using namespace std;

int main() {
    // Baca jumlah perubahan status
    int numChanges;
    cin >> numChanges;
    
    // TODO: Buat object TrafficLight
    
    // TODO: Tampilkan status awal
    
    // TODO: Lakukan perubahan sebanyak jumlah yang ditentukan
    // Setelah setiap perubahan, tampilkan status saat ini
    
    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online