2009-08-23 12 views
3

Ich habe eine Klasse Geräte genannt, die bis zwei Richtlinien akzeptiert wie ich sehen kann: StatePolicy und BehaviorPolicy.
Die StatePolicy hält und verwaltet den Zustand des Geräts.
Die BehaviorPolicy umschließt den Gerätetreiber, der in C oder C++ geschrieben wird.
Jetzt habe ich zwei Fragen:Politik basierte Design-Entscheidungen

  1. Wie zwischen dem Staat und den Verhaltensrichtlinien koordinieren?
  2. Wie speichere ich alle Geräte in einem Container? Da Gerät < X, Y > 's Typ ist anders als Gerät < N, M > Ich kann sie nicht mit einem Container speichern.

EDIT 1: Hier einige Code ist mein Problem zu veranschaulichen:

class AbstractDevice 
{ 
public: 
    virtual ~AbstractDevice() {} 

    virtual void performAction() = 0; 
    virtual const string &getName() const = 0; 
    //virtual void changeState(const ??? &_state) = 0; If I put a template here it won't solve my problem 
}; 

template<typename T> 
class State 
{ 
private: 
    T state; 
protected: 
    typedef T StateType; 
public: 
    State() : state(1) {} 

    const T &getState() { return state; } 
    void setState(const T _state) { state = _state; } 
}; 

template <class StatePolicy> 
class LightbulbBehvior : protected StatePolicy 
{ 
private: 
    typedef StatePolicy SP; 
public: 
    virtual void performAction() 
    { 
    if (SP::getState()) 
     cout << "do stuff"; 
    } 

    void changeState(const typename SP::StateType &_state) 
    { 
    setState(_state); 
    performAction(); 
    } 
}; 

template<class StatePolicy, template <class> class BehviorPolicy> 
class Device : public AbstractDevice, public BehviorPolicy<StatePolicy> 
{ 
private: 
    string sName; 
public: 
    const string &getName() const { return sName; } 
}; 

int main() 
{ 
    AbstractDevice *d = new Device<State<int>, LightbulbBehvior>(); 
    d->changeState(5); 
    return 0; 
} 

EDIT 2: Dies macht den Code mit einem Nachteil funktioniert, ich habe eine Liste aller erlaubten Statustypen zu erhalten. Es sieht ein bisschen wie das Besuchermuster für mich aus. Irgendwelche Gedanken?

class AbstractDevice 
{ 
public: 
    virtual ~AbstractDevice() {} 

    virtual void performAction() = 0; 
    virtual const string &getName() const = 0; 
    virtual void changeState(const int &_state) = 0; 
}; 

Vielen Dank im Voraus,
Omer.

+0

Ich glaube nicht, dass dies ein Politik * basiertes * Design ist. Ich denke, es ist nur eine Designentscheidung mit mehreren Kombinationen von Delegation oder Strategie. Aber das Design besteht darin, * Richtlinien * darzustellen. Es ist kein Design * basierend auf einer bestimmten Richtlinie. –

+0

Ich denke, dies ist ein gutes Beispiel dafür, wie leicht es ist, die Idee von Politiken und Mustern im Allgemeinen zu missverstehen. –

+0

Ich habe einen Code hinzugefügt, um zu verdeutlichen, was ich meine. –

Antwort

2

Hier ist die vollständige Design, das funktioniert und tut es die Aufgabe recht gut daran:

class AbstractState 
{ 
public: 
    virtual ~AbstractState() {} 
}; 

class AbstractDevice 
{ 
public: 
    virtual ~AbstractDevice() {} 

    virtual void performAction() = 0; 
    virtual const string &getName() const = 0; 
    virtual void changeState(const AbstractState &_state) = 0; 
}; 

template<typename T> 
class State : public AbstractState 
{ 
private: 
    T state; 
protected: 
    typedef T StateType; 
public: 
    State() {} 
    State(const T _state) : state(_state) {} 

    const T &getState() const { return state; } 
    void setState(const T _state) { state = _state; } 
}; 

template <class StatePolicy> 
class LightbulbBehvior : protected StatePolicy 
{ 
private: 
    typedef StatePolicy SP; 
public: 
    virtual void performAction() 
    { 
    if (SP::getState()) 
     cout << "do stuff"; 
    } 

    void changeState(const typename SP::StateType &_state) 
    { 
    setState(_state); 
    performAction(); 
    } 
}; 

template<class StatePolicy, template <class> class BehviorPolicy> 
class Device : public AbstractDevice, public BehviorPolicy<StatePolicy> 
{ 
private: 
    string sName; 

    typedef BehviorPolicy<StatePolicy> BP; 
    typedef StatePolicy SP; 
public: 
    const string &getName() const { return sName; } 

    void performAction() 
    { 
    BP::performAction(); 
    } 

    void changeState(const AbstractState &_state) 
    { 
    BP::changeState(((const SP &)_state).getState()); 
    } 
}; 

int main() 
{ 
    AbstractDevice *d = new Device<State<int>, LightbulbBehvior>(); 
    d->changeState(State<int>(5)); 
    delete d; 
    return 0; 
} 

@cjhuitt: Im Allgemeinen Ich denke, du hast recht, aber einen Blick darauf werfen und mir sagen, was Sie denken.

1

Ich bin mir nicht sicher, was Sie in der ersten Frage meinen. In Bezug auf die zweite, können Sie eine DeviceBase Klasse für die Gerät Klassenvorlage erstellen. Dann können Sie Zeiger auf diese Basisklasse in Containern speichern.


class DeviceBase 
{ 
    //... 
}; 

template <class T1, class T2> 
class Device : public DeviceBase 
{ 
    //... 
}; 
+0

Schauen Sie sich den obigen Code an. –

1

Was die erste Frage:

Wie zwischen dem Staat und den Verhaltensrichtlinien koordinieren?

Wenn Sie zwischen den beiden Richtlinien koordinieren müssen, sind sie nicht orthogonal. Wenn sie nicht orthogonal sind, eignen sie sich nicht für die Art von Design, die Sie machen. Betrachtet man jedoch den Beispielcode, sehe ich, dass Sie bereits das Verhalten auf den Zustand angewiesen haben, so dass ich nicht weiß, was der Punkt dieser Frage ist ...

Wie für die zweite Frage, ltcmelo hat die richtige Antwort, die auch in Ihren Code eingebettet ist. Wenn Sie nach einer Möglichkeit suchen, Vorlagen in einem generischen Container zu behalten, ist dies der beste Weg. Um das changeState Problem zu überwinden, müssen Sie einige allgemeine Funktion (en) machen, um die Zustände zu ändern, wie Sie wollen ... wie open, close, usw. Wenn Sie diese Funktionen nicht machen können, ist vielleicht Ihr Code auch generisch.

+0

Der Code war eine Bearbeitung. Siehe bearbeiten Nummer 2 in einer Sekunde. –