Sablony

Uploaded from authorPOINTLite
Views:
 
Category: Entertainment
     
 

Presentation Description

No description available.

Comments

Presentation Transcript

Pokročilé návrhové vzory: 

Pokročilé návrhové vzory Martin Děcký 15.11.2007 3:54

Pokročilé návrhové vzory: 

Pokročilé návrhové vzory

Visitor: 

Visitor class Visitor { public: virtual void VisitFoo(Foo &) = 0; virtual void VisitBar(Bar &) = 0; }; class Foo { public: virtual void Accept(Visitor & visitor) { v.VisitFoo(*this); } };

Obecný Visitor: 

class BaseVisitor { public: virtual ~BaseVisitor() { } }; template <class T, typename R = void> class Visitor { public: typedef R ReturnType; virtual ReturnType Visit(T&) = 0; }; Obecný Visitor

Obecný Visitor: 

Obecný Visitor template <typename R = void> class BaseVisitable { public: typedef R ReturnType; virtual ~BaseVisitable() { } virtual ReturnType Accept(BaseVisitor&) = 0; protected: template <class T> static ReturnType AcceptImpl(T& visited, BaseVisitor& guest) { if (Visitor<T>* p = dynamic_cast<Visitor<T>*>(&guest)) return p->Visit(visited); return ReturnType(); } }; #define DEFINE_VISITABLE() \ virtual ReturnType Accept(BaseVisitor& guest) { \ return AcceptImpl(*this, guest); \ } class ConcreteVisitor : public BaseVisitor, public Visitor<Foo>, public Visitor<Bar> { public: void Visit(Foo &foo); void Visit(Bar &bar); };

Traits: 

Traits I::value_type value; // OK if I is a class int::value_type value; // not working int*::value_type value; // not working Řešení v STL Použití především pro iterátory, číselné typy (numeric_limits) apod. template <class Iterator> struct iterator_traits { static const bool star = false; typedef typename Iterator::value_type value_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; }; template <class T> struct iterator_traits<T*> { static const bool star = false; typedef T value_type; typedef T* pointer; typedef T& reference; };

Curriously recurring template pattern: 

