Domanda

Ecco un esempio di implementazione dell'algoritmo nella classe absctract di base da http://sourcemaking.com / design_patterns / template_method / php

public final function showBookTitleInfo($book_in) {
    $title = $book_in->getTitle();
    $author = $book_in->getAuthor();
    $processedTitle = $this->processTitle($title);
    $processedAuthor = $this->processAuthor($author);
    if (NULL == $processedAuthor) {
        $processed_info = $processedTitle;
    } else {
        $processed_info = $processedTitle.' by '.$processedAuthor;
    }
    return $processed_info;
}

Non mi piace perché penso che "showBookTitleInfo" sa troppo sui metodi che chiama.

Ecco un altro esempio     classe astratta template_method {         var $ state;         funzione pubblica __construct () {             $ this- > state = 0;         }

    public function processEvent( $event ) {
        $this->doFirstStep( $event );
        $this->doSecondStep( $event );
    }
    abstract public function doFirstStep( &$event );
    abstract public function doSecondStep( &$event );
}

class CustomLogic extends template_method {
    public function doFirstStep( &$event ) {
        echo __METHOD__.": state: ".$this->state." event: $event\n";
        $this->state++;
    }
    public function doSecondStep( &$event ) {
        echo __METHOD__.": state: ".$this->state." event: $event\n";
        $this->state++;
    }
}

perché passiamo l'evento come riferimento secondario, se non cambiamo il suo valore? Come devo implementare " i miei passi " la logica, se utilizzano lo stato corrente, può modificarne il valore e altri passaggi possono leggere il valore modificato e modificarlo anche?

Ad esempio, desidero implementare un meccanismo di conteggio dei costi per l'invio di messaggi programmati: semplice e ricorrente (es. ogni lunedì, venerdì fino al 23.05.2009).

Quindi, implemento l'algoritmo in classe astratta come segue:

abstract class AbstractCostCounter {
    public function countNotReccurentSendingCost($messageObj) {
        $totalMessages = $messageObj->getTotalMessages(); // multiple recipients are allowed
        $message_cost = 1; // just to give you an idea
        $this->cost = $totalMessages * $message_cost;
    }
    abstract public function countOptional();

    // I pass $messageObject not as by-reference, because it hasn't to be modified
    public function countCost( $messageObject ) {
        $this->countNotReccurentSendingCost( $messageObject );
        $this->countOptional( $messageObject );
    }

}

class TemplateNotReccurentCostCounting {
    public function countOptional($messageObj) {
        // do nothing
    }
}

class TemplateReccurentCostCounting {
    public function countOptional($messageObj) {
        $notReccurentSendingCost = $this->cost;
        $totalMessagesInScheduledPlan = $messageObj->getTotalMessagesInScheduledPlan();
        $reccurentSendingPlanCost = $notReccurentSendingCost * $totalMessagesInScheduledPlan;
        $this->cost = $reccurentSendingPlanCost;
    }
}

Mi sto muovendo nella giusta direzione? È dove dovrebbe essere implementato il modello di progettazione del metodo Template? Per favore fatemi sapere, se c'è qualcosa di sbagliato in questo codice.

P.S. il contatore dei costi non è un codice di produzione. L'ho scritto perché volevo darti un'idea.

Grazie, in anticipo

È stato utile?

Soluzione

Il modello del modello di modello offre alla classe genitore un controllo molto elevato, la classe genitore deve sapere molto sui metodi astratti (la loro firma) perché deve "controllare" l'algoritmo. A proposito, il metodo concreto nella classe genitore deve essere definitivo.

Non hai alcun vantaggio con i tuoi metodi firstStep secondStep, potrei implementare ciò che voglio in stepOne e non fare nulla in stepTwo ...

La domanda è quando vorresti usare Template Method Pattern, non come riscriverlo per dare maggiore flessibilità :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top