Prefazione
Ho una libreria ORM per un database relazionale immobiliare. Il framework utilizzato è peewee
. La libreria contiene ~ 60 modelli, ognuno dei quali rappresenta una tabella distinta. I modelli rappresentano una (pre-definita, proprietaria) struttura dei dati immobiliari basata su XML. C'è una tabella di livello superiore chiamata immobilie (proprietà immobiliare), che rappresenta la radice del documento XML.
Ogni modello ha definito i metodi di classe from_dom(cls, dom)
e from_dict(cls, dictionary)
e metodi to_dom(self)
e to_dict(self)
che contengono una notevole quantità di codice.
Problema
La libreria funziona bene così com'è, ma il modulo ha attualmente 10255 linee di codice, il che rende piuttosto difficile la lettura e la manutenzione.
Prima idea
La mia idea era quindi quella di dividere il modulo in diversi moduli più piccoli, ciascuno per un modello. Questo, tuttavia, crea i seguenti problemi:
1) peewee
richiede l'impostazione del rispettivo modello di chiave esterna nella rispettiva definizione del modello. Per semplicità di presentazione assumiamo:
class Parent(Model):
@property
def semi_orphans(self):
return Child.select().where(
(Child.mom == self & Child.dad >> None)
| (Child.mom >> None & Child.dad == self))
class Child(model):
mom = ForeignKeyField(Parent)
dad = ForeignKeyField(Parent)
Quindi il modello di riferimento deve essere importato nella rispettiva definizione del modello.
2) Come dovrebbe chiarire l'esempio con la proprietà semi_orphans
, quasi tutti i modelli di riferimento devono conoscere i loro modelli di riferimento per determinati metodi di selezione.
Ciò creerebbe importazioni cicliche irrisolvibili come ho già provato con parti del codice.
Seconda idea
Così ho pensato, potevo esternalizzare i metodi di backreferencing in sottoclassi in mule separate. Ciò tuttavia li renderebbe non disponibili quando si fa qualcosa del tipo:
some_child = Child.get()
semi_orphans = some_child.mom.semi_orphans
Ciò attiverebbe un AttributeError
poiché some_child.mom
restituirebbe il modello base senza il metodo semi_orphans
.
Domanda
Sto trascurando qualcosa? È davvero impossibile suddividere la libreria in componenti più piccoli per aumentare la qualità e la manutenibilità del codice perché non c'è modo di eliminare le dipendenze cicliche?