Implementazione di un metodo dell'interfaccia legacy ma con requisiti di firma diversi

1

Diciamo che ho un'interfaccia come

Public Interface CarManager {
    Car getCar(String model);
}

E ho un sacco di classi legacy che implementano questa interfaccia.

Ma ora ho un nuovo requisito in cui devo ancora implementare questa interfaccia, tuttavia il metodo getCar richiederebbe ora una nuova firma come

Public Class fancyNewImpl implements CarManager {
    Car getCar(Map<String, Int> modelAndYear) {
    // Do something, return something
    }
}

Qual è il modo migliore per risolvere questo problema, senza dover modificare la firma del metodo dell'interfaccia originale e tutte le sue classi di implementazione?

Ho letto un po 'sugli adattatori di interfaccia, ma non sono ancora convinto che questo soddisferà questo particolare caso d'uso.

    
posta SnG 17.02.2017 - 01:42
fonte

2 risposte

2

Opzione 1 - aggiungi solo un nuovo overload di metodi (ovvero: un metodo con lo stesso nome, ma con firma diversa e tecnicamente non ha mai considerato lo stesso metodo dal punto di vista della lingua) alla classe che implementa l'interfaccia

Questa è la risposta suggerita da Lars.

Pro: minimo sforzo

Contro: solo i chiamanti che conoscevano il nome della tua nuova classe concreta fancyNewImpl potevano eseguire il downcasting. Inoltre, se la nuova firma del metodo dovesse essere implementata anche un'altra classe concreta, come fancyNewImplTwo , i chiamanti che tentano di downcast alla prima classe concreta fallirebbero; un chiamante dovrebbe provare entrambe le classi concrete (o tutte le pertinenti) per trovare l'overload del metodo che può utilizzare.

Opzione 2 : definisce un'interfaccia che eredita da quella originale e ha il nuovo metodo di sovraccarico.

link

public interface FancyCarManager extends CarManager
{
    Car getCar(Map<String, Int> modelAndYear);
}

Quindi, implementa i due metodi nella classe concreta che implementa l'interfaccia FancyCarManager .

I chiamanti dovranno ancora eseguire un upcast (tecnicamente un controllo dell'interfaccia) a FancyCarManager e chiamare il nuovo metodo. Ma questa opzione consente a più classi concrete, come FancyNewImpl e FancyNewImplTwo , di essere richiamabili tramite la stessa nuova firma del metodo, tramite la nuova interfaccia.

Opzione 3 - Chiama comunque il metodo, senza interfaccia, tramite Java Reflection

Fondamentalmente questa risposta merita di essere downvoted solo perché ho menzionato questo. Ma nel posto di lavoro di programmazione reale, dovresti vedere un sacco di questo accadendo.

(Le opinioni sono mie e non sono correlate al mio datore di lavoro e non sono ispirate dal mio lavoro.Questa opinione può essere vista in blog di programmazione altrove e articoli su Internet.)

Opzione 4 - Abusa il parametro stringa codificando le cose in esso

Ad esempio, puoi concatenare l'anno nella stringa del modello come

Car car = carManagerInstance.getCar(model + ";" + year);

È possibile aggiungere qualsiasi numero di parentesi (come caratteri stringa), altre punteggiature, caratteri Unicode o anche caratteri non stampabili. Puoi vedere dove sta andando: spalare un frammento XML o un JSON in una stringa.

Probabilmente questo soffocherà qualsiasi codice esistente che si aspetta che la stringa venga formattata alla vecchia maniera.

Tuttavia, nelle basi di codice legacy in cui il vecchio incontra il nuovo (in un modo sanguinante in conflitto), questo accadrà molto. Ciò richiede uno sforzo di test molto elevato (assicurazione della qualità) e avrà sempre un tasso di difetti più alto, indipendentemente da quanto sforzo sia messo.

Promemoria

Solo perché qualcosa è menzionato in questa risposta non significa che sia corretto usarlo. Chiedi ai tuoi colleghi più esperti opinioni. Ciò è particolarmente utile se il tuo collega conosce la base di codice su cui stai lavorando e lo stile di codifica della tua azienda.

    
risposta data 17.02.2017 - 06:44
fonte
0

Un buon modo per risolvere questo problema è utilizzare il polimorfismo

Usando questo si aggiunge semplicemente un secondo metodo con lo stesso nome ma argomenti diversi, quindi si cambia la firma. Ciò consente ai consumatori esistenti di continuare a lavorare con la vecchia versione e consente ai nuovi consumatori di utilizzare la versione più recente del tuo metodo.

Questo è uno dei fondamenti del design OO.

    
risposta data 17.02.2017 - 02:21
fonte

Leggi altre domande sui tag