2008-12-29 6 views
1

Supposons que l'implémentation d'une classe "CAR" soit requise.Implémentation de classes pilotées par l'état

Maintenant, cette classe contient différents états comme « non mis à feu », « mis à feu », « désagrégé », « crevé », etc.,

La façon dont je regarde pour mettre en œuvre cette exigence est de avoir des drapeaux booléens appelés "propriétés" dans la classe et "vérifier l'état" en utilisant ces drapeaux booléens dans chaque fonction membre. Par exemple,

 
CAR.goRacing() 
{ 
    if(bIsPunctured) 
     return ENUM_CANT_DRIVE; 

    //Start the Engine... 
}

Cette implémentation, triviale si cela peut paraître, commence à devenir très compliqué lorsque le nombre d'états que l'objet expose augmente. J'ai également vu des occurrences où un seul état rend la maintenance de l'objet beaucoup trop lourde (je suis sûr que dans ce cas, je suis à blâmer pour mes compétences en programmation)
Existe-t-il un moyen standard d'implémenter un tel état ? -driven objet?

J'ai vu le Property Pattern de Steve Yeggey, mais je suis vraiment à court d'un exemple du monde réel!

Merci.

Répondre

3

Cela semble certainement être un emploi pour le State Pattern

Fondamentalement, vous créez votre application (contexte) et définir le comportement d'une opération dans une catégorie distincte/interface (état)

Cette classe aura différentes sous-classes d'implémentation, une par état.

Lorsque l'état change, l'objet état affecte le nouvel état au contexte. De cette façon, vous avez tout le code d'état dans des classes séparées et évitez le code spaghetti classique.

EDIT

est ici la mise en œuvre plus simple que je pouvais penser.

Supposons que vous ayez un «familier» Un pate fait quelque chose en fonction de l'état dans lequel il se trouve.

Lorsque cet état est terminé, les changements d'état à l'autre (le sommeil étant -> réveiller -> jouer etc.)

Je ne sais même pas si cela compile. Ceci est seulement pour obtenir l'idée *

//These are the states of the "Pet" class 
//sleep -> wake up -> play -> dinner -> sleep -> wake up .. etc. 
class Pet { 

    State currentState; 
    static Pet createNew(){ 
     Pet p = new Pet(); 
     State s = new Sleep(); 
     s.setContext(p); 
     p.currentState = 
     return p; 
    } 

    public void doSomething(){ 
     currentState.doSomething(); 
    } 

} 

abstract class State { 
    Pet context; 
    void setContext(Pet c) { 
     this.context = c; 
    } 
    abstract doSomething(); 
    void sout(Striing message) { 
     System.out.println(message); 
    } 
} 
class Sleep extends State { 
    public void doSomething(){ 
     sout("zzzZZZ ... "); 
     State nextState = new WakeUp(); 
     nextState.setContext(context); 
     context.currentState = nextState; 
    } 
} 
class WakeUp extends State { 
    public void doSomething(){ 
     sout("uuuaaaaww... zzzz What time is it? ... "); 
     State nextState = new Play(); 
     nextState.setContext(context); 
     context.currentState = nextState; 
    } 
} 
class Play extends State { 
    public void doSomething(){ 
     sout("boing, boing, poing, poing"); 
     State nextState = new Dinner(); 
     nextState.setContext(context); 
     context.currentState = nextState; 
    } 
} 
class Dinner extends State { 
    public void doSomething(){ 
     sout("Yum, yum..."); 
     State nextState = new Sleep(); 
     nextState.setContext(context); 
     context.currentState = nextState; 
    } 

}

Et puis votre classe client juste l'utiliser!

Pet myPet = Pet.createNew(); 

while(I_FeelLikePlaying()){ 
    myPet.doSomething(); 
} 
0

Voir here pour une amélioration, en-avantages-de-NET-installations version du modèle d'état. Un état peut être une fonction simple (qui fera la plupart du temps), mais il peut aussi être un objet (ou une autre machine d'état) ...

Cordialement,

Andreas