Chiamate riflessive di oggetti nella stessa gerarchia

0

Non sono sicuro di come esprimerlo. Credo che questo avrebbe dovuto essere chiesto da qualche parte, ma non riesco a trovarlo perché non conosco le parole chiave.

Fondamentalmente, ho alcuni tipi come questo:

interface Foo
    class Bar0 extends Foo
    class Bar1 extends Foo
    class Bar2 extends Foo

E Foo è un'interfaccia come questa:

interface Foo{
    Result compare(Foo other);
}

Il metodo Foo.compare(Foo) è riflessivo, cioè assert a.compare(b).equals(b.compare(a)) . Pertanto, l'implementazione di Bar0.compare(other) dove other è un'istanza di Bar1 , dovrebbe avere la stessa implementazione (eccetto lo scambio di this e other ) come Bar1.compare(other) dove other è un'istanza di% % co_de.

Pertanto, ovviamente non dovrei implementarle entrambe. Ad esempio, se ho implementato per Bar0 , Bar0.compare(Bar1) deve reindirizzare a una chiamata riflessiva ( Bar1.compare(Bar0) ). Tuttavia, è molto scomodo perché devo assicurarmi che solo uno sia implementato ed evitare la ricorsione reciproca accidentale. Apparentemente, nella mia reale implementazione, le sottoclassi non sono denominate return other.compare(this); , Bar0 e Bar1 .

Esiste un metodo conveniente, affidabile ed efficace per implementarlo al fine di garantire che la ricorsione reciproca o l'implementazione ripetuta non si verifichino?

Inoltre, c'è un termine per questa situazione? (Voglio fare qualche ricerca da solo, ma non conosco nemmeno le parole chiave)

    
posta SOFe 08.07.2016 - 14:19
fonte

1 risposta

2

Mi sembra che dovresti implementare

IComparer 
{
    Result Compare(Foo,Foo)
    bool CanCompare(type1,type2)
}

come versione specifica per tipo

ComparerBar1Bar2 : IComparer
{
    Compare(Foo first ,Foo other)
    {
        return (Bar1)first == (Bar2)other;
    }

    bool CanCompare(type1,type2)
    {
        return type1 = Bar1 and type2 = Bar2;        
    }
}

e inietti un set di questi nelle istanze delle tue classi

Foo
{
    Compare(Foo other)
    {
         iComparer = mycomparers.getComparer(this.Type,other.type)
         iComparer(this, other)

         //if we couldnt find one...
         iComparer = mycomparers.getComparer(other.type, this.type)
         iComparer(other, this)
    }
}

Se il confronto non cambia mai, puoi avere questo elenco come statico invece di iniettare, ma ricordati di assicurarti di poter chiamare i comparatori sovrascritti correttamente nelle sottoclassi

    
risposta data 08.07.2016 - 14:30
fonte

Leggi altre domande sui tag