Quale oggetto dovrebbe avere la responsabilità di aggiornare lo stato di un altro oggetto?

1

Diciamo che ho una classe di entità ListOfItems con molte entità correlate Item . Questi elementi vengono elaborati in una classe ItemsProcessor che incapsula il comportamento. Questa classe ha diverse liste di controllo e variabili, ad esempio una lista processed_items . Ogni volta che un elemento viene elaborato, viene aggiunto all'elenco:

class ItemsProcessor:
    def __init__(self, list_of_items):
        self.items = list_of_items.items
        self.processed_items = []

    def process(self):
        for item in self.items:
            if self._process_item(item):
                self.processed_items.append(item)

Ma ora diciamo che abbiamo una classe secondaria ItemsProcessorAlt che incapsula un'ulteriore elaborazione. Ha bisogno di un riferimento a ItemsProcessor perché mantiene lo stato del processo, tra gli altri dati che usa:

class ItemsProcessorAlt:
    def __init__(self, processor):
        self.parent_processor = processor

    def process(self):
        for item in self.parent_processor.items:
            self._process_item_alt(item)

E questo è il modo in cui il processore principale userebbe quello alternativo:

class ItemProcessor:
    def process(self):
        # process all items as shown above
        if self._corrupt_items():
            subprocessor = ItemsProcessorAlt(self)
            subprocessor.process()

Ora, quando un oggetto viene elaborato da quest'ultima classe, lo stato del processo deve essere aggiornato, ovvero l'elenco processed_items . Di chi è la responsabilità di aggiornare questo stato?:

  • Dovrebbe ItemsProcessorAlt.process() aggiornare questi elenchi direttamente?
  • Dovrebbe ItemProcessor define a method to update the state and then ItemsProcessorAlt.process () 'chiamarlo?
  • Dovrebbe ItemsProcessorAlt.process() avere un valore di ritorno che suggerisce al processore principale come deve essere aggiornato lo stato?
  • Dovrebbe ItemsProcessorAlt impostare uno stato da solo in modo che quando il sottoprocesso è finito il processore principale aggiorni il suo stato basandosi su quello?

Si noti che il subprocessore sta usando variabili che giacciono nel processore principale e stanno cambiando mentre il processo / sottoprocesso viene eseguito.

    
posta dabadaba 14.09.2017 - 12:05
fonte

2 risposte

1

Nella progettazione orientata agli oggetti un oggetto dovrebbe essere responsabile e gestire il proprio stato. Quindi l'approccio OO sarebbe che ogni item ha un metodo process() che sa come elaborare quell'elemento. Il tuo ListOfItems potrebbe diventare un ItemCollection l'obiettivo qui è quello di nascondere la gestione dell'enumerazione dal codice chiamante, e quindi ItemCollection.ProcessItems() sarebbe responsabile di chiamare ogni item.process() e aggiungerli a una raccolta di articoli elaborati.

È quindi possibile utilizzare il modello di strategia per fornire il processo corretto nel momento in cui lo si conosce. Se si conosce la creazione di un articolo, il costruttore / fabbrica può garantire il processo corretto. Se non si conosce fino a quando non si chiama ItemCollection.ProcessItems() , è possibile aggiungere un argomento per fornire la funzione di elaborazione corretta o una funzione che può determinare quale utilizzare. Se hai solo bisogno di chiamare il processo alternativo se il primo processo fallisce in qualche modo, puoi fornire il processo alternativo come funzione di callback o gestirlo direttamente in item.process() .

Per gestire lo stato degli elementi sarebbe responsabilità di item.process() assicurare che sia impostato sullo stato appropriato o che restituisca un nuovo oggetto impostato allo stato appropriato se si desidera l'immutabilità. Quindi ItemCollection.ProcessItems() aggiunge quegli elementi a processed_items che potrebbe essere una proprietà di ItemCollection o un oggetto separato a seconda delle tue esigenze.

    
risposta data 14.09.2017 - 15:46
fonte
0

Ho diviso le responsabilità in una classe Manager, il contesto dell'operazione e diversi oggetti Processore:

class Context:
    def __init__(self):
        self.processed_items = []
        self.some_variable1 = 0
        self.some_other_necessary_variable = True

class Processor1:
    def process(self, item, context):
        """
        Process an item and changes current context
        """
        self._do_stuff(item)
        self._update_context(context)

class Processor2:
    def process(self, item, context):
        """
        Process an item and changes current context
        """
        self._do_another_stuff(item)
        self._update_context(context)

class ItemProcessingManager:
    def __init__(self):
        self.context = Context();
        self.items = [] #list of available items
        self.processor1 = Processor1()
        self.processor2 = Processor2()
        #or: self.processors = [Processor1(), Processor2()]

    def process_items(self):
        for item in self.items:
            self.processor1.process(item, self.context)
            #...and if necessary
            if self._has_corrupt_item(item, self.context):
                self.processor2.process(item, self.context)
    
risposta data 14.09.2017 - 16:33
fonte

Leggi altre domande sui tag