Esiste una best practice per inoltrare le sostituzioni del metodo durante l'esecuzione dell'esecuzione del metodo?

2

A volte ho un codice lungo le linee di questo:

    public abstract class A
    {
        protected abstract void DoSomething();
    }

    public abstract class B : A
    {
        /// <inheritdoc />
        protected sealed override void DoSomething()
        {
            SpecialFunctionalityOfClassB();
            DoSomethingInternal();
        }

        private void SpecialFunctionalityOfClassB()
        {
            // execute functionality i don't want an overwriting class to be able to 
            // break by not calling base.DoSomething()
            // redirect method execution to DoSomethingInternal
        }

        protected abstract void DoSomethingInternal();
    }

    public abstract class C : B
    {
        private void SpecialFunctionalityOfClassC()
        {
            // execute functionality i don't want an overwriting class to be able to 
            // break by not calling base.DoSomething()
            // redirect method execution to DoSomethingInternal
        }

        /// <inheritdoc />
        protected sealed override void DoSomethingInternal()
        {
            SpecialFunctionalityOfClassC();
            this.DoSomethingElse();
        }

        protected abstract void DoSomethingElse();
    }

Esiste una tecnica di cui non sono a conoscenza per garantire una catena di metodi inderogabile?

Se non dovessi sigillare i metodi, qualcuno potrebbe sovrascrivere un metodo e dimenticare di chiamarne la versione di base. In questo momento non vorrei sapere un altro modo per essere sicuro che chiunque provenga da D avrà tutte le funzionalità eseguite nel modo in cui lo voglio, senza una sottoclasse che rompa quella struttura.

    
posta Dbl 18.12.2017 - 17:45
fonte

2 risposte

4

Un approccio che potreste adottare è quello di rendere il vostro metodo DoSomething definitivo e delegare a un metodo di implementazione sovrascrivibile per eseguire l'operazione effettiva. Potrebbe quindi impostare un flag quando viene chiamata la sua versione del metodo di implementazione, che controllerebbe quando è ritornata a DoSomething e genera un'eccezione se non fosse avvenuta.

Questo approccio viene adottato, ad esempio, nei metodi del gestore di eventi dell'API di Android, per causare un'eccezione se l'implementatore non riesce a chiamare le versioni della superclasse di onCreate ecc.

    
risposta data 18.12.2017 - 18:23
fonte
2

Che ne dici di qualcosa di simile ...

public abstract class A
{
    protected void DoSomething()
    {
        // TODO: put class A logic here

        SpecialFunctionality(this);
    }

    protected abstract void SpecialFunctionality(A notUsed);
}

public abstract class B : A
{
    protected sealed override void SpecialFunctionality(A notUsed)
    {
        // TODO: put class B logic here

        SpecialFunctionality(this);
    }

    protected abstract void SpecialFunctionality(B notUsed);
}

public abstract class C : B
{
    protected sealed override void SpecialFunctionality(B notUsed)
    {
        // TODO: put class C logic here
    }
}

e così via ...

    
risposta data 18.12.2017 - 18:17
fonte

Leggi altre domande sui tag