Come dovrei strutturare queste classi Python?

1

Classe base

Ho una classe chiamata Remote . Questa classe rappresenta una macchina remota e ha proprietà come ip , hostname , username e password , così come i metodi per il trasferimento dei file alla / dalla macchina e il codice in esecuzione sulla riga di comando della macchina.

Classi basate su provider VM specifici

Ho più sottoclassi di Remote , come SLRemote , per macchine remote in esecuzione su SoftLayer, VBRemote per macchine in esecuzione in Virtual Box e potenzialmente in futuro potrei creare altre sottoclassi come AWSRemote per macchine remote in esecuzione su Amazon Web Services, ad esempio.

Queste classi hanno il metodo __init__ impostato in modo che possano includere alcuni argomenti specifici del provider VM e trovare correttamente una VM esistente o eseguire il provisioning di una nuova VM. Poiché ciò potrebbe richiedere un po '(IE, SoftLayer richiede 2-20 minuti per configurare una nuova VM, a seconda delle dimensioni dell'immagine e delle condizioni della rete), il metodo __init__ esegue queste attività su un thread separato e definisco __getattribute__ metodo che join s il thread di creazione se richiede che la VM sia finita (IE, come puoi trasferire i file alla / dalla macchina se non ha terminato il provisioning?)

Classi basate su software specifico

Ho anche classi come DB2Server , WASServer e FTPServer , che rappresentano macchine remote su cui è installato un software specifico. Mi sembra che anche queste classi dovrebbero in qualche modo ereditare da Remote. Proprio come Remote , hanno un ip , un hostname , un username e un password . Proprio come vuoi trasferire i file in Remote , vuoi trasferire i file in queste classi.

Soluzioni che ho considerato

1 - Quindi voglio sottoclasse Remote , giusto? Bene, no, non proprio, perché DB2Server potrebbe essere installato su SLRemote o VBRemote o AWSRemote , oltre al generico Remote .

2 - E riguardo l'ereditarietà multipla? Di nuovo, no, non proprio, perché poi devo scrivere una serie di classi per ereditare da ogni specifico fornitore VM con il software specifico. Inoltre, cosa succede se installi più cose sullo stesso server?

3 - Attualmente, il progetto che sto seguendo è che le classi basate su software specifico installato ereditano da object (sto usando Python 2), e il metodo __init__ prende in remote discussione. Ho scritto __getattribute__ e __setattr__ in modo che oltre a interrogare direttamente l'oggetto per gli attributi, controlla anche l'oggetto remote per quegli stessi attributi.

Ma questo è fastidioso perché mi richiede di scrivere esattamente lo stesso metodo __getattribute__ e __setattr__ in ciascuna delle mie specifiche classi di software, e mentre il mio team sta crescendo e sempre più persone devono scrivere classi come queste, Devo arrivare a capire che sto usando questi metodi e hanno bisogno di replicare anche quel codice. Ha un cattivo odore di codice.

4 - Mentre stavo scrivendo quello che sto facendo, mi è venuto in mente (i vantaggi di scrivere il tuo problema su Stack Exchange ... o una nota appiccicosa ... o un'e-mail ... o raccontandolo a qualcuno che non sa nulla del problema di cui stai parlando). Potrei scrivere una classe base Software che accetta solo un'istanza Remote e definisce i metodi __getattribute__ e __setattr__ . Quindi DB2Server , WASServer e FTPServer erediterebbero invece da quello.

Altre cose di cui sono vagamente consapevole potrebbero essere d'aiuto?

metaclassi? Programmazione orientata all'aspetto? Mix-ins? Questi sono tutti concetti di cui sono vagamente consapevole ... qualcuno di questi mi aiuterebbe con il mio problema?

Qual è il modo giusto per farlo? Qual è il design standard e corretto da applicare alla mia situazione?

Ottieni meta con queste domande ora:

  • Come posso riassumere meglio questo problema e creare un titolo utile per la domanda con esso?

  • È questo anche il posto giusto per chiederlo? La domanda non coinvolge una singola riga completa di codice, quindi CodeReview non è sicuramente il posto giusto e StackOverflow non sembra giusto,

posta ArtOfWarfare 05.08.2015 - 21:27
fonte

2 risposte

2

Li lascerei completamente separati. I servizi e i server (notare che separo attentamente l'hardware estratto e il software astratto) sono cose separate.

Vorrei che ogni Service oggetto abbia una proprietà Remote (o VMInstance o qualsiasi cosa tu voglia chiamarla), possibilmente trasmessa in un contructor, che potrebbe essere potenzialmente modificabile (migrazione di servizio ...).

A quel punto, potrebbe essere che tu decida che mentre è conveniente avere un accesso per alcune proprietà che (in senso stretto) dipende probabilmente solo da Remote sulla tua istanza Service , puoi implementarla come un semplice pass-through (almeno per un'operazione get-type).

    
risposta data 06.08.2015 - 13:37
fonte
0

Mi sembra che "remoto" sia una proprietà di un oggetto, non qualcosa che lo definisce. In altre parole, hai pensato di utilizzare composizione piuttosto che ereditare? Ad esempio, un AWSRemote è in realtà un VM e un Remote , e un DB2Server potrebbe essere una VM specifica o una macchina fisica, localmente o in remoto. Un costruttore di DB2Server potrebbe ad esempio prendere un oggetto che consente di installarlo e configurarlo e un altro oggetto che ti consente di comunicare con esso come utente.

    
risposta data 05.08.2015 - 23:49
fonte