Curriously recurring template pattern class Base { public: void fnc() { implementation(); } virtual void implementation() = 0; }; class Derived : public Base { public: virtual void implementation() { std::cout << "Derived" << std::endl; } }; int main(int argc, char *argv[]) { Base *obj = new Derived; obj->fnc(); // "Derived" }

Curriously recurring template pattern: 

Curriously recurring template pattern template <class Derived> class Base { public: void fnc() { static_cast<Derived*>(this)->implementation(); } }; class Derived : public Base<Derived> { public: void implementation() { std::cout << "Derived" << std::endl; } }; int main(int argc, char *argv[]) { Base<Derived> *obj = new Derived; obj->fnc(); // "Derived" }

Použití CRTP: 

Použití CRTP

Policies: 

Policies

Ukázka použití policies: 

Ukázka použití policies template <class CreationPolicy, class ThreadPolicy> class Manager : public CreationPolicy, public ThreadPolicy { public: void fnc() { ThreadPolicy::Lock(); Foo *foo = CreationPolicy::Create(); ThreadPolicy::Unlock(); } }; class ThreadUnsafe { public: void Lock() { } void Unlock() { } }; class ThreadSafe { private: mutex_t mtx; public: void Lock() { mutex_lock(&mtx); } void Unlock() { mutex_unlock(&mtx); } }; template <class T> class CreateWithNew { public: static T* Create() { return new T; } protected: ~CreateWithNew() { /* Only derived classes can destroy policy */ } }; Manager<CreateWithNew<Foo>, ThreadSafe> manager; manager.fnc();

Template template parameters: 

Template template parameters template <template <class CreateType> class CreationPolicy> class Manager : public CreationPolicy<Foo> { void fnc() { Bar* bar = CreationPolicy<Bar>::Create(); } }; template <template <class> class CreationPolicy> class Manager : public CreationPolicy<Foo> { // ... }; template <template <class> class CreationPolicy = CreateWithNew> class Manager : public CreationPolicy<Foo> { // ... }; Host template dědí od CreationPolicy instanciované pro typ Foo Může používat (statické metody) stejné CreationPolicy také pro typ Bar Parametr CreateType je jen formální Výchozí policy template <template <class T = Foo> class CreationPolicy = CreateWithNew> class Manager : public CreationPolicy<> { };

Parametrizované policies: 

Parametrizované policies template <class T, template <class> class CreationPolicy = CreateUsingNew, template <class> class LifetimePolicy = DefaultLifetime, template <class> class ThreadingModel = SingleThreaded> class SingletonHolder { public: static T& Instance() { if (!instance_) { typename ThreadingModel<T>::Lock guard; if (!instance_) { if (destroyed_) { LifetimePolicy<T>::OnDeadReference(); destroyed_ = false; } instance_ = CreationPolicy<T>::Create(); LifetimePolicy<T>::ScheduleCall(&DestroySingleton); } } return *instance_; } private: static void DestroySingleton(); SingletonHolder(); typedef ThreadingModel<T>::VolatileType InstanceType; static InstanceType* instance_; static bool destroyed_; }; template <class T> class SingleThreaded { public: typedef T VolatileType; };

Obohacené politiky: 

Obohacené politiky Foo *prototype = new Foo; Manager<Foo, PrototypeCreator> manager; manager.SetPrototype(prototype); template <class T, template <class> class CreationPolicy> class Manager : public CreationPolicy<T> { void SwitchPrototype(T* prototype) { delete CreationPolicy<T>::GetPrototype(); CreationPolicy<T>::SetPrototype(prototype); } }; int main(int argc, char *argv[]) { Foo *prototype = new Foo; Manager<Foo, PrototypeCreator> prototypeManager; prototypeManager.SwitchPrototype(prototype); // OK Manager<Foo, CreateWithNew> standardManager; standardManager.SwitchPrototype(prototype); // compile error } Host template může obsahovat pokročilé metody Jejich sémantická správnost spoléhá na existenci volitelných metod politiky

Poznámky k politikám: 

Poznámky k politikám

Type concepts: 

Type concepts template <class T> void fnc(T x) { function_requires< EqualityComparableConcept<T> >(); // T must support } template <class T> class Foo { public: BOOST_CLASS_REQUIRE(T, boost, EqualityComparableConcept<T>) };

Metaprogramování: 

Metaprogramování

Klasická ukázka metaprogramování: 

Klasická ukázka metaprogramování unsigned int factorial(const unsigned int n) { if (n == 0) return 1; return n * factorial(n – 1); } int main(int argc, char *argv[]) { std::cout << factorial(0) << std::endl; // 1 std::cout << factorial(5) << std::endl; // 120 } template <unsigned int N> struct Factorial { enum { value = N * Factorial<N - 1>::value }; }; template <> struct Factorial<0> { enum { value = 1 }; }; int main(int argc, char *argv[]) { std::cout << Factorial<0>::value << std::endl; // 1 std::cout << Factorial<5>::value << std::endl; // 120 }

Entity v příkladu: 

Entity v příkladu

Type2Type<T>: 

Type2Type<T> template <class T, class U> T* Create(const U& arg) { return new T(arg); } template <class T, class U> T* Create(const U& arg, Type2Type<T>) { return new T(arg); } template <class U> Foo* Create(const U& arg, Type2Type<Foo>) { return new Foo(arg, 42); } template <typename T> struct Type2Type { typedef T UniqueType; };

Typelists: 

Typelists class NullType { }; template <class H, class T> struct TypeList { typedef H Head; typedef T Tail; }; #define TYPELIST_1(T1) TypeList<T1, NullType> #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) > #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) > // ... template <class TList> struct Length; template <> struct Length<NullType> { enum { value = 0 }; }; template <class H, class T> struct Length <TypeList<H, T> > { enum { value = 1 + Length<T>::value }; }; Ukázka prediátu

Další zajímavé predikáty: 

Další zajímavé predikáty template <class TList, class T> struct Append; template <> struct Append<NullType, NullType> { typedef NullType Result; }; template <class T> struct Append<NullType, T> { typedef TypeList<T, NullType> Result; }; template <class H, class T> struct Append<NullType, TypeList<H, T> > { typedef TypeList<H, T> Result; }; template <class H, class T, class Type> struct Append<TypeList<H, T>, Type> { typedef TypeList<H, typename Append<T, Type>::Result> Result; }; template <class TList> struct Reverse; template <> struct Reverse<NullType> { typedef NullType Result; }; template <class H, class T> struct Reverse<TypeList<H, T> > { typedef typename Append<typename Reverse<T>::Result, H>::Result Result; }; Reverse

Generování tříd: 

Generování tříd

Generování roztroušené hierarchie: 

Generování roztroušené hierarchie template <class TList, template <class> class Action> class GenScatterHierarchy; template <class T1, class T2, template <class> class Action> class GenScatterHierarchy<TypeList<T1, T2>, Action> : public GenScatterHierarchy<T1, Action>, public GenScatterHierarchy<T2, Action> { public: typedef TypeList<T1, T2> TList; typedef GenScatterHierarchy<T1, Action> LeftBase; typedef GenScatterHierarchy<T1, Action> RightBase; }; template <class Type, template <class> class Action> class GenScatterHierarchy : public Action<Type> { typedef Action<Type> LeftBase; }; template <template <class> class Action> class GenScatterHierarchy<NullType, Action> { };

Generování lineární hierarchie: 

Generování lineární hierarchie struct EmptyType { }; template <class TList, template <class, class> class Action, class Root = EmptyType> class GenLinearHierarchy; template <class T1, class T2, template <class, class> class Action, class Root> class GenLinearHierarchy<TypeList<T1, T2>, Action, Root> : public Action<T1, GenLinearHierarchy<T2, Action, Root> > { }; template <class T, template <class, class> class Action, class Root> class GenLinearHierarchy<TYPELIST_1(T), Action, Root> : public Action<T, Root> { }; template <class T, class Base> class EventHandler : public Base { public: virtual void OnEvent(T& obj, int id); }; typedef GenLinearHierarchy<TYPELIST_2(Window, Button), EventHandler> ConcreteEventHandler;

Obecná Abstract factory: 

Obecná Abstract factory template <class T> class AtomicAbstractFactory { public: virtual T* DoCreate(Type2Type<T>) = 0; virtual ~AtomicAbstractFactory() { } }; template <class TypeList, template <class> class AtomicFactory = AtomicAbstractFactory> class AbstractFactory : public GenScatterHierarchy<TypeList, AtomicFactory> { template <class T> T* Create() { return AtomicFactory<T>::DoCreate(Type2Type<T>); } }; typedef AbstractFactory<TYPELIST_3(Foo, Bar, Foobar) > SampleAbstractFactory; Obecná abstract factory

Třídy obecné Abstract factory: 

Třídy obecné Abstract factory

Obecná Concrete factory: 

Obecná Concrete factory typedef AbstractFactory<TYPELIST_3(Foo, Bar, Foobar) > SampleAbstractFactory; typedef Factory<SampleAbstractFactory, FactoryNew, TYPELIST_3(FooImpl, BarImpl, FoobarImpl) > SampleFactory;

Obecná Concrete factory: 

Obecná Concrete factory template <class ConcreteProduct, class Base> class FactoryNew : public Base { private: typedef typename Base::ProductList BaseProductList; protected: typedef typename BaseProductList::Tail ProductList; public: typedef typename BaseProductList::Head AbstractProduct; ConcreteProduct* DoCreate(Type2Type<AbstractProduct>) { return new ConcreteProduct; } }; template <class AbsFactory, template <class, class> class AtomicFactory = FactoryNew, class TList = typename AbsFactory::ProductList> class ConcreteFactoy : public GenLinearHierarchy<typename Reverse<TList>::Result, AtomicFactory, AbsFactory> { public: typedef typename AbsFactory::ProductList ProductList; typedef TList ConcreteProductList; };

Pohled jinam: 

Pohled jinam

Objective C: Categories: 

Objective C: Categories template <class Arithmetics> class integer : public Arithmetics { private: int value_; public: void set_value(int value) { value_ = value; } int get_value() { return value_; } void add(integer & b) { value_ = arithmetic_add(value_, b.value_); } }; class SimpleArithmetics { public: static int arithmetic_add(int a, int b) { return a + b; } }; typedef integer<SimpleArithmetics> SimpleInteger;

Objective C: Categories: 

Objective C: Categories @interface integer : Object { @private int value_; } - (void) set_value: (int) value; - (int) get_value; - (void) add: (integer *) b; @end @interface integer (Arithmetics) - (int) arithmetic_add: (int) a: (int) b; @end @implementation integer - (void) set_value: (int) value { value_ = value; } - (int) get_value { return value_; } - (void) add: (integer *) b { value_ = [self arithmetic_add: value_: b->value_]; } @end @implementation integer (Arithmetics) - (int) arithmetic_add: (int) a: (int) b { return a + b; }

Shrnutí: 

Shrnutí

Zdroje: 

Zdroje