<( ̄︶ ̄)小小程序员

<( ̄︶ ̄)小小程序员

状态模式概述

状态模式是一种行为型设计模式,它可以让一个对象在其内部状态发生变化时更改其行为。通过将每个状态封装成一个独立的类,我们可以使状态之间互相独立,并且使得状态的切换变得更加灵活、可扩展。(多个状态之间可以相互转换)
在状态模式中,我们通常会定义一个抽象状态类(Abstract State),以及多个具体状态类(Concrete States)。每个具体状态都会实现抽象状态类中定义的各种操作,并且在需要时执行状态转换。
此外,还有一个环境类(Context),它包含了当前状态,并且在状态发生变化时调用各个状态类的方法来实现状态转换。因为这些状态类都实现了同一个接口,所以环境类不需要知道具体状态的细节,只需要调用相应的方法即可。

如何理解状态类和环境类

电视遥控器的例子

一个电视遥控器。电视遥控器有三种状态:开机状态、关机状态和静音状态。我们可以通过简单地按遥控器上的按钮来更改状态。为了实现这个功能,首先我们需要定义一个抽象状态类,该类将定义所有可能的操作:

class TVState {
public:
    virtual void onButtonPressed(TVRemote* remote) = 0;
    virtual void offButtonPressed(TVRemote* remote) = 0;
    virtual void muteButtonPressed(TVRemote* remote) = 0;
};

TVState中包含了三种操作:开机、关机和静音。这些操作在不同的状态下可能会有不同的实现方式,因此我们需要在具体状态类中进行实现。

// 具体状态类:开机状态
class OnState : public TVState {
public:
    void onButtonPressed(TVRemote* remote) override {
        std::cout << "The TV is already on." << std::endl;
    }

    void offButtonPressed(TVRemote* remote) override {
        std::cout << "Turning off the TV." << std::endl;
        remote->setState(new OffState());
    }

    void muteButtonPressed(TVRemote* remote) override {
        std::cout << "Muting the TV." << std::endl;
        remote->setState(new MuteState());
    }
};

// 具体状态类:关机状态
class OffState : public TVState {
public:
    void onButtonPressed(TVRemote* remote) override {
        std::cout << "Turning on the TV." << std::endl;
        remote->setState(new OnState());
    }

    void offButtonPressed(TVRemote* remote) override {
        std::cout << "The TV is already off." << std::endl;
    }

    void muteButtonPressed(TVRemote* remote) override {
        std::cout << "Cannot mute the TV when it's turned off." << std::endl;
    }
};

// 具体状态类:静音状态
class MuteState : public TVState {
public:
    void onButtonPressed(TVRemote* remote) override {
        std::cout << "Unmuting the TV." << std::endl;
        remote->setState(new OnState());
    }

    void offButtonPressed(TVRemote* remote) override {
        std::cout << "Turning off the TV." << std::endl;
        remote->setState(new OffState());
    }

    void muteButtonPressed(TVRemote* remote) override {
        std::cout << "The TV is already muted." << std::endl;
    }
};

在这些具体状态类中,我们重写了TVState中定义的所有操作,并且在需要时执行状态转换。例如,在开机状态下按下静音键会将遥控器的状态更改为“静音状态”。
接下来,让我们定义环境类(Context):

class TVRemote {
private:
    TVState* currentState;

public:
    TVRemote() {
        currentState = new OffState();
    }

    void setState(TVState* state) {
        currentState = state;
    }

    void pressOnButton() {
        currentState->onButtonPressed(this);
    }

    void pressOffButton() {
        currentState->offButtonPressed(this);
    }

    void pressMuteButton() {
        currentState->muteButtonPressed(this);
    }
};

在环境类中,我们维护了当前状态,并且在状态发生变化时调用相应的具体状态类方法。我们还定义了三个按键操作:开机、关机和静音。
现在,我们可以使用电视遥控器来测试状态模式的实现了:

int main() {
    TVRemote remote;

    remote.pressOnButton();    // Turning on the TV.
    remote.pressOnButton();    // The TV is already on.
    remote.pressMuteButton();  // Muting the TV.
    remote.pressMuteButton();  // The TV is already muted.
    remote.pressOffButton();   // Turning off the TV.
    remote.pressOffButton();   // The TV is already off.
    remote.pressMuteButton();  // Cannot mute the TV when it's turned off.
    remote.pressOnButton();    // Turning on the TV.
    remote.pressMuteButton();  // Unmuting the TV.

    return 0;
}

