Una condizione su un argomento utilizzato in più chiamate di un metodo: applicato dal chiamante o dal metodo?

3

Supponiamo di avere un oggetto un di una classe A . Ha un metodo che ha bisogno di un argomento sotto forma di un altro oggetto di un particolare tipo - ma l'argomento dovrebbe anche essere in uno stato particolare, perché l'operazione eseguita dal metodo (diciamo che sta interrogando un servizio esterno, ma potrebbe essere qualcos'altro ) lo richiede.

class A(object):
    def action(self, argument):

        return do_something(argument)

La prima soluzione che mi viene in mente è semplice: il metodo dovrebbe applicare una condizione sui dati di input. Dovrebbe testarlo per lo stato richiesto e quindi sollevare un'eccezione o modificare lo stato:

class A(object):
    def action(self, argument):
        if argument.state == False:
            raise Exception()

        return do_something(argument)

class A(object):
    def action(self, argument):
        if argument.state == False:
            argument.change_state()

        return do_something(argument)

Tuttavia, l'istanza di cui stiamo parlando è solo una delle molte istanze di A . Tutte queste istanze devono eseguire la stessa operazione sui dati di input: testarla per uno stato particolare e quindi rafforzarla o semplicemente generare un'eccezione. Sembra che potrebbero utilizzare un'istanza condivisa di parametro il cui stato richiesto è già applicato da un chiamante esterno, istanza di classe B :

class B(object):
    def action(self, argument):
        argument.change_state()
        for a in self.instances_of_A:
            yield a.action(argument)

Poiché ritengo che l'operazione eseguita dal metodo non sia incapsulata correttamente senza applicare lo stato richiesto di argomento all'interno del metodo, penso che dovrebbe essere spostata nel precedente chiamante. L'oggetto a e tutte le altre istanze di classe A fornirebbero solo i dati necessari per eseguire l'operazione.

class B(object):
    def action(self, argument):
        argument.change_state()
        for a in self.instances_of_A:
            yield  do_something(argument, a.data)

Tuttavia, c'è un altro problema: l'operazione restituisce un valore che può essere interpretato in un modo correlato all'istanza di A per ottenere un altro pezzo di dati - e ora sembra che l'operazione do_qualcosa dovrebbe essere incapsulata in un metodo di classe A .

Come dovrei risolvere questo problema? Dovrei semplicemente mantenere il design attuale e rendere oggetto a i dati di ritorno che potrebbero essere utilizzati per interpretare il codice di ritorno fornito dall'operazione? Forse dovrei usare la catena di comando e modificare classe A per delegare l'operazione ad altre istanze di A? Quali sono gli altri modi in cui potrei gestirlo?

    
posta vikingr 21.11.2015 - 23:48
fonte

1 risposta

1

Suppongo che tu debba introdurre un semplice DTO nel tuo schema. Prendi il tuo agrument, controlla se è in uno stato valido e metti quello stato in un nuovo oggetto DTO. Nel tuo ultimo esempio, puoi farlo all'interno del tuo metodo B::action .

In questo modo non avrai più bisogno di controllare lo stato perché questo DTO è sempre in uno stato valido per definizione. A imporrà il suo contratto accettando solo questo DTO per un'operazione.

    
risposta data 23.11.2015 - 08:49
fonte

Leggi altre domande sui tag