È buona pratica creare metodi di delega convenienti?

4

Supponiamo che abbia un design del genere:

class Corpus:
    def something1(self):
        pass
    def something2(self):
        pass
    def serialize_to_stream(self, stream):
        _CorpusJsonSerializer().serialize(self, stream)

class _CorpusJsonSerializer:
    def serialize(self, corpus, stream):
        .
        .
        .
    .
    .
    . 

Penso che il processo di serializzazione dovrebbe essere in una classe separata per vari motivi. Ciò rende superfluo il metodo serialize_to_stream in Corpus . Vorrei comunque averlo lì perché penso che sia più facile per gli utenti del Corpus, perché non devono sapere nulla di un'altra classe CorpusJsonSerializer .

Pensi che sia ragionevole? O devo solo esporre il CorpusJsonSerializer e lasciare che l'utente faccia il lavoro?

    
posta Honza Brabec 19.08.2013 - 09:36
fonte

1 risposta

2

Questo è un compromesso tra facilità d'uso e disaccoppiamento.

Avere una parte serialize-method della tua classe Corpus può renderla più facile da usare, ma in questo modo la tua classe Corpus dipende da _CorpusJsonSerializer e viceversa, il che significa che hai una dipendenza ciclica. Questo è spesso un segno di progettazione errata, poiché rende difficile testare Corpus , più difficile da riutilizzare in un contesto diverso, più difficile da estendere ecc.

Nella maggior parte dei casi, eviterei soluzioni con dipendenze cicliche. Ancora meglio sarebbe una progettazione in cui non è necessario uno speciale _CorpusJsonSerializer , ma solo un generale JsonSerializer che accetta un oggetto arbitrario (ad esempio, di tipo Corpus ) e ne determina il tipo e gli attributi serializzabili digitare in fase di esecuzione. In questo modo, elimineresti tutte le dipendenze correnti.

Un'altra opzione di progettazione, che non è così generica ma evita la dipendenza ciclica, è quella di iniettare la dipendenza dall'esterno. Significa che nel costruttore Corpus viene fornito un parametro per un oggetto "serializzatore" che viene archiviato nell'oggetto Corpus e utilizzato nel metodo serialize_to_stream . Puoi passare qui un oggetto di _CorpusJsonSerializer nella maggior parte dei casi, ma anche un oggetto completamente diverso seguendo le stesse convenzioni di interfaccia (cioè fornendo un metodo serialize ). In questo modo, quando a scopo di test non è necessario un serializzatore, non è necessario fornirne uno; o se hai bisogno di un diverso tipo di serializzatore, puoi facilmente cambiarlo. Ovviamente, questa opzione implicherà che _CorpusJsonSerializer è esposto all'utente, ma puoi mantenere il metodo di convenienza in Corpus senza gli svantaggi delle dipendenze cicliche.

    
risposta data 19.08.2013 - 11:16
fonte

Leggi altre domande sui tag