通过上面的代码,我们可以看到当我们按下不同的键时,电视遥控器的状态会发生相应的变化。

完整代码

remote.cpp

#include "remote.h"
#include "state.h"

TVRemote::TVRemote(TVState* State )
{
    currentState = State;
}

void TVRemote::setState(TVState* state)
{
    currentState = state;
}

void TVRemote::pressOnButton()
{
    currentState->onButtonPressed(this);
}

void TVRemote::pressOffButton()
{
    currentState->offButtonPressed(this);
}

void TVRemote::pressMuteButton()
{
    currentState->muteButtonPressed(this);
}

remote.h

#pragma once
class TVState; //这里没声明,报了一堆错

class TVRemote
{
private:
    TVState* currentState;

public:
    TVRemote(TVState* State);

    void setState(TVState* state);

    void pressOnButton();

    void pressOffButton();

    void pressMuteButton();
};

state.h

#pragma once
#include"remote.h"


class TVState {
public:
    virtual void onButtonPressed(TVRemote* remote) = 0; // 开机
    virtual void offButtonPressed(TVRemote* remote) = 0; // 关机
    virtual void muteButtonPressed(TVRemote* remote) = 0; // 静音
};

// 具体状态类:关机状态
class OffState : public TVState
{
public:
    void onButtonPressed(TVRemote* remote) override;
    void offButtonPressed(TVRemote* remote) override;
    void muteButtonPressed(TVRemote* remote) override;
};

// 具体状态类:开机状态
class OnState : public TVState
{
public:
    void onButtonPressed(TVRemote* remote) override;
    void offButtonPressed(TVRemote* remote) override;
    void muteButtonPressed(TVRemote* remote) override;
};

// 具体状态类:静音状态
class MuteState : public TVState {
public:
    void onButtonPressed(TVRemote* remote) override;
    void offButtonPressed(TVRemote* remote) override;
    void muteButtonPressed(TVRemote* remote) override;
};

state.cpp

#include<iostream>
#include "state.h"
#include "remote.h"


// 具体状态类:关机状态
void OffState::onButtonPressed(TVRemote* remote) 
{
    std::cout << "Turning on the TV." << std::endl;
    remote->setState(new OnState());
}

void OffState::offButtonPressed(TVRemote* remote) 
{
    std::cout << "The TV is already off." << std::endl;
}

void OffState::muteButtonPressed(TVRemote* remote)
{
    std::cout << "Cannot mute the TV when it's turned off." << std::endl;
}

// 具体状态类:开机状态
void OnState::onButtonPressed(TVRemote* remote) 
{
    std::cout << "The TV is already on." << std::endl;
}

void OnState::offButtonPressed(TVRemote* remote) 
{
    std::cout << "Turning off the TV." << std::endl;
    remote->setState(new OffState());
}

void OnState::muteButtonPressed(TVRemote* remote)
{
    std::cout << "Muting the TV." << std::endl;
    remote->setState(new MuteState());
}


// 具体状态类:静音状态
void MuteState::onButtonPressed(TVRemote* remote)
{
    std::cout << "Unmuting the TV." << std::endl;
    remote->setState(new OnState());
}

void MuteState::offButtonPressed(TVRemote* remote) 
{
    std::cout << "Turning off the TV." << std::endl;
    remote->setState(new OffState());
}

void MuteState::muteButtonPressed(TVRemote* remote)
{
    std::cout << "The TV is already muted." << std::endl;
}

main.cpp

#include <iostream>
using namespace std;
#include "state.h"
#include "remote.h"

int main() {
    TVState* off = new MuteState;
    TVRemote remote(off);

    remote.pressOnButton();    // Turning on the TV.
    remote.pressOnButton();    // The TV is already on.
    remote.pressMuteButton();  // Muting the TV.
    remote.pressMuteButton();  // The TV is already muted.
    remote.pressOffButton();   // Turning off the TV.
    remote.pressOffButton();   // The TV is already off.
    remote.pressMuteButton();  // Cannot mute the TV when it's turned off.
    remote.pressOnButton();    // Turning on the TV.
    remote.pressMuteButton();  // Unmuting the TV.

    return 0;
}

【30】c++设计模式——>状态模式-LMLPHP

10-27 03:47