2015-08-18 17 views
5

Sto tentando di utilizzare lo schema di comando per la prima volta e con esso creo una fabbrica di comandi, seguo le indicazioni di un corso di pluralsight.com in cui implementa un'interfaccia per la fabbrica che include un metodo MakeCommand.Metodo di fabbrica - Parametri sconosciuti

Ora il mio problema deriva dal fatto che passa semplicemente una serie di stringhe come argomenti per questo metodo (la sua è un'app della riga di comando), tuttavia i miei comandi utilizzeranno una varietà di argomenti di una varietà di tipi, il mio piano era quello di utilizzare questi comandi per archiviare gli aggiornamenti ai modelli, quindi se l'applicazione non può connettersi ai servizi, i comandi verranno messi in coda per quando la connessione ritorna.

Questo è sempre stato un po 'un punto critico per me con interfacce generiche, come gestisco la moltitudine di argomenti possibili?

Il mio primo pensiero è stato quello di passare il modello stesso, con un semplice argomento di stringa con il tipo di comando (Elimina, Aggiorna, ecc.) Tuttavia, poiché i miei modelli non hanno alcuna classe base o interfaccia comune mi rimane un simile problema.

Mi manca qualcosa di base qui?

MODIFICA: è stato richiesto un esempio del mio problema.

ho un'interfaccia CommandFactory come tale

public interface ICommandFactory 
{ 
    string CommandName { get; } 
    string Description { get; } 

    ICommand MakeCommand(..arguments..) 
} 

e non ho modelli semplici come (puro esempio)

public class Model1 
{ 
    public string Name {get;set;} 
    public int Age {get;set;} 
} 


public class Model2 
{ 
    public DateTime Time {get;set;} 
    public double Price {get;set} 
} 

se volevo creare un comando che, per esempio aggiornato un Model1, mi chiedo come dovrebbe essere il MakeCommand dell'interfaccia, non posso fare MakeCommand (string cmdType, modello Model1) perché ho diversi modelli diversi che non condividono nessuna baseclass/interfaccia comune

+0

Vorrei provare a creare una nuova interfaccia che contenga metodi per ottenere gli argomenti. Se ciò non corrisponde al tuo modello, dai un'occhiata ai parametri variadici. –

+3

Il tuo problema non è chiaro per me. Puoi mostrare qualche codice rilevante? – CodeCaster

+0

Certo, due secondi durante la modifica. – Ben

risposta

0

Ti suggerisco di usare lo schema di comando, questo modello usa il ricevitore come oggetto che contiene argomenti, nel tuo receiver puoi aggiungere un elenco o un dizionario di oggetti.

In questo sito è possibile trovare il codice sorgente

link: http://www.dofactory.com/net/command-design-pattern

+0

Quindi il tuo suggerimento è di evitare di usare il modello di fabbrica con lo schema di comando? – Ben

1

Sembra che si desidera che i singoli modelli per definire il modo in cui possono essere aggiornati. In tal caso, non è possibile passare una funzione/azione dal modello a MakeCommand?

public class Model 
{ 
    public string Name {get;set;} 
    public int Age {get;set;} 
    public void UpdateModel() {...} 
} 

public interface ICommandFactory 
{ 
    string CommandName { get; } 
    string Description { get; } 

    ICommand MakeCommand(Action<Model>); 
    ICommand MakeCommandFunc(Func<Model, bool>); 
} 

public class Command : ICommand 
{ 
    Action<Model> _action; 
    Command(Action<Model> action) 
    { 
     _action = action; 
    } 

    Execute() 
    { 
     _action(); 
    } 
} 

EDIT: Come richiesto, utilizzare la classe interfaccia comune per modellare tutte le classi

public interface IModel 
{ 
    void UpdateModel(); 
} 

public class Model1 : IModel 
{ 
    public string Name {get;set;} 
    public int Age {get;set;} 

    // implement updating of the model 
    public void UpdateModel() {...do model update...} 
} 


public class Model2 : IModel 
{ 
    public DateTime Time {get;set;} 
    public double Price {get;set} 

    // 'dummy' implement updating of the model if this model does not supports updating 
    public void UpdateModel() { // do nothing or throw NotImplementedException(); } 
} 

public interface ICommandFactory 
{ 
    string CommandName { get; } 
    string Description { get; } 

    ICommand MakeCommand(IModel model); 
} 
+0

No, questo non è quello che voglio. Il comando chiamerebbe i repository che aggiornano il modello, voglio semplicemente essere in grado di passare uno qualsiasi dei miei modelli alla fabbrica dei comandi. Ma dal momento che non hanno antenato o interfaccia comuni non sono sicuro di come passare il modello diverso. – Ben

+0

in tal caso sarà necessario passare un'interfaccia comune (può essere vuota anche) IModel ecc. Per collegare tutti questi modelli. Oppure (non è una buona idea), passare i modelli come oggetto alla fabbrica di comandi – sppc42

+0

Questo era il mio pensiero originale! ma poi ho letto così tanti commenti sulle interfacce vuote che sono davvero male all'odore di codice. Quindi questa domanda. – Ben

0

Si potrebbe anche rendere l'interfaccia ICommandFactory generica in questo modo:

public interface ICommandGeneric 
{ 
    void execute(); 
} 

public class CommandOnModel1 : ICommandGeneric 
{ 
    private Model1 model; 
    public CommandOnModel1(Model1 model) 
    { 
     this.model = model; 
    } 

    public void execute() 
    { 
     System.Diagnostics.Debug.WriteLine(model.ToString()); 
    } 
} 

public interface ICommandFactory <in ModelType> 
{ 
    string CommandName { get; } 
    string Description { get; } 

    ICommandGeneric MakeCommand(ModelType model, string parameter1); 
} 

public class Model1 
{ 

} 

public class Model1CommandFactory : ICommandFactory<Model1> 
{ 

    public string CommandName 
    { 
     get { return "CommandOnModel1"; } 
    } 

    public string Description 
    { 
     get { return "I do stuff on Model1"; } 
    } 

    public ICommandGeneric MakeCommand(Model1 model, string parameter1) 
    { 
     return new CommandOnModel1(model); 
    } 
} 

Detto questo, Non sono del tutto sicuro che dovresti usare una fabbrica e forse nemmeno lo schema di comando qui.

+0

Sto iniziando a pensare che lo schema di fabbrica sia in realtà più un problema, ma perché suggerisci che non dovrei usare lo schema di comando, sembra essere una buona soluzione per risolvere il mio problema originale (accodamenti di accodamento, cancella ecc. per l'esecuzione quando ritorna la connessione netta). – Ben

+0

@ user1412240 Non hai veramente descritto il tuo problema originale, quindi non posso dirlo con certezza. Forse lo schema di comando è la scelta migliore. –

Problemi correlati