2012-06-17 6 views
6

Eventuali duplicati:
Adding Extra method to interfaceL'aggiunta di nuovo metodo in Java Interface modo si tratta di modifiche minime alle classi che ereditano

C'è scenario in cui ho Interface X, che è stato attuato con i miei migliaia di classi. Ora voglio aggiungere un nuovo metodo in quello Interface X. Quindi, come apportare le modifiche in modo minimale per risolvere il problema dei metodi sovrascritti in tutte le mie classi

+0

Modificare l'interfaccia in una classe astratta e fornire un'implementazione di base? –

+8

Hai migliaia di classi? Wow. –

+0

@verisimilitude Questa soluzione non creerebbe presto un incubo di manutenzione e introdurrà molte interfacce nel sistema? – Thihara

risposta

1

Non esiste un modo semplice per farlo. Se si aggiunge un metodo all'interfaccia, tutte le classi di implementazione devono sovrascriverle. Se si modifica l'interfaccia in una classe astratta, è necessario ridefinire anche le classi di implementazione.

Ma hai una gerarchia di classi giusta? Quindi puoi minimizzare il lavoro implementando quel metodo solo nelle classi base. Ma ciò dipende dalle tue esigenze e dai tuoi dettagli specifici, quindi immagino che l'implementazione sia felice!

E se non esiste una gerarchia di classi semplice che è possibile utilizzare per implementare nuovi metodi come quello, forse è il momento di pensare a una grande riscrittura a favore della riduzione dello sforzo di manutenzione futura.

+1

Hai letto il link che @verisimilitude ha pubblicato in un commento? Se non lo fai, ti preghiamo di leggerlo, cambierà la tua risposta e il tuo punto di vista. –

+0

Sì, ma questo non porterà a problemi di manutenzione prima o poi? Dipende anche dal tipo di metodo che viene introdotto, se il metodo in questione è qualcosa che verrà utilizzato ovunque nell'interfaccia se usato come tipo, allora questa soluzione non aiuterà molto ... – Thihara

+0

Dipende davvero, se hai un gruppo, vale a dire 10+, di classi e si desidera solo che alcune di esse, cioè 2, quindi sarà come 2 classi implementando il nuovo metodo e 8+ averlo senza un'implementazione (design abbastanza male troppo). Se tutte le classi che implementano l'interfaccia effettiva dovrebbero avere questo nuovo metodo, allora la domanda OP sarà fuori luogo e non penso che OP abbia bisogno di questo :). –

11

vorrei creare un'estensione della vostra interfaccia per solo le classi che hanno bisogno di metodi aggiuntivi ...

public interface BaseInterface { 
    public int exampleMethod(); 
} 

public interface ExtendedInterface extends BaseInterface { 
    public int anotherMethod(); 
} 

Le migliaia di classi già implementano BaseInterface. Per le classi che richiedono il metodo aggiuntivo, le modifichi per implementare ExtendedInterface.

Se gli oggetti vengono memorizzati in una collezione così come un array BaseInterface[], questo funziona ancora perché gli oggetti di tipo ExtendedInterface sono anche oggetti di tipo BaseInterface, in modo che possano ancora essere immagazzinate nella stessa collezione comune.

Ad esempio, questo è ancora perfettamente valido ...

BaseInterface[] objects = new BaseInterface[2]; 
objects[0] = new ClassThatImplementsBaseInterface(); 
objects[1] = new ClassThatImplementsExtendedInterface(); 

Tuttavia, se avete bisogno di accedere al nuovo metodo della ExtendedInterface, ma l'oggetto viene memorizzato in una raccolta BaseInterface, è necessario di gettare in un ExtendedInterface prima di poter utilizzare ...

BaseInterface[] objects = new BaseInterface[1]; 
objects[0] = new ClassThatImplementsExtendedInterface(); 

if (objects[0] instanceof ExtendedInterface){ 
    // it is an ExtendedInterface, so we can call the method after we cast it 
    ((ExtendedInterface)objects[0]).anotherMethod(); 
} 
else { 
    // it is a BaseInterface, and not an ExtendedInterface 
} 

Questo può o può non essere adatto, a seconda dell'uso.

Se davvero avete bisogno di tutte le migliaia di oggetti per implementare il nuovo metodo, dovrete aggiungere il metodo allo BaseInterface e quindi utilizzare una funzionalità del vostro IDE o editor di testo per implementare il metodo in tutte le vostre classi. Ad esempio, è possibile aprirli tutti in un editor di testo e fare una ricerca-sostituzione su trovare qualcosa che è comune a ogni classe e sostituire con il codice comune + il codice predefinito per il nuovo metodo. Abbastanza veloce e indolore. Sono sicuro che alcuni IDE probabilmente aggiungerebbero automaticamente la dichiarazione del metodo a tutte le classi ereditarie, o almeno avranno un'opzione per farlo in un menu di scelta rapida.

+0

Questa è la stessa cosa che ha già detto verosimiglianza. – paulsm4

+0

D'accordo, ma questo è più specifico per il requisito dell'utente, ha un codice di esempio in esso, e secondo me è molto più facile da capire rispetto al post collegato. Inoltre, sono d'accordo con l'approccio, quindi perché non scrivere una risposta a tale effetto. – wattostudios

2

Se il nuovo metodo è una vera estensione dell'interfaccia, la cosa giusta da fare è modificare l'interfaccia e utilizzare gli strumenti dell'ambiente di sviluppo per trovare tutti i punti in cui la nuova funzionalità deve essere implementata. Quindi fai il lavoro. Eclipse e Netbeans faranno un ottimo lavoro.

[NB Sono un po 'sorpreso che gli strumenti di refactoring non si prendono cura di alcune delle sforzo manuale, ma così è.]

Se il nuovo metodo non sarà chiamato maggior parte del tempo nel vecchio codice, prendere in considerazione la nuova interfaccia per essere un'estensione di quello vecchio:

public interface NewInterface extends OldInterface { 
    void newMethod(); 
} 

Se avete bisogno di passare i vecchi oggetti di interfaccia per i nuovi consumatori di interfaccia con una versione nulla di newMethod(), si può fare qualcosa di simile:

public class NewInterfaceWrapper<T extends OldInterface> implements NewInterface { 

    private T wrapped; 

    public NewInterfaceWrapper(T wrapped) { 
     this.wrapped = wrapped; 
    } 

    // Define all the old interface methods and delegate to wrapped.method 

    // Now provide the null implementation of new method. 
    void newMethod() { } 
} 

... 

wantsNewInterface(new NewInterfaceWrapper(oldImplementer)); 

Non è bello, ma i grandi sistemi di solito crescono come in questo modo.

+0

Sembra WATTO Studios e ho la stessa idea. Felice di cancellare se questo non è utile. – Gene

+0

Mantieni il tuo post - hai un approccio diverso con i wrapper - non ci avevo pensato! – wattostudios

Problemi correlati