Come evitare di trascinare gli argomenti dalla funzione alla funzione

5

Quando eseguo il layout del codice, mi piace iniziare con una vista di livello piuttosto elevato e quindi iniziare a delegare il calcolo effettivo alla classe o alle funzioni che hanno un po 'più di dettaglio. Poi in queste classi di funzioni, faccio lo stesso, strato per strato, fino a quando non arrivo al fondo dove devo fare l'azione "reale".

Esempio:

def build_table():
    legs = get_legs()
    plate = get_plate()
    return put_together(legs, plate)

def get_legs():
    legs = []
    for i in [0,1,2,3]:
        legs.append(get_leg_from_warehouse())
    return legs

def get_plate():
    plate = get_plate_from_warehouse()
    return finish_plate(plate)

def put_together(legs, plate):
    table = Table()
    for i in [0,1,2,3]:
       table.mount(legs[i])
    table.mount(plate)
    return table

class Table:
    self.component = []
    def mount(self, item):
        self.component.append(item)

In questo modo, trovo facile pensare al layout e nascondere la complessità. Per lo più ho brevi pezzi di codice che sono facili da capire.

Lo svantaggio di questo è che quando scopro che ho bisogno di un'informazione disponibile in cima allo stack più in basso, passo gli argomenti dalla funzione alla funzione. Nell'esempio sopra, potrei raccogliere "viti" in alto, e poi continuare a passarle in una funzione in cui sono effettivamente forate nel legno. Questo fa sì che non sia così facile modificare il codice, e mi chiedevo cosa avrei potuto fare al riguardo. In questo esempio il codice modificato sarà simile a questo:

def build_table():
    legs = get_legs()
    plate = get_plate()
    screws = get_screws()
    return put_together(legs, plate, screws)

def get_legs():
    legs = []
    for i in [0,1,2,3]:
        legs.append(get_leg_from_warehouse())
    return legs

def get_plate():
    plate = get_plate_from_warehouse()
    return finish_plate(plate)

def get_screws():
    drive_to_hardwarestore()
    screws = buy_screws()
    drive_home()
    return screws

def put_together(legs, plate, screws):
    table = Table()
    for i in [0,1,2,3]:
       table.mount(legs[i], screws)
    table.mount(plate, screws)
    return table

class Table:
    self.component = []
    def mount(self, item, screws):
        self.component.append((item, screws.pop()))

Quindi, oltre ad aggiungere il codice per ottenere le viti, ho dovuto modificare 4 righe. Ciò aumenterebbe linearmente con la quantità di livelli.

Come posso refactoring? D'altra parte, come posso evitare questo in primo luogo? Il mio processo di progettazione è "sbagliato"?

    
posta Isaac 15.11.2013 - 07:36
fonte

1 risposta

7

So besides adding the code for getting screws, I had to modify 4 lines. This would increase linearly with the amount of layers.

Penso che questo sia un errore. Quando aggiungi un altro tipo di parte di tabella, dovrai solo modificare 4 linee di codice nel tuo "livello di costruzione dell'oggetto". Gli strati sopra il livello di "costruzione di oggetti" nel tuo codice funzioneranno solo con oggetti "table", non modificati, a condizione che non debbano affrontare il nuovo tipo di parti. È possibile passare quell'oggetto tabella attraverso un numero arbitrario di livelli e non è necessario modificare nulla. E quando trovi una parte nel tuo codice in cui devi accedere alle tue viti, quel codice può semplicemente chiedere l'oggetto "tabella" per le viti.

Naturalmente, quando il processo di costruzione dell'oggetto diventa più complicato, e pensi di avere "troppe cose da fare", puoi prendere in considerazione la creazione di una classe factory (tabella) per incapsulare le costruzioni. In questo modo, è possibile creare "viti", "gambe" e "piastra" in un unico punto, memorizzarli in variabili membro della fabbrica e recuperarli successivamente nella funzione "montatura".

Quindi, finché il processo di costruzione è semplice, attenersi alla progettazione e, se diventa più complicato, utilizzare le classi di fabbrica.

    
risposta data 15.11.2013 - 09:28
fonte

Leggi altre domande sui tag