Avoid public `SetState()` interface in state pattern implementation in C++ - c++

The state pattern
itself is really nice pattern for implementing state machines because it allows to encapsulate state transitions logic in states themselves and adding a new state is actually becomes easier because you need to make changes only in relevant states.
But, it is usually avoided in description how should states be changed.
If you implement state change logic in Context then whole the point of pattern is missed, but if you implement state change logic in states, that means you need to set a new state in Context.
The most common way is to add the public method to Context SetState() and pass reference to Context to the state object, so it will be able to set a new state, but essentially it will allow the user to change state outside the state machine.
To avoid it I came to the following solutions:
class IContext {
public:
virtual void SetState(unique_ptr<IState> newState) = 0;
}
class Context : public IContext {
private:
virtual void SetState(unique_ptr<IState> newState) override { ... };
}
But in general changing the method scope in derived class doesn't look really good.
Is there another way to hide this interface (friend class is not an option because it requires to change the Context class for each state being added)?

You could consider having the handler handle()returning the next state...
class IState {
public:
virtual unique_ptr<IState> handle(Context&) = 0;
};
class StateA : public IState {
private:
// presented inline for simplicity, but should be in .cpp
// because of circular dependency.
//
virtual unique_ptr<IState> handle(Context& ctx) override
{
//...
if (/*...*/)
return make_unique(StateB{});
//... including other state switch..
return { nullptr }; // returning null indicates no state change,
// returning unique_ptr<>(this) is not really an option.
}
};

The goal of the state pattern is to hide/encapsulate different implementations from the caller.However, caller only needs to know what type of implementation it needs.

Not sure how much this helps, but I just implemented a sample state machine in C# that uses the observer pattern and a tiny bit of reflection to get a very clean and encapsulated implementation of the state pattern.
Context.cs:
using System;
using System.Collections.Generic;
using System.Linq;
public class Context
{
State State { get; set; }
List<State> States { get; }
public Context()
{
States = new()
{
new HappyState(),
new SadState(),
};
SetState<HappyState>();
}
void DoSomething() => State?.DoSomething();
string ReturnSomething() => State?.ReturnSomething();
void SetState<StateType>() where StateType : State => SetState(typeof(StateType));
void SetState(Type stateType)
{
if (!stateType.IsSubclassOf(typeof(State))) return;
var nextState = States.Where(e => e.GetType() == stateType).First();
if (nextState is null) return;
if (State is not null)
{
State?.ExitState();
State.ChangeRequested -= OnChangeRequested;
}
State = nextState;
State.ChangeRequested += OnChangeRequested;
State.EnterState();
}
void OnChangeRequested(Type stateType) => SetState(stateType);
}
State.cs:
using System;
public abstract class State
{
public event Action<Type> ChangeRequested;
protected void SetState<StateType>() where StateType : State
{
ChangeRequested?.Invoke(typeof(StateType));
}
public virtual void EnterState() { }
public virtual void ExitState() { }
public virtual void DoSomething() { }
public virtual string ReturnSomething() => "";
}
You can then use this Syntax in either the Context or any State
SetState<HappyState>();
Link to Repository

Related

How to implement the State design pattern?

Let's say I am going to implement (in the C++) following finite state machine consisting of 5 states where the transitions between the states occur based on value of 6 boolean flags. In each of the states only a couple of the total number of the boolean flags is relevant e.g. in the State_A the transition into the State_B is conditional by following condition: flag_01 == true && flag_02 == true and the value of the rest of the flags is irrelevant.
I would like to exploit the State design pattern for implementation of the state machine
I have unfortunately stuck at the very beginning. Namely on definition of the interface of the common base class for all the state subclasses. It seems to me that my situation is little bit different from the examples mentioned in the literature where the state transitions occur based on single events with a guard condition. Can anybody give me an advice how to define the interface for the common base class in my situation where the transitions between states occur based on logic expressions with several operands?
You can create some reducer which will decide what state should be user. Let me show an example via C#.
This is an abstraction of state:
public interface IAtmMachineState
{
void Execute();
}
and its concrete states:
public class WithdrawState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("You are taking money");
}
}
public class DepositState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("You are putting money");
}
}
public class SleepState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("Insert your card");
}
}
and this is context of state:
public class AtmStateContext
{
private IAtmMachineState _currentState;
public AtmStateContext()
{
_currentState = new SleepState();
}
public void SetState(IAtmMachineState currentState)
{
_currentState = currentState;
}
public void Execute()
{
_currentState.Execute();
}
}
And this is a reducer which can take parameters:
public class StateReducer
{
public IAtmMachineState Get(int a, string b)
{
if (a == 0)
return new WithdrawState();
else if (!string.IsNullOrEmpty(b))
return new DepositState();
return new SleepState();
}
}
And it can be used like this:
AtmStateContext atmState = new AtmStateContext();
StateReducer stateReducer = new StateReducer();
atmState.SetState(stateReducer.Get(1, ""));
atmState.Execute(); // OUTPUT: insert your card

