Come gestire i passaggi aggiuntivi che fanno parte della classe concreta genericamente nel modello di progettazione del modello di modello?

1

Ho una serie di operazioni che devono essere eseguite come parte di un processo di grandi dimensioni e le sottoclassi possono leggermente differire in parte del passo. Questo problema sembra essere risolto utilizzando il metodo di modello del modello di progettazione, quindi ho qualcosa di simile in basso.

class BaseTemplate(object):
    def perform(self)
        self.disable()
        self.update()
        self.enable()

    def disable(self):
        # Generic behavior

    def update(self):
        # Generic behavior

    def enable(self)
        # Generic behavior

class FooTemplate(BaseTemplate):
    def enable(self):
       # Foo-specific behavior

    def update(self):
       # Foo-specific behavior

class BarTemplate(BaseTemplate):
    def update(self):
       # Bar-specific behavior

Tuttavia, il problema con update() è che i modelli concreti hanno solo bisogno di qualche passo in più su quello che ha fatto la classe base.

Ad esempio,

BaseTemplate

def update():
    # Get X
    # Set field A of X
    # Set field B of X

FooTemplate

def update():
    # Get Y (Y is a subclass of X)
    # Set field A of Y
    # Set field B of Y
    # Set field C of Y (Field C is specific to Y which is a subclass of X)

Il problema è che l'impostazione del campo di A e B è duplicata come mostrato sopra, quindi potrei fare qualcosa di simile in FooTemplate

def update():
    super(FooTemplate, self).update() # Handles fields A and B
    # Set field C

Tuttavia, il metodo delle super classi è un metodo anti-pattern Chiama Super poiché tutte le sottoclassi '% co_de' % deve chiamare update() altrimenti si interromperà.

Quindi, un approccio diverso sarebbe avere un metodo no-op che imposta il campo super.update() nella classe base e quindi implementare le sottoclassi dei template solo quando necessario. Tuttavia, questo approccio sembra violare il campo di aggiornamento OOP C è richiesto solo da C e altre sottoclassi di FooTemplate non dovrebbero saperlo.

Domande:

  1. È corretto utilizzare il modello di metodo del modello per il mio utilizzo?
  2. Come gestire BaseTemplate che aggiunge passaggi aggiuntivi mentre i modelli diventano concreti in un modo OOP?
  3. Qualche suggerimento in generale?
posta Harry Cho 04.01.2018 - 23:03
fonte

1 risposta

3

Cerca di non correggere su uno schema specifico. Se sembra che non si adatti, provane un altro. È difficile dire dal tuo esempio spoglio, quale modello potrebbe essere più appropriato, ma due modelli che vengono in mente sono pipeline e catena di responsabilità . In questo modo puoi comporre i tuoi processi da una serie di piccoli comandi e concatenarli. Ancora meglio, puoi modificare la sequenza in fase di runtime.

Puoi restare fedele al modello di modello, ma trovo che qualunque sia la struttura del metodo template che usi, allora ad un certo punto troverai una classe derivata in cui vuoi una granularità più fine o subisci una logica duplicata (come stai vivendo) . Questi modelli di ereditarietà vincolano molto le classi e un design più composito potrebbe rendere il codice più flessibile. In generale ereditare da una classe per evitare un po 'di codice duplicato è qualcosa da evitare e finisce con gerarchie di ereditarietà molto complicate che sono difficili da capire.

Se riesci a mostrare più del contesto, potrei essere in grado di offrire più suggerimenti. Cosa sono X e Y per esempio? da dove provengono i nuovi valori di A B e C, e in che modo Get ottiene istanze di X e Y?

    
risposta data 05.01.2018 - 00:45
fonte

Leggi altre domande sui tag