구조패턴-Flyweight

2008. 8. 19. 00:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Flyweight]
의도:
대규모의 미세한 객체들을 효과적으로 사용하기 위해서는 공유 개념을 도입
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Flyweight
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <list>
#include <algorithm>


/////////////////////////////////////////////////////////////////////////////
//
// Flyweight
//
/////////////////////////////////////////////////////////////////////////////
class Flyweight
{
public:
 virtual ~Flyweight() {}
public:
 virtual void Operation (void) = 0;
};

class ConcreteFlyweight : public Flyweight
{
public:
 ConcreteFlyweight (std::string s, int n) :
  Key_   (n),
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << "(" << Key_ << ")" << std::endl;
 }

private:
 int         Key_;
 std::string Value_;
};

class UnsharedConcreteFlyweight : public Flyweight
{
public:
 UnsharedConcreteFlyweight (std::string s) :
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << std::endl;
 }

private:
 std::string Value_;
};

//// ------------------------------------------------------------------------

class FlyweightFactory
{
private:
 struct PoolDeleter
 {
 public:
  PoolDeleter() : Count_(0) {}
 public:
  void operator()(std::pair<int,Flyweight*> i)
  {
   Flyweight *p = i.second;

   if (p)
   {
    Count_++;
    delete p;
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 virtual ~FlyweightFactory ()
 {
  int Count;

  Count = std::for_each(Pool_.begin(), Pool_.end(), PoolDeleter());
  std::cout << "~FlyweightFactory(): [ConcreteFlyweight] deleting count="
            << Count
            << std::endl
            << std::endl;
 }

public:
 Flyweight* GetFlyweight (std::string value, int key)
 {
  Flyweight*  f;

  if ( Pool_.end() == Pool_.find (key) )
  {
   f = new ConcreteFlyweight (value, key);
   Pool_[key] = f;
  }
  else
  {
   f = Pool_[key];
  }

  return f;
 }

 Flyweight* GetUnsharedFlyweight (std::string value)
 {
  Flyweight* f;

  f = new UnsharedConcreteFlyweight ( value );

  return f;
 }

private:
 std::map <int,Flyweight*> Pool_;
};

//// ------------------------------------------------------------------------

class Context
{
private:
 template<class T>
 struct OperationCaller : public std::unary_function<T, void>
 {
 public:
  void operator()(T ptr)
  {
   if (ptr)
    ptr->Operation();
  }
 };

 template<class T>
 struct ListDeleter : public std::unary_function<T, void>
 {
 public:
  ListDeleter() : Count_(0) {}
 public:
  void operator()(T ptr)
  {
   if (ptr)
   {
    if (dynamic_cast<UnsharedConcreteFlyweight*>(ptr))
    {
     Count_++;
     delete ptr;
    }
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 ~Context ()
 {
  int Count;

  Count = std::for_each(List_.begin(), List_.end(), ListDeleter<Flyweight*>());
  std::cout << "~Context(): [UnsharedConcreteFlyweight] deleting count="
            << Count
            << std::endl;
 }

public:
 void Add (std::string s, int n=0)
 {
  if (n)
   List_.push_back ( Factory_.GetFlyweight (s, n) );
  else
   List_.push_back ( Factory_.GetUnsharedFlyweight (s) );
 }

 void Operation (void)
 {
  std::for_each(List_.begin(), List_.end(), OperationCaller<Flyweight*>());  

  std::cout << std::endl;
 }

private:
 std::list<Flyweight*> List_;
 FlyweightFactory      Factory_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Context context;

 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );

 context.Operation ();

 return 0;
}
-----------------------------------------------------------------------------
one(1)
two
one(1)
two
one(1)
two
one(1)
two
one(1)
two

~Context(): [UnsharedConcreteFlyweight] deleting count=5
~FlyweightFactory(): [ConcreteFlyweight] deleting count=1


Posted by 셈말짓기 :

구조패턴-Facade

2008. 8. 18. 21:03 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Facade]
의도:
서브시스템을 합성하는 다수의 객체들의 인터페이스 집합에 대해 일관된 하나의 인터페이스를
제공할 수 있게 한다. Facade는 서브시스템을 사용하기 쉽게 하기 위한 포괄적 개념의 인터
페이스를 정의 한다.
-----------------------------------------------------------------------------/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Facade
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Subsystem
//
/////////////////////////////////////////////////////////////////////////////
class SubsystemA
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemA::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemA::OperationB()" << std::endl;
 }
};

class SubsystemB
{
public:
 void Operation (void)
 {
  std::cout << "\tSubsystemB::Operation()" << std::endl;
 }
};

class SubsystemC
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemC::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemC::OperationB()" << std::endl;
 }
 void OperationC (void)
 {
  std::cout << "\tSubsystemC::OperationC()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Facade
//
/////////////////////////////////////////////////////////////////////////////
class Facade
{
public:
 void OperationA (void)
 {
  std::cout << "Facade::OperationA()" << std::endl;
  A_.OperationA();
  B_.Operation ();
  C_.OperationA();
  std::cout << std::endl;
 }

 void OperationB (void)
 {
  std::cout << "Facade::OperationB()" << std::endl;
  A_.OperationB();
  C_.OperationB();
  C_.OperationC();
  std::cout << std::endl;
 }

private:
 SubsystemA A_;
 SubsystemB B_;
 SubsystemC C_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Facade f;

 f.OperationA();
 f.OperationB();

 return 0;
}
-----------------------------------------------------------------------------Facade::OperationA()
        SubsystemA::OperationA()
        SubsystemB::Operation()
        SubsystemC::OperationA()

Facade::OperationB()
        SubsystemA::OperationB()
        SubsystemC::OperationB()
        SubsystemC::OperationC()

Posted by 셈말짓기 :

구조패턴-Decorator

2008. 8. 18. 20:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Decorator]
의도:
객체에 동적으로 새로운 서비스를 추가할 수 있게 한다. Decorator패턴은 기능의 추가를
위해서 서브클래스를 생성하는 것보다 융통성 있는 방법을 제공한다.

다른 이름:
Wrapper
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Decorator
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Decorator
//
//
/////////////////////////////////////////////////////////////////////////////
class Component
{
public:
 virtual ~Component() {}

public:
 virtual void Operation (void) = 0;
};

class ConcreteComponent : public Component
{
public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteComponent::Operation()" << std::endl;
 }
};

