Per illustrare la mia preoccupazione principale, iniziamo considerando un tipico problema "banale", il filtraggio dei dati e l'amp; parsing proveniente da un processo e scaricando le informazioni su qualcosa {gui console, file, stdout, ...}. Ora, diciamo che abbiamo un "codebase" comune (esempio minimo e molto semplificato):
class Listener:
def on_process(self, line):
print(line)
class CommandExecutor:
def __init__(self, on_process=None):
self.on_process = on_process
def run(self):
lines = [
".\a.py:9:9: F841 local variable 'foo' gives error1",
".\b.py:9:9: F842 local variable 'bar' gives error2",
".\c.py:9:9: F843 local variable 'foo' gives error3"
]
for l in lines:
if self.on_process:
self.on_process(line=l)
Quindi, dopo un po 'di riflessione, diciamo che ho raccolto dalla dozzina di possibili soluzioni solo 3, cioè:
solution1
if __name__ == "__main__":
l = Listener()
def process_line(line):
if "F842" in line:
return False, None
else:
return True, f"{line} <---PARSED SUCCESFULLY"
def on_process(**kwargs):
line = kwargs["line"]
valid_line, new_line = process_line(line)
if valid_line:
l.on_process(new_line)
c = CommandExecutor(on_process)
c.run()
Solution2
if __name__ == "__main__":
l = Listener()
def process_line(line):
if "F842" in line:
raise Exception("Invalid line")
else:
return f"{line} <---PARSED SUCCESFULLY"
def on_process(**kwargs):
try:
line = kwargs["line"]
new_line = process_line(line)
l.on_process(new_line)
except Exception as e:
pass
c = CommandExecutor(on_process)
c.run()
SOLUTION3
if __name__ == "__main__":
l = Listener()
def check_line(line):
if "F842" in line:
return False
else:
return True
def parse_line(line):
return f"{line} <---PARSED SUCCESFULLY"
def on_process(**kwargs):
line = kwargs["line"]
if check_line(line):
l.on_process(parse_line(line))
c = CommandExecutor(on_process)
c.run()
E dopo che alcuni pensieri hanno concluso che:
- Soluzione1: è quella meno pitone, la più pericolosa di tutto il set ma probabilmente la "più veloce" (microottimizzazione)
- Soluzione2: è "più pulito" di solution1 ma probabilmente sta facendo troppo, non ha una corretta separazione delle preoccupazioni
- Soluzione3: probabilmente è il codice più pulito ma sarà piuttosto prolisso e forse non offre troppi vantaggi
Sono abbastanza interessato a sapere se c'è un evidente "miglior candidato" dal gruppo di soluzioni di cui sopra ... o se c'è una soluzione migliore di quelle proposte.
Il fatto è che io tendo a perdere tempo quando scelgo una soluzione per risolvere un problema specifico specifico perché di solito trovo molte soluzioni ... In effetti, ho appena postato 3 possibili modi, ma nella mia testa ne ho poche dozzine ... E questo è davvero brutto perché ovviamente è una grande perdita di tempo e una grande indicazione che non conosco il modo migliore per affrontare un particolare problema. Mi piace quando posso scegliere una soluzione di codifica il più presto possibile
Quindi la domanda qui sarebbe, come decidere con quale soluzione astratta rimanere fedele prima di iniziare a usarla ampiamente nelle app? Vuoi veramente evitare di refactoring il meno possibile quando il numero di app che utilizzano una particolare soluzione è cresciuto così nel mio libro sembra che valga la pena di dare una giusta quantità di pensiero nelle fasi iniziali prima di aumentare di livello (voglio dire, estendere la tua app usando eredità, composizione, plugin, ...).