State Machine Change State

I'm continuously running into the same problem, and can't fix it even when looking through tutorials.
I've "set up" my State machine, but I can't transition between states.
Here is my StateMachine:
class StateMachine
{
State* m_State;
public:
StateMachine();
~StateMachine();
void changeState(State* state);
};
And here is an example State:
class A : State
{
public:
A();
~A();
void handleInput(int a);
}
If I pass a = 1 into A::handleInput() I want to transition to State B. But when I implement it I can't access the StateMachine from A::handleInput(), making me scrub my head in agony.
But when I implement it I can't access the StateMachine from A::handleInput()
Well, that's a well known problem with the State Pattern, that there's no mention how to keep the state classes in track with an enclosing State Machine.
IMO, that's one of the valid use cases to consider the StateMachine class as being implemented as a Singleton.
This way it's instance would be accessible from any Stateclass implementation.
As I'm talking in terms of Design Patterns here, the State classes could be designed with help of the Flyweight Pattern, since they're usually stateless themselves.
I've once driven all that into a c++ template framework, which abstracts the interfaces of State and State Machine (see link below).
Here's a short code example by these means:
StateMachine.h
struct State {
virtual void handleInput(int x) = 0;
virtual ~State() {} = 0;
};
class StateMachine {
State* m_State;
StateMachine();
public:
static StateMachine& instance() {
static StateMachine theInstance;
return theInstance;
}
void changeState(State* state) {
m_State = state;
}
void triggerInput(int x) {
m_State->handleInput(x);
}
};
StateA.h
#include "StateMachine.h"
class StateB;
extern StateB* stateB;
class StateA : public State {
public:
virtual ~StateA() {}
virtual void handleInput(int x) {
if(x == 1) {
// Change to StateB
StateMachine::instance.changeState(stateB);
}
else {
// Do something with x
}
}
};
I omit the definition od StateB here, should be the same manner as StateA.
References:
C++ Singleton Design Pattern
State machine template class framework for C++
I've taken a look at the Sourcemaking example and for me the implementation example really sucks; having to create new instances upon every state change:
https://sourcemaking.com/design_patterns/state/cpp/1
Personally as someone who's designed state machines in electronics with JK flip flops, I would use a similar but semantically different approach. The complexity in state machines involves the action performed according to the state and input; typically in C you would do this with lots of switch statements and possibly arrays describing how to handle the current state and new input aka event.
So to me the OO approach to this would be to model the event handler. This would have an interface which describes the format of the inputs. You then have different implementations of that interface for each different state. With that, the state machine can simply implement a collection of states to event handlers - array, vector or map. Although the handlers still may contain case statements, the overall spaghettiness is very much reduced. You can easily extend the design with new state handlers as and when necessary:
So you could have something like this:
#include <map>
typedef enum
{
//TODO : state list, e.g.
eOff,
eOn
}
teCurrentState;
typedef struct
{
//TODO : Add inputs here, e.g.
bool switch1;
}
tsInputDesc;
typedef struct
{
//TODO : Add outputs here, e.g.
bool relay1;
}
tsOutputDesc;
// ------------------------------------------------
class IEventHandler
{
public:
virtual ~IEventHandler() {}
// returns new state
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) = 0;
};
// ------------------------------------------------
class OnStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class OffStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class StateMachine
{
protected:
teCurrentState mCurrentState;
std::map<teCurrentState, IEventHandler*> mStateHandlers;
void makeHandlers()
{
mStateHandlers[eOff] = new OffStateHandler();
mStateHandlers[eOn] = new OnStateHandler();
}
public:
StateMachine()
{
makeHandlers();
mCurrentState = eOff;
}
void handleInput(tsInputDesc const& input, tsOutputDesc output)
{
teCurrentState newState = mStateHandlers[mCurrentState]->handleInput(input, output);
mCurrentState = newState;
}
};
// ------------------------------------------------
void runFsm()
{
StateMachine fsm;
tsInputDesc input;
tsOutputDesc output;
bool alive = true;
while (alive)
{
// TODO : set input according to....inputs (e.g. read I/O port etc)
fsm.handleInput(input, output);
// TODO : use output
}
}

