#include <iostream>
#include <sstream>
#include <cstdio>
#include <ctime>
#include <chrono>
#include <thread>
class ContextInterface{
public:
int NContext;
};
class StrategyInterface{
public:
virtual ~StrategyInterface( void ){};
virtual void AlgorithmProcedure( const ContextInterface& context ) = 0;
};
class ConcreteStrategy_B : public StrategyInterface{
class dtor{
public:
~dtor( void ){
if( ConcreteStrategy_B::pInst )
delete ConcreteStrategy_B::pInst;
ConcreteStrategy_B::pInst = nullptr;
}
};
private:
ConcreteStrategy_B( void ) {}
~ConcreteStrategy_B( void ){StrategyInterface::~StrategyInterface();}
public:
explicit ConcreteStrategy_B( const ConcreteStrategy_B&) = delete;
ConcreteStrategy_B( ConcreteStrategy_B&&) = delete;
virtual void AlgorithmProcedure( const ContextInterface& context ) override{
char _MsgBuf[ 64 ];
sprintf( _MsgBuf,
"AlgorithmProcedure B is functioning using NContext:\t%d\n",
context.NContext );
std::ostringstream oss;
oss << _MsgBuf;
std::cout << oss.str();
}
static ConcreteStrategy_B& getInstance( void ){
if( !pInst ) {
pInst = new ConcreteStrategy_B;
static dtor d;
}
return *pInst;
}
protected:
static ConcreteStrategy_B *pInst;
};
ConcreteStrategy_B *ConcreteStrategy_B::pInst = nullptr;
class ConcreteStrategy_A : public StrategyInterface{
class dtor{
public:
~dtor( void ){
if( ConcreteStrategy_A::pInst )
delete ConcreteStrategy_A::pInst;
ConcreteStrategy_A::pInst = nullptr;
}
};
private:
ConcreteStrategy_A( void ){}
~ConcreteStrategy_A( void ){ StrategyInterface::~StrategyInterface();}
public:
explicit ConcreteStrategy_A( const ConcreteStrategy_A&) = delete;
ConcreteStrategy_A( ConcreteStrategy_A&&) = delete;
virtual void AlgorithmProcedure( const ContextInterface& context ) override{
char _MsgBuf[ 64 ];
sprintf( _MsgBuf,
"AlgorithmProcedure A is functioning using NContext:\t%d\n",
context.NContext );
std::ostringstream oss;
oss << _MsgBuf;
std::cout << oss.str();
}
static ConcreteStrategy_A& getInstance( void ){
if( !pInst ){
pInst = new ConcreteStrategy_A;
static dtor d;
}
return *pInst;
}
protected:
static ConcreteStrategy_A *pInst;
};
ConcreteStrategy_A *ConcreteStrategy_A::pInst = nullptr;
class StrategyFactory{
public:
virtual StrategyInterface *getConcreteStrategy( void ) const = 0;
virtual ~StrategyFactory( void ){}
};
class StrategyAFactory : public StrategyFactory{
public:
virtual StrategyInterface *getConcreteStrategy( void ) const override{
puts("Strategy A Factory produced a ConcretAlgorithm A");
return &ConcreteStrategy_A::getInstance();
}
};
class StrategyBFactory : public StrategyFactory{
public:
virtual StrategyInterface *getConcreteStrategy( void ) const override{
puts("Strategy B Factory produced a ConcretAlgorithm B");
return &ConcreteStrategy_B::getInstance();
}
};
class WidgetApplication{
protected:
StrategyInterface *pStrategy;
public:
WidgetApplication( const StrategyFactory *factory ){
pStrategy = factory->getConcreteStrategy();
puts("WidgetApplication Strategy initialized by factory");
}
void StrategySetter( const StrategyFactory* factory){
pStrategy = factory->getConcreteStrategy();
puts("WidgetApplication Strategy altered by factory");
}
void function( void ){
srand( (unsigned int )time( nullptr ));
ContextInterface context{ rand() % 1000 + 1 };
pStrategy->AlgorithmProcedure( context );
}
};
int main( void ){
StrategyAFactory stratAFact;
StrategyBFactory stratBFact;
WidgetApplication WApp( &stratAFact );
puts( "------------------------");
WApp.function();
puts( "------------------------");
std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
WApp.StrategySetter( &stratBFact );
puts( "------------------------");
WApp.function();
return 0;
}