Risolve un'astrazione che perde (controllo del tipo)

4

Ho un metodo che accetta un'interfaccia e digita il controllo sul parametro, e in base al tipo viene presa una decisione per inviare un messaggio di posta elettronica o un avviso

    public void Bar(ISomeInterface someClass)
    {
        if (someClass is SomeClassToo)
        {
            Emailer.Send(someClass.Something());
        }
        else
        {
            Alerter.Alert(someClass.Something());
        }
    }

So che questo è negativo per ovvi motivi, ma mi piacerebbe sapere quali altre opzioni devo risolvere, poiché una delle soluzioni che ho è di mettere un'astrazione su ciascuna delle classi che implementa ISomeInterface per l'emailer / alerter usando un ICommunicator (vedi sotto) ma non sono sicuro che sia giusto in quanto sembra che da qualche parte nel mio codice ci sia qualcosa che controlla il tipo o sa di ogni tipo anche se è solo in una configurazione di container IOC .

public class SomeClass : ISomeInterface
{
    private ICommunicator _communicator;

    public SomeClass(ICommunicator communicator)
    {
        _communicator = communicator;
    }

    public void Something()
    {
        if (_communicator != null)
        {
            _communicator.Send("yee ha");
        }
    }
    
posta nickbw 01.09.2015 - 03:24
fonte

2 risposte

3

Senza il contesto completo è difficile sapere la cosa giusta da fare.

Mi sembra però che gli implementatori di ISomeInterface debbano fare qualcosa di diverso, a seconda dell'implementazione. Questo mi porta a credere che il tuo secondo approccio sia corretto.

Il fatto è che ogni implementazione di ISomeInterface può avere il proprio elenco di dipendenze. Uno potrebbe prendere un Alerter mentre un altro potrebbe prendere un Emailer . Fintanto che una classe "di terze parti" potrebbe chiamare ISomeInterface.Something() senza aver bisogno di sapere se Something() chiama un Emailer o un Alerter o un SkynetActivator impostato. Quando viene costruito SomeClass, qualcosa dovrà sapere quali dipendenze fornire, ma va bene, perché è una classe concreta.

Le classi concrete possono avere dipendenze. Le interfacce non dovrebbero dipendere dall'implementazione.

    
risposta data 01.09.2015 - 03:48
fonte
3

it feels like somewhere in my code there will have to be something that checks the type or knows about each type even if it is just in an IOC container configuration.

Il modello di comando

Un cenno a commento @Stephen .

Il modello di comando disaccoppia la "richiesta" dal richiedente. Citando il sito collegato:

  • encapsulate a request in an object
  • allows the parameterization of clients with different requests
  • allows saving the requests in a queue
    
risposta data 01.09.2015 - 18:11
fonte

Leggi altre domande sui tag