https://refactoring.guru/design-patterns/catalog
Method of super class for create object, which may be overided in the child classes.
class magicBox {
...
virtual coin* createCoin() = 0;
};
class euroMagicBox: public magicBox {
...
coin* createCoin() override {
// create euro
}
};
Abstract class provides methods for create one or more types of objects, the concrete implementation allow create concrete object for each type
class furnitureFactory {
public:
virtual chair createChair() = 0;
virtual table createTable() = 0;
};
class victorianFurnitureFactory: public furnitureFactory {
public:
chair* createChair() override {
// create victorian chair
}
};
Build complex object step by step. Different kinds of object can be built with using same steps.
class builder {
private:
product* product;
public:
// may be overrided in child classes for support different implemenation of build steps dependes on product
virtual buildStep1();
virtual buildStep2();
virtual buildStep3();
product* get();
};
class director {
...
product* partialBuild() {
builder.buildStep1();
return builder.get();
}
product* fullBuild() {
builder.buildStep1();
builder.buildStep2();
builder.buildStep3();
return builder.get();
}
};
Abstract class which provides clone method for correct copy each concrete implementation.
No need to change common code.
class shape {
public:
virtual shape* clone() = 0;
};
class rect: public shape {
private:
int x,y,x1,y1;
public:
shape* clone() {
// copy
}
};
Guaranty creation exactly one instance of object.
class singleton {
private:
static obj* val;
public:
singleton() = delete;
singleton(const singleton&) = delete;
static obj* get() {
if (val == nullptr) {
val = new obj();
}
return val;
}
};
Used for collaborate objects with incompatible interfaces.
class Target {
public:
virtual ~Target() = default;
virtual std::string Request() const {
return "Target: The default target's behavior.";
}
};
class Adaptee {
public:
std::string SpecificRequest() const {
return ".eetpadA eht fo roivaheb laicepS";
}
};
/**
* The Adapter makes the Adaptee's interface compatible with the Target's
* interface.
*/
class Adapter : public Target {
private:
Adaptee *adaptee_;
public:
Adapter(Adaptee *adaptee) : adaptee_(adaptee) {}
std::string Request() const override {
std::string to_reverse = this->adaptee_->SpecificRequest();
std::reverse(to_reverse.begin(), to_reverse.end());
return "Adapter: (TRANSLATED) " + to_reverse;
}
};
Used for split a large class or a set of closely related classes into two separate hierarchies—abstraction and implementation—which can be developed independently of each other. Archive it by switching from inheritance to the object composition.
class Implementation {
public:
virtual ~Implementation() {}
virtual std::string OperationImplementation() const = 0;
};
// add as many as you want, `ConcreteImplementations` not dependent on each other
class ConcreteImplementationA : public Implementation {
public:
std::string OperationImplementation() const override {
return "ConcreteImplementationA: Here's the result on the platform A.\n";
}
};
class ConcreteImplementationB : public Implementation {
public:
std::string OperationImplementation() const override {
return "ConcreteImplementationB: Here's the result on the platform B.\n";
}
};
class Abstraction {
/**
* @var Implementation
*/
protected:
Implementation* implementation_;
public:
Abstraction(Implementation* implementation) : implementation_(implementation) {
}
virtual ~Abstraction() {
}
virtual std::string Operation() const {
return "Abstraction: Base operation with:\n" +
this->implementation_->OperationImplementation();
}
};
class ExtendedAbstraction : public Abstraction {
public:
ExtendedAbstraction(Implementation* implementation) : Abstraction(implementation) {
}
std::string Operation() const override {
return "ExtendedAbstraction: Extended operation with:\n" +
this->implementation_->OperationImplementation();
}
};
void ClientCode(const Abstraction& abstraction) {
// ...
std::cout << abstraction.Operation();
// ...
}
Compose objects into tree structures and then work with these structures as if they were individual objects. Make sense only if object's hierarhy can be represented as a tree.
class Component {
protected:
Component *parent_;
public:
virtual ~Component() {}
void SetParent(Component *parent) {
this->parent_ = parent;
}
Component *GetParent() const {
return this->parent_;
}
virtual void Add(Component *component) {}
virtual void Remove(Component *component) {}
virtual bool IsComposite() const {
return false;
}
virtual std::string Operation() const = 0;
};
class Leaf : public Component {
public:
std::string Operation() const override {
return "Leaf";
}
};
class Composite : public Component {
protected:
std::list<Component *> children_;
public:
void Add(Component *component) override {
this->children_.push_back(component);
component->SetParent(this);
}
void Remove(Component *component) override {
children_.remove(component);
component->SetParent(nullptr);
}
bool IsComposite() const override {
return true;
}
std::string Operation() const override {
std::string result;
for (const Component *c : children_) {
if (c == children_.back()) {
result += c->Operation();
} else {
result += c->Operation() + "+";
}
}
return "Branch(" + result + ")";
}
};
Extend behavior with using wrapper (add exra actions to the API mthods).
class Component {
public:
virtual ~Component() {}
virtual std::string Operation() const = 0;
};
class ConcreteComponent : public Component {
public:
std::string Operation() const override {
return "ConcreteComponent";
}
};
class Decorator : public Component {
protected:
Component* component_;
public:
Decorator(Component* component) : component_(component) {
}
std::string Operation() const override {
return this->component_->Operation();
}
};
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component* component) : Decorator(component) {
}
std::string Operation() const override {
return "ConcreteDecoratorA(" + Decorator::Operation() + ")";
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* component) : Decorator(component) {
}
std::string Operation() const override {
return "ConcreteDecoratorB(" + Decorator::Operation() + ")";
}
};
void ClientCode(Component* component) {
// ...
std::cout << "RESULT: " << component->Operation();
// ...
}
Simplify interface of complex object(s)
class Subsystem1 {
public:
std::string Operation1() const {
return "Subsystem1: Ready!\n";
}
// ...
std::string OperationN() const {
return "Subsystem1: Go!\n";
}
};
class Subsystem2 {
public:
std::string Operation1() const {
return "Subsystem2: Get ready!\n";
}
// ...
std::string OperationZ() const {
return "Subsystem2: Fire!\n";
}
};
class Facade {
protected:
Subsystem1 *subsystem1_;
Subsystem2 *subsystem2_;
public:
Facade(
Subsystem1 *subsystem1 = nullptr,
Subsystem2 *subsystem2 = nullptr) {
this->subsystem1_ = subsystem1 ?: new Subsystem1;
this->subsystem2_ = subsystem2 ?: new Subsystem2;
}
~Facade() {
delete subsystem1_;
delete subsystem2_;
}
std::string Operation() {
std::string result = "Facade initializes subsystems:\n";
result += this->subsystem1_->Operation1();
result += this->subsystem2_->Operation1();
result += "Facade orders subsystems to perform the action:\n";
result += this->subsystem1_->OperationN();
result += this->subsystem2_->OperationZ();
return result;
}
};
void ClientCode(Facade *facade) {
// ...
std::cout << facade->Operation();
// ...
}
Used for fit more objects into the available amount of RAM by sharing common parts of state between multiple objects instead of keeping all of the data in each object.
struct SharedState
{
std::string brand_;
std::string model_;
std::string color_;
SharedState(const std::string &brand, const std::string &model, const std::string &color)
: brand_(brand), model_(model), color_(color)
{
}
friend std::ostream &operator<<(std::ostream &os, const SharedState &ss)
{
return os << "[ " << ss.brand_ << " , " << ss.model_ << " , " << ss.color_ << " ]";
}
};
struct UniqueState
{
std::string owner_;
std::string plates_;
UniqueState(const std::string &owner, const std::string &plates)
: owner_(owner), plates_(plates)
{
}
friend std::ostream &operator<<(std::ostream &os, const UniqueState &us)
{
return os << "[ " << us.owner_ << " , " << us.plates_ << " ]";
}
};
class Flyweight
{
private:
SharedState *shared_state_;
public:
Flyweight(const SharedState *shared_state) : shared_state_(new SharedState(*shared_state))
{
}
Flyweight(const Flyweight &other) : shared_state_(new SharedState(*other.shared_state_))
{
}
~Flyweight()
{
delete shared_state_;
}
SharedState *shared_state() const
{
return shared_state_;
}
void Operation(const UniqueState &unique_state) const
{
std::cout << "Flyweight: Displaying shared (" << *shared_state_ << ") and unique (" << unique_state << ") state.\n";
}
};
class FlyweightFactory
{
private:
std::unordered_map<std::string, Flyweight> flyweights_;
std::string GetKey(const SharedState &ss) const
{
return ss.brand_ + "_" + ss.model_ + "_" + ss.color_;
}
public:
FlyweightFactory(std::initializer_list<SharedState> share_states)
{
for (const SharedState &ss : share_states)
{
this->flyweights_.insert(std::make_pair<std::string, Flyweight>(this->GetKey(ss), Flyweight(&ss)));
}
}
Flyweight GetFlyweight(const SharedState &shared_state)
{
std::string key = this->GetKey(shared_state);
if (this->flyweights_.find(key) == this->flyweights_.end())
{
std::cout << "FlyweightFactory: Can't find a flyweight, creating new one.\n";
this->flyweights_.insert(std::make_pair(key, Flyweight(&shared_state)));
}
else
{
std::cout << "FlyweightFactory: Reusing existing flyweight.\n";
}
return this->flyweights_.at(key);
}
void ListFlyweights() const
{
size_t count = this->flyweights_.size();
std::cout << "\nFlyweightFactory: I have " << count << " flyweights:\n";
for (std::pair<std::string, Flyweight> pair : this->flyweights_)
{
std::cout << pair.first << "\n";
}
}
};
// ...
void AddCarToPoliceDatabase(
FlyweightFactory &ff, const std::string &plates, const std::string &owner,
const std::string &brand, const std::string &model, const std::string &color)
{
std::cout << "\nClient: Adding a car to database.\n";
const Flyweight &flyweight = ff.GetFlyweight({brand, model, color});
// The client code either stores or calculates extrinsic state and passes it
// to the flyweight's methods.
flyweight.Operation({owner, plates});
}
A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object.
class Subject {
public:
virtual void Request() const = 0;
};
class RealSubject : public Subject {
public:
void Request() const override {
std::cout << "RealSubject: Handling request.\n";
}
};
class Proxy : public Subject {
private:
RealSubject *real_subject_;
bool CheckAccess() const {
// Some real checks should go here.
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void LogAccess() const {
std::cout << "Proxy: Logging the time of request.\n";
}
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {
}
~Proxy() {
delete real_subject_;
}
void Request() const override {
if (this->CheckAccess()) {
this->real_subject_->Request();
this->LogAccess();
}
}
};
void ClientCode(const Subject &subject) {
// ...
subject.Request();
// ...
}
Pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.
class Handler {
public:
virtual Handler *SetNext(Handler *handler) = 0;
virtual std::string Handle(std::string request) = 0;
};
class AbstractHandler : public Handler {
private:
Handler *next_handler_;
public:
AbstractHandler() : next_handler_(nullptr) {
}
Handler *SetNext(Handler *handler) override {
this->next_handler_ = handler;
return handler;
}
std::string Handle(std::string request) override {
if (this->next_handler_) {
return this->next_handler_->Handle(request);
}
return {};
}
};
class MonkeyHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "Banana") {
return "Monkey: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
class SquirrelHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "Nut") {
return "Squirrel: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
class DogHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "MeatBall") {
return "Dog: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
void ClientCode(Handler &handler) {
std::vector<std::string> food = {"Nut", "Banana", "Cup of coffee"};
for (const std::string &f : food) {
std::cout << "Client: Who wants a " << f << "?\n";
const std::string result = handler.Handle(f);
if (!result.empty()) {
std::cout << " " << result;
} else {
std::cout << " " << f << " was left untouched.\n";
}
}
}
Turns a request into a stand-alone object that contains all information about the request. This transformation lets you pass requests as a method arguments, delay or queue a request’s execution, and support undoable operations.
class Command {
public:
virtual ~Command() {
}
virtual void Execute() const = 0;
};
class SimpleCommand : public Command {
private:
std::string pay_load_;
public:
explicit SimpleCommand(std::string pay_load) : pay_load_(pay_load) {
}
void Execute() const override {
std::cout << "SimpleCommand: See, I can do simple things like printing (" << this->pay_load_ << ")\n";
}
};
class Receiver {
public:
void DoSomething(const std::string &a) {
std::cout << "Receiver: Working on (" << a << ".)\n";
}
void DoSomethingElse(const std::string &b) {
std::cout << "Receiver: Also working on (" << b << ".)\n";
}
};
class ComplexCommand : public Command {
private:
Receiver *receiver_;
std::string a_;
std::string b_;
public:
ComplexCommand(Receiver *receiver, std::string a, std::string b) : receiver_(receiver), a_(a), b_(b) {
}
void Execute() const override {
std::cout << "ComplexCommand: Complex stuff should be done by a receiver object.\n";
this->receiver_->DoSomething(this->a_);
this->receiver_->DoSomethingElse(this->b_);
}
};
class Invoker {
private:
Command *on_start_;
Command *on_finish_;
public:
~Invoker() {
delete on_start_;
delete on_finish_;
}
void SetOnStart(Command *command) {
this->on_start_ = command;
}
void SetOnFinish(Command *command) {
this->on_finish_ = command;
}
void DoSomethingImportant() {
std::cout << "Invoker: Does anybody want something done before I begin?\n";
if (this->on_start_) {
this->on_start_->Execute();
}
std::cout << "Invoker: ...doing something really important...\n";
std::cout << "Invoker: Does anybody want something done after I finish?\n";
if (this->on_finish_) {
this->on_finish_->Execute();
}
}
};
Traverse elements of a collection without exposing its underlying representation.
template <typename T, typename U>
class Iterator {
public:
typedef typename std::vector<T>::iterator iter_type;
Iterator(U *p_data, bool reverse = false) : m_p_data_(p_data) {
m_it_ = m_p_data_->m_data_.begin();
}
void First() {
m_it_ = m_p_data_->m_data_.begin();
}
void Next() {
m_it_++;
}
bool IsDone() {
return (m_it_ == m_p_data_->m_data_.end());
}
iter_type Current() {
return m_it_;
}
private:
U *m_p_data_;
iter_type m_it_;
};
template <class T>
class Container {
friend class Iterator<T, Container>;
public:
void Add(T a) {
m_data_.push_back(a);
}
Iterator<T, Container> *CreateIterator() {
return new Iterator<T, Container>(this);
}
private:
std::vector<T> m_data_;
};
class Data {
public:
Data(int a = 0) : m_data_(a) {}
void set_data(int a) {
m_data_ = a;
}
int data() {
return m_data_;
}
private:
int m_data_;
};
void ClientCode() {
std::cout << "________________Iterator with int______________________________________" << std::endl;
Container<int> cont;
for (int i = 0; i < 10; i++) {
cont.Add(i);
}
Iterator<int, Container<int>> *it = cont.CreateIterator();
for (it->First(); !it->IsDone(); it->Next()) {
std::cout << *it->Current() << std::endl;
}
Container<Data> cont2;
Data a(100), b(1000), c(10000);
cont2.Add(a);
cont2.Add(b);
cont2.Add(c);
std::cout << "________________Iterator with custom Class______________________________" << std::endl;
Iterator<Data, Container<Data>> *it2 = cont2.CreateIterator();
for (it2->First(); !it2->IsDone(); it2->Next()) {
std::cout << it2->Current()->data() << std::endl;
}
delete it;
delete it2;
}
The pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object. To avoid complex dependencies between objects.
class BaseComponent;
class Mediator {
public:
virtual void Notify(BaseComponent *sender, std::string event) const = 0;
};
class BaseComponent {
protected:
Mediator *mediator_;
public:
BaseComponent(Mediator *mediator = nullptr) : mediator_(mediator) {
}
void set_mediator(Mediator *mediator) {
this->mediator_ = mediator;
}
};
class Component1 : public BaseComponent {
public:
void DoA() {
std::cout << "Component 1 does A.\n";
this->mediator_->Notify(this, "A");
}
void DoB() {
std::cout << "Component 1 does B.\n";
this->mediator_->Notify(this, "B");
}
};
class Component2 : public BaseComponent {
public:
void DoC() {
std::cout << "Component 2 does C.\n";
this->mediator_->Notify(this, "C");
}
void DoD() {
std::cout << "Component 2 does D.\n";
this->mediator_->Notify(this, "D");
}
};
class ConcreteMediator : public Mediator {
private:
Component1 *component1_;
Component2 *component2_;
public:
ConcreteMediator(Component1 *c1, Component2 *c2) : component1_(c1), component2_(c2) {
this->component1_->set_mediator(this);
this->component2_->set_mediator(this);
}
void Notify(BaseComponent *sender, std::string event) const override {
if (event == "A") {
std::cout << "Mediator reacts on A and triggers following operations:\n";
this->component2_->DoC();
}
if (event == "D") {
std::cout << "Mediator reacts on D and triggers following operations:\n";
this->component1_->DoB();
this->component2_->DoC();
}
}
};
void ClientCode() {
Component1 *c1 = new Component1;
Component2 *c2 = new Component2;
ConcreteMediator *mediator = new ConcreteMediator(c1, c2);
std::cout << "Client triggers operation A.\n";
c1->DoA();
std::cout << "\n";
std::cout << "Client triggers operation D.\n";
c2->DoD();
delete c1;
delete c2;
delete mediator;
}
Save and restore the previous state of an object without revealing the details of its implementation.
class Memento {
public:
virtual ~Memento() {}
virtual std::string GetName() const = 0;
virtual std::string date() const = 0;
virtual std::string state() const = 0;
};
class ConcreteMemento : public Memento {
private:
std::string state_;
std::string date_;
public:
ConcreteMemento(std::string state) : state_(state) {
this->state_ = state;
std::time_t now = std::time(0);
this->date_ = std::ctime(&now);
}
std::string state() const override {
return this->state_;
}
std::string GetName() const override {
return this->date_ + " / (" + this->state_.substr(0, 9) + "...)";
}
std::string date() const override {
return this->date_;
}
};
class Originator {
private:
std::string state_;
std::string GenerateRandomString(int length = 10) {
const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;
std::string random_string;
for (int i = 0; i < length; i++) {
random_string += alphanum[std::rand() % stringLength];
}
return random_string;
}
public:
Originator(std::string state) : state_(state) {
std::cout << "Originator: My initial state is: " << this->state_ << "\n";
}
void DoSomething() {
std::cout << "Originator: I'm doing something important.\n";
this->state_ = this->GenerateRandomString(30);
std::cout << "Originator: and my state has changed to: " << this->state_ << "\n";
}
Memento *Save() {
return new ConcreteMemento(this->state_);
}
void Restore(Memento *memento) {
this->state_ = memento->state();
std::cout << "Originator: My state has changed to: " << this->state_ << "\n";
delete memento;
}
};
class Caretaker {
private:
std::vector<Memento *> mementos_;
Originator *originator_;
public:
Caretaker(Originator* originator) : originator_(originator) {
}
~Caretaker() {
for (auto m : mementos_) delete m;
}
void Backup() {
std::cout << "\nCaretaker: Saving Originator's state...\n";
this->mementos_.push_back(this->originator_->Save());
}
void Undo() {
if (!this->mementos_.size()) {
return;
}
Memento *memento = this->mementos_.back();
this->mementos_.pop_back();
std::cout << "Caretaker: Restoring state to: " << memento->GetName() << "\n";
try {
this->originator_->Restore(memento);
} catch (...) {
this->Undo();
}
}
void ShowHistory() const {
std::cout << "Caretaker: Here's the list of mementos:\n";
for (Memento *memento : this->mementos_) {
std::cout << memento->GetName() << "\n";
}
}
};
void ClientCode() {
Originator *originator = new Originator("Super-duper-super-puper-super.");
Caretaker *caretaker = new Caretaker(originator);
caretaker->Backup();
originator->DoSomething();
caretaker->Backup();
originator->DoSomething();
caretaker->Backup();
originator->DoSomething();
std::cout << "\n";
caretaker->ShowHistory();
std::cout << "\nClient: Now, let's rollback!\n\n";
caretaker->Undo();
std::cout << "\nClient: Once more!\n\n";
caretaker->Undo();
delete originator;
delete caretaker;
}
Used for enable subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.
class IObserver {
public:
virtual ~IObserver(){};
virtual void Update(const std::string &message_from_subject) = 0;
};
class ISubject {
public:
virtual ~ISubject(){};
virtual void Attach(IObserver *observer) = 0;
virtual void Detach(IObserver *observer) = 0;
virtual void Notify() = 0;
};
class Subject : public ISubject {
public:
virtual ~Subject() {
std::cout << "Goodbye, I was the Subject.\n";
}
void Attach(IObserver *observer) override {
list_observer_.push_back(observer);
}
void Detach(IObserver *observer) override {
list_observer_.remove(observer);
}
void Notify() override {
std::list<IObserver *>::iterator iterator = list_observer_.begin();
HowManyObserver();
while (iterator != list_observer_.end()) {
(*iterator)->Update(message_);
++iterator;
}
}
void CreateMessage(std::string message = "Empty") {
this->message_ = message;
Notify();
}
void HowManyObserver() {
std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
}
void SomeBusinessLogic() {
this->message_ = "change message message";
Notify();
std::cout << "I'm about to do some thing important\n";
}
private:
std::list<IObserver *> list_observer_;
std::string message_;
};
class Observer : public IObserver {
public:
Observer(Subject &subject) : subject_(subject) {
this->subject_.Attach(this);
std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
this->number_ = Observer::static_number_;
}
virtual ~Observer() {
std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
}
void Update(const std::string &message_from_subject) override {
message_from_subject_ = message_from_subject;
PrintInfo();
}
void RemoveMeFromTheList() {
subject_.Detach(this);
std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
}
void PrintInfo() {
std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
}
private:
std::string message_from_subject_;
Subject &subject_;
static int static_number_;
int number_;
};
int Observer::static_number_ = 0;
void ClientCode() {
Subject *subject = new Subject;
Observer *observer1 = new Observer(*subject);
Observer *observer2 = new Observer(*subject);
Observer *observer3 = new Observer(*subject);
Observer *observer4;
Observer *observer5;
subject->CreateMessage("Hello World! :D");
observer3->RemoveMeFromTheList();
subject->CreateMessage("The weather is hot today! :p");
observer4 = new Observer(*subject);
observer2->RemoveMeFromTheList();
observer5 = new Observer(*subject);
subject->CreateMessage("My new car is great! ;)");
observer5->RemoveMeFromTheList();
observer4->RemoveMeFromTheList();
observer1->RemoveMeFromTheList();
delete observer5;
delete observer4;
delete observer3;
delete observer2;
delete observer1;
delete subject;
}
Lets an object alter its behavior when its internal state changes. It appears as if the object changed its class.
class Context;
class State {
protected:
Context *context_;
public:
virtual ~State() {
}
void set_context(Context *context) {
this->context_ = context;
}
virtual void Handle1() = 0;
virtual void Handle2() = 0;
};
class Context {
private:
State *state_;
public:
Context(State *state) : state_(nullptr) {
this->TransitionTo(state);
}
~Context() {
delete state_;
}
void TransitionTo(State *state) {
std::cout << "Context: Transition to " << typeid(*state).name() << ".\n";
if (this->state_ != nullptr)
delete this->state_;
this->state_ = state;
this->state_->set_context(this);
}
void Request1() {
this->state_->Handle1();
}
void Request2() {
this->state_->Handle2();
}
};
class ConcreteStateA : public State {
public:
void Handle1() override;
void Handle2() override {
std::cout << "ConcreteStateA handles request2.\n";
}
};
class ConcreteStateB : public State {
public:
void Handle1() override {
std::cout << "ConcreteStateB handles request1.\n";
}
void Handle2() override {
std::cout << "ConcreteStateB handles request2.\n";
std::cout << "ConcreteStateB wants to change the state of the context.\n";
this->context_->TransitionTo(new ConcreteStateA);
}
};
void ConcreteStateA::Handle1() {
{
std::cout << "ConcreteStateA handles request1.\n";
std::cout << "ConcreteStateA wants to change the state of the context.\n";
this->context_->TransitionTo(new ConcreteStateB);
}
}
void ClientCode() {
Context *context = new Context(new ConcreteStateA);
context->Request1();
context->Request2();
delete context;
}
Defines a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
class Strategy
{
public:
virtual ~Strategy() = default;
virtual std::string doAlgorithm(std::string_view data) const = 0;
};
class Context
{
private:
std::unique_ptr<Strategy> strategy_;
public:
explicit Context(std::unique_ptr<Strategy> &&strategy = {}) : strategy_(std::move(strategy))
{
}
void set_strategy(std::unique_ptr<Strategy> &&strategy)
{
strategy_ = std::move(strategy);
}
void doSomeBusinessLogic() const
{
if (strategy_) {
std::cout << "Context: Sorting data using the strategy (not sure how it'll do it)\n";
std::string result = strategy_->doAlgorithm("aecbd");
std::cout << result << "\n";
} else {
std::cout << "Context: Strategy isn't set\n";
}
}
};
class ConcreteStrategyA : public Strategy
{
public:
std::string doAlgorithm(std::string_view data) const override
{
std::string result(data);
std::sort(std::begin(result), std::end(result));
return result;
}
};
class ConcreteStrategyB : public Strategy
{
std::string doAlgorithm(std::string_view data) const override
{
std::string result(data);
std::sort(std::begin(result), std::end(result), std::greater<>());
return result;
}
};
void clientCode()
{
Context context(std::make_unique<ConcreteStrategyA>());
std::cout << "Client: Strategy is set to normal sorting.\n";
context.doSomeBusinessLogic();
std::cout << "\n";
std::cout << "Client: Strategy is set to reverse sorting.\n";
context.set_strategy(std::make_unique<ConcreteStrategyB>());
context.doSomeBusinessLogic();
}
Define algorithm in the super class, and override paticular steps in the sub classes.
class AbstractClass {
public:
void TemplateMethod() const {
this->BaseOperation1();
this->RequiredOperations1();
this->BaseOperation2();
this->Hook1();
this->RequiredOperation2();
this->BaseOperation3();
this->Hook2();
}
protected:
void BaseOperation1() const {
std::cout << "AbstractClass says: I am doing the bulk of the work\n";
}
void BaseOperation2() const {
std::cout << "AbstractClass says: But I let subclasses override some operations\n";
}
void BaseOperation3() const {
std::cout << "AbstractClass says: But I am doing the bulk of the work anyway\n";
}
virtual void RequiredOperations1() const = 0;
virtual void RequiredOperation2() const = 0;
virtual void Hook1() const {}
virtual void Hook2() const {}
};
class ConcreteClass1 : public AbstractClass {
protected:
void RequiredOperations1() const override {
std::cout << "ConcreteClass1 says: Implemented Operation1\n";
}
void RequiredOperation2() const override {
std::cout << "ConcreteClass1 says: Implemented Operation2\n";
}
};
class ConcreteClass2 : public AbstractClass {
protected:
void RequiredOperations1() const override {
std::cout << "ConcreteClass2 says: Implemented Operation1\n";
}
void RequiredOperation2() const override {
std::cout << "ConcreteClass2 says: Implemented Operation2\n";
}
void Hook1() const override {
std::cout << "ConcreteClass2 says: Overridden Hook1\n";
}
};
void ClientCode(AbstractClass *class_) {
// ...
class_->TemplateMethod();
// ...
}
Used for separate algorithms from the objects on which they operate.
class ConcreteComponentA;
class ConcreteComponentB;
class Visitor {
public:
virtual void VisitConcreteComponentA(const ConcreteComponentA *element) const = 0;
virtual void VisitConcreteComponentB(const ConcreteComponentB *element) const = 0;
};
class Component {
public:
virtual ~Component() {}
virtual void Accept(Visitor *visitor) const = 0;
};
class ConcreteComponentA : public Component {
public:
void Accept(Visitor *visitor) const override {
visitor->VisitConcreteComponentA(this);
}
std::string ExclusiveMethodOfConcreteComponentA() const {
return "A";
}
};
class ConcreteComponentB : public Component {
public:
void Accept(Visitor *visitor) const override {
visitor->VisitConcreteComponentB(this);
}
std::string SpecialMethodOfConcreteComponentB() const {
return "B";
}
};
class ConcreteVisitor1 : public Visitor {
public:
void VisitConcreteComponentA(const ConcreteComponentA *element) const override {
std::cout << element->ExclusiveMethodOfConcreteComponentA() << " + ConcreteVisitor1\n";
}
void VisitConcreteComponentB(const ConcreteComponentB *element) const override {
std::cout << element->SpecialMethodOfConcreteComponentB() << " + ConcreteVisitor1\n";
}
};
class ConcreteVisitor2 : public Visitor {
public:
void VisitConcreteComponentA(const ConcreteComponentA *element) const override {
std::cout << element->ExclusiveMethodOfConcreteComponentA() << " + ConcreteVisitor2\n";
}
void VisitConcreteComponentB(const ConcreteComponentB *element) const override {
std::cout << element->SpecialMethodOfConcreteComponentB() << " + ConcreteVisitor2\n";
}
};
void ClientCode(std::array<const Component *, 2> components, Visitor *visitor) {
// ...
for (const Component *comp : components) {
comp->Accept(visitor);
}
// ...
}