Va bene avere una classe astratta vuota per rendere le classi concrete polimorfiche

5

PRIMA:

Ho un'interfaccia che ha una definizione di metodo

public interface IDockable
{
    void Dock(DockerContainerConfig config);
}

Tutto è ok per la mia prima implementazione

public class DockerContainer : IDockable
{
    public void Dock(DockerContainerConfig config)
    {

    }
}

public class DockerContainerConfig
{ 
    //machine configuration properties here 
}

Nella mia seconda implementazione, tuttavia, mi sono reso conto che ho bisogno di utilizzare un diverso set di configurazione.

public class DockerMachine : IDockable
{
    public void Dock(DockerMachineConfig config)
    {

    }
}

public class DockerMachineConfig
{
    //machine configuration properties here 
}

DOPO:

Per rendere il Configuration Classes polimorfico, ho creato una classe genitore e lasciato ereditare Configuration Classes da esso.

public class DockerConfig
{

}

public class DockerMachineConfig : DockerConfig
{
    //machine configuration properties here 
}

public class DockerContainerConfig : DockerConfig
{
    //container configuration properties here 
}

Con questo ho anche cambiato la definizione del metodo per l'interfaccia.

public interface IDockable
{
    void Dock(DockerConfig config);
}

E nelle mie lezioni concrete, ho appena fatto un cast sugli oggetti della classe di configurazione. Si prega di notare che le due classi di configurazione sono totalmente diverse, nulla è comune. Uno si occupa della macchina, quindi ha bisogno della configurazione della macchina e l'altra si occupa del contenitore, quindi ha bisogno della configurazione del contenitore. Ma in ogni caso lo fai, DockerContainer e DockerMachine fa la stessa cosa. "aggancia un container all'interno di una macchina" . È qualcosa come DockerMachine fa cose dall'esterno e DockerContainer fa le cose dall'interno. Hai un'idea:)

public class DockerContainer : IDockable
{
    public void Dock(DockerConfig config)
    {
        DockerContainerConfig container = config as DockerContainerConfig;
    }
}

public class DockerMachine : IDockable
{
    public void Dock(DockerConfig config)
    {
        DockerMachineConfig machine = config as DockerMachineConfig;
    }
}

Ci sono due cose che penso di aver fatto un errore qui:

  1. Ho modificato la definizione del metodo nell'interfaccia da void Dock(DockerContainerConfig config); a void Dock(DockerConfig config);
  2. Ho creato una classe genitore vuota public class DockerConfig{} solo per poter rendere il mio Configuration Classes polimorfico

Vorrei sapere se le modifiche apportate sono conformi al buon design e alle migliori pratiche.

    
posta jmc 14.10.2016 - 10:46
fonte

2 risposte

17
public interface IDockable<T>
{
    public void Dock(T config);
}

Avendo un parametro type, puoi specificare il parametro che vuoi accettare all'interno del metodo Dock nelle tue classi. Esempio:

public class DockerMachine : IDockable<DockerMachineConfig>
{
    public void Dock(DockerMachineConfig config)
    {
    }
}

public class DockerContainer : IDockable<DockerContainerConfig>
{
    public void Dock(DockerContainerConfig config)
    {
    }
}

Questo sarebbe il mio modo preferito per farlo, ma ci sono molti altri modi con cui riuscirai a formarti. Quello che stai facendo al momento potrebbe essere decisamente semplificato avendo un parametro di tipo sull'interfaccia IDockable che sarebbe un po 'più pulito a mio parere.

    
risposta data 14.10.2016 - 12:23
fonte
9

Le parti specifiche dell'implementazione non dovrebbero far parte dell'interfaccia. Prendi invece ogni configurazione specifica come parametro costruttore.

public interface IDockable
{
    void Dock();
}

public class DockerContainer : IDockable
{
    private DockerContainerConfig config;

    public DockerContainer(DockerContainerConfig config)
    {
        this.config = config;
    }

    ...
}

public class DockerMachine : IDockable
{
    private DockerMachineConfig config;

    public DockerMachine (DockerMachineConfig config)
    {
        this.config = config;
    }

    ...
}
    
risposta data 14.10.2016 - 16:29
fonte

Leggi altre domande sui tag