3 votes

Comment concevoir un modèle de commande avec différents écouteurs ?

J'ai une fenêtre qui fonctionne comme le concepteur de Visual Studio. Chaque document a deux vues :

  • Vue de la source,
  • Vue du designer.

J'ai une barre d'outils qui peut émettre différentes commandes. Le bouton de la barre d'outils possède une propriété de type chaîne CommandId qui stocke l'identifiant de la commande, par exemple :

  • Couper, copier, coller ;
  • Insérer la grille,
  • Format automatique
  • ...

J'ai du mal à concevoir un modèle de commande où l'exécution de la commande est différente selon la vue.

Pour un exemple évident, le Commande de copie copiera le texte sélectionné dans la fenêtre Vue de la source mais il copiera le contrôle sélectionné lorsqu'il se trouve dans la fenêtre Vue de l'architecte .

Je suis en train de cartographier le commandId à une chaîne CopyCommand mais comme l'exécution de la commande est différente selon la vue, je ne suis pas sûr de la manière dont cela doit être mis en œuvre.

  • Si chaque vue fournit une liste de commande concrète qu'elle comprend (et donc ayant deux CopyCommand comme Commande SourceCopyCommand y DesignCopyCommand qui partagent le même identifiant) ?

  • Ou bien chaque commande doit-elle être unique, mais la vue a une grande fonction de mappage qui change le comportement en fonction de l'identifiant de la commande ?

2voto

Ryan Michela Points 3330

Utilisez une combinaison des Modèle de stratégie et le Modèle d'État . Faites en sorte que chaque fenêtre implémente une interface qui définit les commandes communes qui peuvent lui être envoyées - ex. IWindowEditCommands . Pour les fenêtres multi-canaux, utilisez des objets de stratégie internes pour encapsuler les différentes implémentations des commandes communes pour chaque état de fenêtre possible. Le modèle State intervient lorsque vous passez d'un état de fenêtre à l'autre - par exemple, la vue de conception et la vue source. Lorsque la fenêtre change d'état, elle modifie le type de l'objet stocké dans le fichier commandState de manière appropriée, en veillant à ce que la bonne stratégie concrète soit utilisée pour mettre en œuvre les fonctions couper, copier et coller.

Pour connecter cette fonction à vos objets de commande de menu, il suffit que les commandes de menu trouvent la fenêtre actuellement sélectionnée et lui envoient le message approprié.

public interface IWindowEditCommands
{
    string Copy();
    string Cut();
    void   Paste(string buffer);
}

public class Editor implements IWindowEditCommands
{
    private IWindowEditCommands commandState;

    //constructor and other methods

    public void SwitchToSourceView()
    {
        //do stuff
        commandState = new EditorSourceViewStrategy(this);
    }

    public void SwitchToDesignView()
    {
        //do stuff
        commandState = new EditorDesignViewStrategy(this);
    }

    //IWindowEditCommands methods
    public string Copy() { return commandState.Copy(); }
    public string Cut()  { return commandState.Cut(); }

    public void Paste(string buffer) { commandState.paste(buffer); }

}

public class EditorSourceViewStrategy implements IWindowEditCommands
{
    private Editor editor;

    public EditorSourceViewEditCommands(Editor editor)
    {
        this.editor = editor;
    }

    public string Copy() {return...} //return the selected source from the source view
    public string Cut()  {return...} //return the and delete the selected source from the source view
    public void Paste(String buffer) {} //insert the buffer text at the insertion point
}

public class EditorDesignViewStrategy implements IWindowEditCommands
{
    private Editor editor;

    public EditorDesignViewEditCommands(Editor editor)
    {
        this.editor = editor;
    }

    public string Copy() {return...} //return the selected TAGS from the source view
    public string Cut()  {return...} //return the and delete the selected TAGS from the source view
    public void Paste(String buffer) {} //insert the buffer text at the insertion point
}

0voto

bytebender Points 5064

Et si vous passiez dans un ICommandContext (ce serait comme un récepteur, voir "Design Patterns" pg.234). Chacune de vos vues implémenterait cette interface et aurait alors la connaissance de la manière d'exécuter la commande. La seule responsabilité des objets de commande à ce stade est d'encapsuler l'action afin que vous puissiez appeler CopyCommand depuis le menu, depuis le clavier "Ctrl + C", avec un clic droit sur la copie, et peut-être d'une autre manière...

public interface ICommandContext 
{
void Cut();
void Copy();
void Past();
void AutoFormat(); 
}

public SourceView : ICommandContext
{
    public void Cut()
    {
        // Do stuff here...
    }
}

public class CopyCommand : Command
{
    public override Execute(ICommandContext context)
    {
        context.Copy();
    }
}

définition (de dofactory ) :

E vous permettant ainsi de paramétrer clients avec différentes requêtes, de mettre en ou d'enregistrer les demandes, et de supporter des annulables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X