Come decidere, dovrei mettere i metodi per astrarre la classe o per interfacciarlo?

3

Sto scrivendo un'app per cui è necessario disporre di una fase di registrazione generica. Deve essere in grado di fare alcune cose specifiche (io uso l'interfaccia per questo) e deve essere un elemento visivo (di Xamarin, non importa, però), diciamo VisualElement (io uso la classe astratta per quello). Ecco come appare:

public interface IRegistrationStep
{
    Task<bool> Validate();
    void Minimize();
    void Maximize();
}

public abstract class RegistrationStep : ContentView, IRegistrationStep
{
    public abstract Task<bool> Validate();
    public abstract void Minimize();
    public abstract void Maximize();
}

Dopo, deduco tutti i miei passi da RegistrationStep . Se ho bisogno del passo per essere in grado di fare ancora una cosa, semplicemente lo aggiungo all'interfaccia, aggiungo il metodo astratto alla classe astratta e lo implemento nell'implementazione astratta della classe ... O forse no? Come, forse a volte dovrei aggiungere metodi solo alla classe astratta e non all'interfaccia?

La mia domanda è, come posso decidere dove aggiungere nuovi metodi? Ci sono esempi quando è più ragionevole aggiungere metodi alla classe astratta e non all'interfaccia?

    
posta nicks 15.09.2016 - 09:47
fonte

3 risposte

4

Applica il principio YAGNI: se è sufficiente aggiungere il nuovo metodo alla classe astratta, aggiungilo solo lì - non aggiungere nulla a IRegistrationStep "non hai ancora bisogno di (ancora)". Ma se hai un codice che ha una dipendenza da IRegistrationStep e che sta per usare il nuovo metodo, devi ovviamente aggiungerlo in entrambi i posti.

    
risposta data 15.09.2016 - 09:58
fonte
1

In generale, l'estensione di un'interfaccia non è una buona idea. Un'interfaccia dovrebbe offrire un'unica funzionalità distinta. Se hai bisogno di più tardi dovresti definire un'interfaccia aggiuntiva e implementarla anche nella tua classe.

Hai una buona ragione per usare le interfacce? Ti aspetti di volere e implementare quell'interfaccia su altre classi che non ereditano dalla stessa classe base che RegisterStep eredita da? In caso contrario, probabilmente non vi è alcun valore aggiunto e sarebbe meglio non utilizzare affatto le interfacce.

Il nome dell'interfaccia non è così bello. Un'interfaccia definisce il comportamento, non un oggetto. Questo è il motivo per cui vedrai nomi come IEnumerable e IDisposable anziché IEnumerator o IDisposer. Allo stesso modo, il tuo dovrebbe essere denominato IRegistrationSteppable. Se ciò ti sembra strano, potrebbe essere solo un'altra interfaccia indicatore non adatta al tuo problema.

    
risposta data 15.09.2016 - 16:31
fonte
0

Il duro requisito per le interfacce arriva quando devi ereditare da più di una cosa.

(c # non ti consente di ereditare da più di una classe poiché ciò può causare qualche ambiguità interessante sul metodo da chiamare in alcuni casi limite)

quindi di avere un ConcreteRegistrationStep , che vuoi ereditare dall'astratto ma anche implementare qualche altra funzionalità, ad esempio IDisposable il fatto che esiste un'interfaccia IDisposable anziché una classe astratta che ti permette di fare eredita l'interfaccia e quindi puoi lanciare ConcreteRegistrationStep su un dispositivo usa e getta.

Seguendo questa logica puoi vedere che avere IRegistrationStep e utilizzare questo codice che consuma RegistrationSteps piuttosto che la classe astratta consentirà a te o ad altri una maggiore flessibilità in futuro.

    
risposta data 15.09.2016 - 10:46
fonte

Leggi altre domande sui tag