class Decorator : public Component
{
public:
 explicit Decorator (Component* p) :
  Component_(p)
 {
 }

public:
 virtual void Operation (void)
 {
  if (Component_.get())
   Component_->Operation ();
 }

private:
 std::auto_ptr<Component> Component_;
};

class ConcreteDecoratorA : public Decorator
{
public:
 explicit ConcreteDecoratorA (Component* p) :
  Decorator(p)
 {
 }

public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorA::Operation()" << std::endl;
 }
};

class ConcreteDecoratorB : public Decorator
{
public:
 explicit ConcreteDecoratorB (Component* p) :
  Decorator(p)
 {
 }
public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorB::Operation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Component> p;
 
 p.reset( new ConcreteDecoratorB (
              new ConcreteDecoratorA (
                  new ConcreteComponent())) );

 p->Operation ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteComponent::Operation()
ConcreteDecoratorA::Operation()
ConcreteDecoratorB::Operation()

Posted by 셈말짓기 :

구조패턴-Bridge

2008. 8. 18. 17:38 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Bridge]
의도:
구현과 추상화 개념을 분리하려는 것이다. 이로써 구현 자체도 하나의 추상화 개념으로 다양한
변형이 가능해지고, 구현과 독립적으로 인터페이스도 다양함을 가질 수 있게 된다.

다른 이름:
Handle/body
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Bridge
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Bridge
//
/////////////////////////////////////////////////////////////////////////////
class Implementor
{
public:
 virtual ~Implementor () {}
public:
 virtual void OperationImp (void) = 0;
};

class ConcreteImplementorA : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorA::OperationImp()" << std::endl;
 }
};

class ConcreteImplementorB : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorB::OperationImp()" << std::endl;
 }
};

class ImplementorFactory
{
private:
 ImplementorFactory(void) : Env_(0) {};
public:
 static ImplementorFactory* Instance (void)
 {
  if (0==Instance_)
  {
   Instance_ = new ImplementorFactory();
  }

  return Instance_;
 }

private:
 static ImplementorFactory* Instance_;

public:
 Implementor* CreateImplementor (void)
 {
  Implementor* p;
 
  if (Env_==0)
   p = new ConcreteImplementorA();
  else
   p = new ConcreteImplementorB();

  return p;
 }

public:
 void SetEnv (int e)
 {
  Env_ = e;
 }

 int  GetEnv (void)
 {
  return Env_;
 }

private:
 int Env_;
};

ImplementorFactory* ImplementorFactory::Instance_ = 0;

class Abstraction
{
public:
 Abstraction () : Imp_(0)
 {
 }

public:
 virtual void Operation (void)
 {
  GetImp ()->OperationImp();
 }

private:
 Implementor* GetImp (void)
 {
  if (Imp_==0)
  {
   Imp_ = ImplementorFactory::Instance()->CreateImplementor ();
  }

  return Imp_;
 }

private:
 Implementor *Imp_;
};

