понедельник, 10 февраля 2014 г.

Команда(Command)

Инкапсулирует запрос как объект

#include <iostream>
#include <vector>
using namespace std;

class Command
{
public:
virtual ~Command() {}
virtual void operator()() = 0;
};

class Add : public Command
{
public:
Add(int& a) : num(a) {}
virtual void operator()() { cout << "num + a" << endl; num += 20; }
private:
int& num;
};

class Multiply : public Command
{
public:
Multiply(int& a) : num(a) {}
virtual void operator()() { cout << "num * a" << endl; num *= 3; }
private:
int& num;
};

class Exe  ///Главный объект, который знает о получателе и инициаторе
{
public:
Exe(int a) : num(a) {}
void pushAddCommand() { commands.push_back(new Add(num)); }
void pushMultyCommand() { commands.push_back(new Multiply(num)); }
void ExecuteAllCommands() {for (int i = 0; i < commands.size(); ++i) (*commands[i])();}
int getNum() const {return num;}
private:
int num;  //в моем случае получателем выступает данный инт
vector<Command*> commands;
};

int main()
{
Exe obj(20);
obj.pushAddCommand();
obj.pushMultyCommand();
obj.ExecuteAllCommands();
cout << obj.getNum() << endl;
}

воскресенье, 9 февраля 2014 г.

Мост(Bridge Body/Head)

Идея: Отделить интерфейс от реализации. Это достигается за счет того, что реализация инкапсулируется в отдельную сущность(Body). Интерфейс к реализации обращается с помощью указателя на эту сущность. По реализации очень похож на стратегию.

#include <iostream>
#include <string>
#include <stdio.h>

using namespace std;

class Body
{
public:
virtual ~Body() {}
virtual void print() = 0;
};


class Printf : public Body
{
public:
virtual void print()
{
printf("You are using 'printf' implementation\n");
}
};

class Cout : public Body
{
public:
virtual void print()
{
cout << "You are using 'cout' implementation" << endl;
}
};

class Head
{
public:
Head(const string& pattern)
{
if (pattern == "printf")  //Для того, что бы подставить нужную реализацию
impl = new Printf;    //я криво сделал условия. Было б куда лучше, если
else if (pattern == "cout") // использовалась абстрактная фабрика, которая
impl = new Cout; // сама создавала нужную реализацию
else
impl = 0;
}

void print () {if (impl) impl->print(); }

private:
Body* impl;
};

int main()
{
string bridge;
cin >> bridge;
Head head(bridge);
head.print();
return 0;
}

суббота, 8 февраля 2014 г.

Абстрактная фабрика(Abstract factory)

Позволяет создавать семейство объектов

#include <iostream>
using namespace std;


class Sweetness //product1
{
public:
virtual void print() = 0;
virtual ~Sweetness() {};
};

class Cookie : public Sweetness
{
public:
virtual void print() { cout << "COKKIE!!!" << endl; }
};

class Cake : public Sweetness
{
public:
virtual void print() { cout << "CAKE!!!" << endl; }
};

class Drinks  //product2
{
public:
virtual void print() = 0;
virtual ~Drinks() {}
};

class Tea : public Drinks
{
public:
virtual void print() {cout << "TEA!!!" << endl; }
};

class Coffee : public Drinks
{
public:
virtual void print() {cout << "COFFEE!!!" << endl; }
};

class AbstractFactory
{
public:
virtual Sweetness* getSweetness() = 0;
virtual Drinks* getDrink() = 0;
virtual ~AbstractFactory() {}
};

class TeaAndCookie : public AbstractFactory
{
public:
virtual Sweetness* getSweetness() {return new Cookie; }
virtual Drinks* getDrink() { return new Tea; }
};

class CofeeAndCake : public AbstractFactory
{
public:
virtual Sweetness* getSweetness() {return new Cake; }
virtual Drinks* getDrink() { return new Coffee; }
};

void use(AbstractFactory* ptr)
{
Drinks* drink = ptr->getDrink();
Sweetness* sweet = ptr->getSweetness();

drink->print();
sweet->print();

delete drink;
delete sweet;

cout << endl;
}


int main()
{
AbstractFactory* cookie = new TeaAndCookie;
AbstractFactory* cake = new CofeeAndCake;

use(cookie);
use(cake);

return 0;
}

четверг, 6 февраля 2014 г.

Компоновщик(Composite)

Компонует объекты в древовидные структуры для представления иерархии часть-целое

