L'impostazione dei campi di una classe base quando si utilizza il costruttore non è un'opzione

1

Sto rifattorizzando una classe base, le cui implementazioni sono plug-in, caricate in fase di runtime da un'altra classe usando reflection.

La classe di cui faccio refactoring utilizza un ID utente del dominio del modulo \ utente. Ho bisogno di estenderlo per funzionare anche con indirizzi email di dominio.

Per fare questo, ho introdotto una enumerazione di tipi di identificatori utente, ad esempio UserIdentifierType.DomainUser, UserIdentifierType.SmtpAddress, UserIdentifierType.SomeFutureType .

Affinché la classe funzioni, è necessario impostare il tipo di identificativo utente.

Il mio approccio abituale sarebbe quello di creare un costruttore che accetta il tipo di identificatore richiesto come argomento, ma il problema che ho è che la classe che consuma sa solo come chiamare il costruttore vuoto. Non è possibile cambiare la classe che consuma.

Invece, ho implementato un metodo di inizializzazione:

public void Initialise(UserIdentifierType userIdentifierType)
{
    _initialised = true;
}

Ogni metodo della classe base controlla che l'inizializzatore sia stato chiamato e genera un'eccezione se non.

if(!_initialised){throw new Exception("The Initialise() method must be called before using any other methods of this class");}

Per me, questo ha un odore peggiore delle mie calze! Non è trasparente, non è auto-documentante e non si adatta ai principi di OOP.

Esiste un modo più ordinato per eseguire l'impostazione del tipo di identificatore nell'istanza di base senza utilizzare un costruttore o un inizializzatore?

    
posta Simon 15.11.2014 - 15:24
fonte

1 risposta

1

Sembra che il tuo problema, in breve, è che devi apportare una modifica all'indietro incompatibile con una classe pubblica con più client che non controlli.

Il modo usuale per gestire questi problemi di compatibilità con le versioni precedenti è non cambiare il codice esistente . Invece, fornisci un'API completamente nuova che implementa la nuova funzionalità incompatibile all'indietro e annuncia che la vecchia classe è deprecata.

Ora puoi gradualmente convincere i tuoi clienti a cambiare il loro codice per usare la tua nuova classe. Una volta che tutti i tuoi utenti (o almeno tutti gli utenti a cui tieni) utilizzano l'API nuova e migliorata, puoi revocare il supporto per la vecchia classe e / o eliminarla.

Sembra molto lavoro, e in effetti lo è. Per il codice con molti clienti (framework e piattaforme in particolare) può anche richiedere anni. Ma l'alternativa sta infrangendo tutti i tuoi client API senza preavviso, facendo arrabbiare tutti, perdendo il lavoro e andando in rovina.

    
risposta data 15.11.2014 - 20:22
fonte

Leggi altre domande sui tag