How to decouple process in business layer

I am facing a problem that, for some business processes the sequence of invoking business objects and methods may change frequently. So I came up with something similar to the below:(Sorry somehow I can't post image..., I tried to express them in the below text)
Business Objects:
Object1, Object2
Methods: M1, M2, M3, M4
Processes: P1 (M1 > M2 > M3), P2 (M2 > M3 > if M3 return true then M4 else end)
In this case I am using .NET 3.5. I create some classes to represent processes, which contains those sequences I mentioned. It works. But the problem is I need to compile every time when process changed. It would be much better if I could configure it by some sort of XML.
I have heard about jBPM for Java, Workflow Foundation for .NET but not sure if they fit my needs, or would they be overkill. I even don't what keyword to search in Google. Could anyone advice what technology I should use to solve this issue? Or just point me to some websites or books? Thanks in advance.
A common way to decouple software layers is by using interfaces as stated by Dependency Inversion Principle. In you case you could abstract the process concept using an interface and implement the logic in the implementation of that interface.
when you need change the logic of the process you can create a new implementation of that interface. You can use any IoC framework to inject what implementation you want to use
below is showed just a simple way to do that:
public interface IMethod
{
void M1();
string M2();
void M3();
void M4();
}
public interface IProcess
{
IMethod Method { get; set; }
void P1();
void P2();
}
public class Process : IProcess
{
public IMethod Method
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public void P1()
{
Method.M1();
Method.M2();
}
public void P2()
{
if(Method.M2()==string.Empty)
{
Method.M3();
}
}
}
public class AnotherProcess : IProcess
{
public IMethod Method
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public void P1()
{
Method.M4();
}
public void P2()
{
Method.M2();
Method.M4();
}
}
public class UseProcess
{
private IProcess _process;
//you can inject the process dependency if you need use a different implementation
public UseProcess(IProcess process)
{
_process = process;
}
public void DoSomething()
{
_process.P1();
}
}

Testable design with COM objects

What is a good way to design for testing and extensibility when a component used to complete a task could either be a COM component or a .NET component? Does it make sense to wrap the COM component completely and extract an interface? Here is a simple, completely contrived, RCW interface on a COM component, where "abc" is the acronym for the component maker:
public interface IComRobot
{
void abcInitialize(object o);
void abcSet(string s, object o);
void abcBuild();
void abcExit();
}
To me, the fact that the provider of the component chose to prefix all methods with something indicating their company is somewhat irritating. The problem is, I want to define other Robot components that perform the same actions, but the underlying implementation is different. It would be completely confusing to Robot builders to have to implement "abcAnything".
How should I go about building a RobotFactory with a simple implementation that works like this?
public class RobotFactory
{
public static IRobot Create(int i)
{
// // problem because ComRobot implements IComRobot not IRobot
if (i == 0) return new ComRobot();
if (i == 1) return new AdvancedRobot();
return new SimpleRobot();
}
}
Should I bite the bullet and accept the abc prefix in my interface, thus confusing robot implementers? Should I force a dependency on the Robot consumer to know when they are using the COM robot? None of these seem ideal. I'm thinking about an additional level of abstraction (that can solve everything, right?). Something like so:
public interface IRobot : IDisposable
{
void Initialize(object o);
void Set(string s, object o);
void Build();
void Exit();
}
public class ComRobotWrapper: IRobot
{
private readonly IComRobot m_comRobot;
public ComRobotWrapper()
{
m_comRobot = ComRobotFactory.Create();
}
public void Initialize(object o)
{
m_comRobot.abcInitialize(o);
}
public void Set(string s, object o)
{
m_comRobot.abcSet(s, o);
}
public void Build()
{
m_comRobot.abcBuild();
}
public void Exit()
{
m_comRobot.abcExit();
}
public void Dispose()
{
//...RELEASE COM COMPONENT
}
}
public class ComRobotFactory
{
public static IComRobot Create()
{
return new ComRobot();
}
}
I would then alter and use the RobotFactory like so:
public class RobotFactory
{
public static IRobot Create(int i)
{
if (i == 0) return new ComRobotWrapper();
if (i == 1) return new AdvancedRobot();
return new SimpleRobot();
}
}
public class Tester
{
// local vars loaded somehow
public void Test()
{
using (IRobot robot = RobotFactory.Create(0))
{
robot.Initialize(m_configuration);
robot.Set(m_model, m_spec);
robot.Build();
robot.Exit();
}
}
}
I'm interested in opinions on this approach. Do you recommend another approach? I really don't want to take on a DI framework, so that is out of scope. Are the pitfalls in testability? I appreciate you taking the time to consider this lengthy issue.
That looks spot on to me. You are creating an interface that is right for your domain / application, and implementing it in terms of a thrid party component.

Resolving a Forward Declaration Issue Involving a State Machine in C++

I've recently returned to C++ development after a hiatus, and have a question regarding
implementation of the State Design Pattern. I'm using the vanilla pattern, exactly as
per the GoF book.
My problem is that the state machine itself is based on some hardware used as part of
an embedded system - so the design is fixed and can't be changed. This results in a
circular dependency between two of the states (in particular), and I'm trying to
resolve this. Here's the simplified code (note that I tried to resolve this by using
headers as usual but still had problems - I've omitted them in this code snippet):
#include <iostream>
#include <memory>
using namespace std;
class Context
{
public:
friend class State;
Context() { }
private:
State* m_state;
};
class State
{
public:
State() { }
virtual void Trigger1() = 0;
virtual void Trigger2() = 0;
};
class LLT : public State
{
public:
LLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class ALL : public State
{
public:
ALL() { }
void Trigger1() { new LLT(); }
void Trigger2() { new DH(); }
};
// DL needs to 'know' about DH.
class DL : public State
{
public:
DL() { }
void Trigger1() { new ALL(); }
void Trigger2() { new DH(); }
};
class HLT : public State
{
public:
HLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class AHL : public State
{
public:
AHL() { }
void Trigger1() { new DH(); }
void Trigger2() { new HLT(); }
};
// DH needs to 'know' about DL.
class DH : public State
{
public:
DH () { }
void Trigger1() { new AHL(); }
void Trigger2() { new DL(); }
};
int main()
{
auto_ptr<LLT> llt (new LLT);
auto_ptr<ALL> all (new ALL);
auto_ptr<DL> dl (new DL);
auto_ptr<HLT> hlt (new HLT);
auto_ptr<AHL> ahl (new AHL);
auto_ptr<DH> dh (new DH);
return 0;
}
The problem is basically that in the State Pattern, state transitions are made by
invoking the the ChangeState method in the Context class, which invokes the
constructor of the next state.
Because of the circular dependency, I can't invoke the constructor because it's
not possible to pre-define both of the constructors of the 'problem' states.
I had a look at this article, and the template method which seemed to be the ideal solution - but it doesn't compile and my knowledge of templates is a rather limited...
The other idea I had is to try and introduce a Helper class to the subclassed states,
via multiple inheritance, to see if it's possible to specify the base class's constructor
and have a reference to the state subclasse's constructor. But I think that was rather
ambitious...
Finally, would a direct implmentation of the Factory Method Design Pattern be the best way
to resolve the entire problem?
You can define the member functions outside of the class definitions, e.g.,
class DL : public State
{
public:
void Trigger2();
};
inline void DL::Trigger2() { new DH(); }
Define the member functions that rely on later class definitions after those classes are defined. The inline keyword is only necessary if you define the member function outside of the class in the header file.
As an aside, why are you just using new DH() in your functions; you're leaking memory everywhere!