#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <list>
#include <iostream>
#include <string.h>

using namespace std;


class Element
{
public:
  virtual ~Element() {}
  virtual void Print() = 0;
};

class Compositing : public Element
{
public:
  virtual ~Compositing() {}
    virtual void Print()
  {
    for (list<Element*>::iterator it = children.begin();
         it != children.end();
         ++it)
    {
      (*it)->Print();
    }
  }
    void Add(Element* ptr)
  {
    children.push_back(ptr);
  }
  void Remove(Element* ptr)
  {
    children.remove(ptr);
  }
private:
  list<Element*> children;
};

class Directory : public Element
{
public:
  Directory(const char* name) : dir_name(name) {}
  virtual ~Directory() {}
  virtual void Print()
  {
    cout << dir_name << " DIR" << endl;

    DIR *dir = opendir(dir_name);
    if(dir)
    {
      struct dirent *ent;
      while((ent = readdir(dir)) != NULL)
      {
        if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
        {
          cout <<"    " << ent->d_name;

        if (strcmp(ent->d_name, " ") && strchr(ent->d_name,'.'))
          cout << " FILE" << endl;
        else
          cout << " DIR" << endl;
        }
      }
    }
    else
    {
      fprintf(stderr, "Error opening directory\n");
    }
    closedir(dir);
  }
  private:
    const char* dir_name;
};

class File : public Element
{
public:
  File(const char* name) : file_name(name) {}
  virtual ~File() {}
  virtual void Print()
  {
    cout << file_name << " FILE" << endl;
  }
private:
  const char* file_name;

};

int main(void)
{

  Compositing comp;

  Element* file = new File("composite.cpp");
  Element* dir = new Directory(".");


  Compositing* c2 = new Compositing;
  c2->Add(dir);
  cout << endl;
  comp.Add(file);
  comp.Add(c2);
  comp.Add(file);

  comp.Print();

  return 0;
}

среда, 5 февраля 2014 г.

Стратегия/Политика(Strategy/Policy)

Идея: инкапсулировать алгоритм с возможностью замены алгоритма во время выполнения

#include <iostream>
using namespace std;

class BaseStrategy
{
public:
virtual ~BaseStrategy() {}
virtual void use(int *a) = 0;
};

class Strategy1 : public BaseStrategy
{
public:
virtual void use(int *a) { cout << "Strategy1" << endl; cout << (*a += 33) << endl;}
};

class Strategy2 : public BaseStrategy
{
public:
virtual void use(int *a) { cout << "Strategy2" << endl; cout << (*a += 6) << endl;}
};

class Strategy3 : public BaseStrategy
{
public:
virtual void use(int* a) { cout << "Strategy3" << endl; cout << (*a += 18) << endl;}
};

class BaseComposition
{
public:
virtual ~BaseComposition() {}
virtual void setStragy(BaseStrategy*) = 0;
virtual void use() = 0;

protected:
BaseStrategy* ptr;
};

class Composition : public BaseComposition
{
public:
Composition(int a) : num(a) {}
virtual void setStragy(BaseStrategy* ptr) { BaseComposition::ptr = ptr; }
virtual void use() { ptr->use(&num); }

private:
int num;
};

int main()
{
Composition obj(20);
Strategy1 str1;
Strategy2 str2;
Strategy3 str3;

obj.setStragy(&str1);
obj.use();

obj.setStragy(&str2);
obj.use();

obj.setStragy(&str3);
obj.use();

return 0;
}

вторник, 4 февраля 2014 г.

Виртуальный конструктор или прототип

Функцию член, предоставляющую возможность клонирования объекта, в C++ традиционно называют виртуальным конструктором. Конечно, виртуальных конструкторов не существует, но при создании копии объекта обычно осуществляется непрямой вызов конструктора копий класса через виртуальную функцию, что создает эффект виртуального конструктора.

class Base
{
public:
  virtual ~Base(){};
  virtual void Say() = 0;
  virtual Base* clone() = 0;
};

class A : public Base
{
public:
  ~A() {}
  A(){}
  A(const A& ){}
  virtual void Say() { cout << "Class A\n"; }
  virtual A* clone() { new A(*this); }
};

class B : public Base
{
public:
  ~B() {}
  B(){}
  B(const B& ){}
  virtual void Say() { cout << "Class B\n"; }
  virtual B* clone() { new B(*this); }
};

int main()
{
  Base* a = new A;
  Base* b = a->clone();
  delete a;
  b->Say();
 
  return 0;
}