class RefinedAbstraction : public Abstraction
{
public:
 virtual void RefinedOperation (void)
 {
  Abstraction::Operation();
  std::cout<< "RefinedAbstraction::RefinedOperation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<RefinedAbstraction> p;


 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 std::cout << std::endl;
 ImplementorFactory::Instance()->SetEnv (1);

 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteImplementorA::OperationImp()
RefinedAbstraction::RefinedOperation()

ConcreteImplementorB::OperationImp()
RefinedAbstraction::RefinedOperation()

Posted by 셈말짓기 :

Reference-Counting

2008. 8. 18. 13:24 from 셈말짓기/C and C++

#include <windows.h>
#include <tchar.h>

#include <iostream>

/////////////////////////////////////////////////////////////////////////////
//
// Handle
//
/////////////////////////////////////////////////////////////////////////////
template<typename T>
class CRefCountedInstance
{
public:
 CRefCountedInstance ();

public:
 inline void AddRef       (void);
 inline void Release      (void);
 inline void Assign       (T *p);
 inline bool IsReferenced (void);
 inline T*   GetInstance  (void);

private:
 T   *Instance_;
 int  RefCount_;
};

template<typename T>
CRefCountedInstance<T>::CRefCountedInstance () :
 RefCount_ (0),
 Instance_ (0)
{
}

template<typename T>
void CRefCountedInstance<T>::AddRef (void)
{
 RefCount_++;
}

template<typename T>
void CRefCountedInstance<T>::Release (void)
{
 if (RefCount_>0)
 {
  RefCount_--;
 }

 if (RefCount_==0)
 {
  if (Instance_)
  {
   delete Instance_;
  }

  Instance_ = 0;
 }
}

template<typename T>
void CRefCountedInstance<T>::Assign (T *p)
{
 Instance_ = p;
 AddRef ();
}

template<typename T>
bool CRefCountedInstance<T>::IsReferenced (void)
{
 if (RefCount_==0)
  return false;

 return true;
}

template<typename T>
T* CRefCountedInstance<T>::GetInstance (void)
{
 return Instance_;
}

template<typename T>
class Handle
{
public:
 Handle ();
 explicit Handle (T *p);
 Handle (const Handle<T> &copy);
 ~Handle ();

public:
 Handle<T>& operator = (const Handle<T>& rhs);

public:
 inline T& operator*  () const;
 inline T* operator-> () const;
 inline T* Get    (void) const;

private:
 CRefCountedInstance<T>* Rep_;
};

template<typename T>
Handle<T>::Handle () : Rep_(0)
{
}

template<typename T>
Handle<T>::Handle (T *p)
{
 Rep_ = new CRefCountedInstance<T>();
 Rep_->Assign(p);
}

template<typename T>
Handle<T>::Handle (const Handle<T> &copy)
{
 Rep_ = copy.Rep_;

 if (Rep_)
  Rep_->AddRef ();
}

template<typename T>
Handle<T>::~Handle ()
{
 if (Rep_)
 {
  Rep_->Release ();

  if (!Rep_->IsReferenced())
   delete Rep_;
 }
}

template<typename T>
Handle<T>& Handle<T>::operator = (const Handle<T>& rhs)
{
 if (this == &rhs) return *this;

 if (Rep_)
  Rep_->Release ();

 Rep_ = rhs.Rep_;

 if (Rep_)
  Rep_->AddRef ();

 return *this;
}

template<typename T>
T& Handle<T>::operator*() const
{
 return *(Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::operator -> () const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::Get (void) const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
/////////////////////////////////////////////////////////////////////////////
class Object
{
public:
 explicit Object(int n=0) : Data_(n)
 {
  std::cout << "Object(" << Data_ << ")" << std::endl;
 }

public:
 virtual ~Object()
 {
  std::cout << "~Object(" << Data_ << ")" << std::endl;
 }

public:
 int Data_;
};

Handle<Object> Test (Handle<Object> h)
{
 if (h.Get())
  h->Data_ = 3;

 return h;
}


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Handle<Object> p1( new Object(1) );
 Handle<Object> p2( new Object(2) );
 Handle<Object> p3;
 Handle<Object> p4;


 std::cout << std::endl;


 std::cout << "p2 = p1;" << std::endl;
 p2 = p1;
 std::cout << std::endl;


 std::cout << "p3 = p1;" << std::endl;
 p3 = p1;
 std::cout << std::endl;


 std::cout << "p4 = Test (p3);" << std::endl;
 p4 = Test (p3);

 std::cout << "p1->Data_ = " << p1->Data_ << std::endl;
 std::cout << "p2->Data_ = " << p2->Data_ << std::endl;
 std::cout << "p3->Data_ = " << p3->Data_ << std::endl;
 std::cout << "p4->Data_ = " << p3->Data_ << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Object(1)
Object(2)

p2 = p1;
~Object(2)

p3 = p1;

p4 = Test (p3);
p1->Data_ = 3
p2->Data_ = 3
p3->Data_ = 3
p4->Data_ = 3
~Object(3)

Posted by 셈말짓기 :