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 Visitor {
public:
typedef R ReturnType;
virtual ReturnType Visit(T&) = 0;
}; Obecný Visitor
Obecný Visitor : Obecný Visitor template class BaseVisitable {
public:
typedef R ReturnType;
virtual ~BaseVisitable() {
}
virtual ReturnType Accept(BaseVisitor&) = 0;
protected:
template static ReturnType AcceptImpl(T& visited, BaseVisitor& guest) {
if (Visitor* p = dynamic_cast*>(&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, public Visitor {
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 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 struct iterator_traits {
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 Base {
public:
void fnc() {
static_cast(this)->implementation();
}
};
class Derived : public Base {
public:
void implementation() {
std::cout << "Derived" << std::endl;
}
};
int main(int argc, char *argv[]) {
Base *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 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 CreateWithNew {
public:
static T* Create() {
return new T;
}
protected:
~CreateWithNew() {
/* Only derived
classes can
destroy policy */
}
}; Manager, ThreadSafe> manager;
manager.fnc();
Template template parameters : Template template parameters template class CreationPolicy> class Manager
: public CreationPolicy {
void fnc() {
Bar* bar = CreationPolicy::Create();
}
}; template class CreationPolicy> class Manager
: public CreationPolicy {
// ...
}; template class CreationPolicy = CreateWithNew> class Manager
: public CreationPolicy {
// ...
}; 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 class CreationPolicy = CreateWithNew> class Manager
: public CreationPolicy<> {
};
Parametrizované policies : Parametrizované policies template class CreationPolicy = CreateUsingNew,
template class LifetimePolicy = DefaultLifetime,
template class ThreadingModel = SingleThreaded>
class SingletonHolder {
public:
static T& Instance() {
if (!instance_) {
typename ThreadingModel::Lock guard;
if (!instance_) {
if (destroyed_) {
LifetimePolicy::OnDeadReference();
destroyed_ = false;
}
instance_ = CreationPolicy::Create();
LifetimePolicy::ScheduleCall(&DestroySingleton);
}
}
return *instance_;
}
private:
static void DestroySingleton();
SingletonHolder();
typedef ThreadingModel::VolatileType InstanceType;
static InstanceType* instance_;
static bool destroyed_;
}; template class SingleThreaded {
public:
typedef T VolatileType;
};
Obohacené politiky : Obohacené politiky Foo *prototype = new Foo;
Manager manager;
manager.SetPrototype(prototype); template class CreationPolicy> class Manager
: public CreationPolicy {
void SwitchPrototype(T* prototype) {
delete CreationPolicy::GetPrototype();
CreationPolicy::SetPrototype(prototype);
}
};
int main(int argc, char *argv[]) {
Foo *prototype = new Foo;
Manager prototypeManager;
prototypeManager.SwitchPrototype(prototype); // OK
Manager 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 void fnc(T x) {
function_requires< EqualityComparableConcept >(); // T must support
} template class Foo {
public:
BOOST_CLASS_REQUIRE(T, boost, EqualityComparableConcept)
};
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 struct Factorial {
enum {
value = N * Factorial::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 : Type2Type template T* Create(const U& arg) {
return new T(arg);
} template T* Create(const U& arg, Type2Type) {
return new T(arg);
}
template Foo* Create(const U& arg, Type2Type) {
return new Foo(arg, 42);
} template struct Type2Type {
typedef T UniqueType;
};
Typelists : Typelists class NullType {
};
template struct TypeList {
typedef H Head;
typedef T Tail;
};
#define TYPELIST_1(T1) TypeList
#define TYPELIST_2(T1, T2) TypeList
#define TYPELIST_3(T1, T2, T3) TypeList
// ... template struct Length;
template <> struct Length {
enum {
value = 0
};
};
template struct Length > {
enum {
value = 1 + Length::value
};
}; Ukázka prediátu
Další zajímavé predikáty : Další zajímavé predikáty template struct Append;
template <> struct Append {
typedef NullType Result;
};
template struct Append {
typedef TypeList Result;
};
template struct Append > {
typedef TypeList Result;
};
template struct Append, Type> {
typedef TypeList::Result> Result;
}; template struct Reverse;
template <> struct Reverse {
typedef NullType Result;
};
template struct Reverse > {
typedef typename Append::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 Action> class GenScatterHierarchy;
template class Action>
class GenScatterHierarchy, Action>
: public GenScatterHierarchy, public GenScatterHierarchy {
public:
typedef TypeList TList;
typedef GenScatterHierarchy LeftBase;
typedef GenScatterHierarchy RightBase;
};
template class Action> class GenScatterHierarchy
: public Action {
typedef Action LeftBase;
};
template class Action> class GenScatterHierarchy {
};
Generování lineární hierarchie : Generování lineární hierarchie struct EmptyType {
};
template class Action,
class Root = EmptyType>
class GenLinearHierarchy;
template class Action, class Root>
class GenLinearHierarchy, Action, Root>
: public Action > {
};
template class Action, class Root>
class GenLinearHierarchy
: public Action {
}; template class EventHandler : public Base {
public:
virtual void OnEvent(T& obj, int id);
};
typedef GenLinearHierarchy ConcreteEventHandler;
Obecná Abstract factory : Obecná Abstract factory template class AtomicAbstractFactory {
public:
virtual T* DoCreate(Type2Type) = 0;
virtual ~AtomicAbstractFactory() {
}
}; template class AtomicFactory = AtomicAbstractFactory>
class AbstractFactory : public GenScatterHierarchy {
template T* Create() {
return AtomicFactory::DoCreate(Type2Type);
}
};
typedef AbstractFactory SampleAbstractFactory; Obecná abstract factory
Třídy obecné Abstract factory : Třídy obecné Abstract factory
Obecná Concrete factory : Obecná Concrete factory typedef AbstractFactory SampleAbstractFactory;
typedef Factory
SampleFactory;
Obecná Concrete factory : Obecná Concrete factory template
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) {
return new ConcreteProduct;
}
};
template class AtomicFactory = FactoryNew,
class TList = typename AbsFactory::ProductList>
class ConcreteFactoy : public GenLinearHierarchy::Result,
AtomicFactory,
AbsFactory> {
public:
typedef typename AbsFactory::ProductList ProductList;
typedef TList ConcreteProductList;
};
Pohled jinam : Pohled jinam
Objective C: Categories : Objective C: Categories template 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 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
Catch the
buzz on authorSTREAM
Copyright © 2002-2008 authorSTREAM. All rights reserved.