Pregunta

Aquí hay un ejemplo de implementación del algoritmo en la clase absctract base de 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;
}

No me gusta porque creo que "showBookTitleInfo" sabe demasiado sobre los métodos que llama.

Aquí hay otro ejemplo     clase abstracta template_method {         var $ state;         función pública __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++;
    }
}

¿por qué pasamos el evento como referencia, si no cambiamos su valor? ¿Cómo debo implementar " mis pasos " ¿la lógica, si están utilizando el estado actual, puede modificar su valor y otros pasos pueden leer el valor modificado y también pueden modificarlo?

Por ejemplo, quiero implementar un mecanismo de conteo de costos para el envío programado de mensajes: simple y recurrente (por ejemplo, todos los lunes, viernes hasta el 23.05.2009).

Entonces, implemento el algoritmo en clase abstracta de la siguiente manera:

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;
    }
}

¿Me estoy moviendo en la dirección correcta? ¿Es donde se debe implementar el patrón de diseño del método de plantilla? Avíseme si hay algún problema con este código.

P.S. El contador de costos no es un código de producción. Lo escribí porque quería darte una idea.

Gracias de antemano

¿Fue útil?

Solución

El patrón de método de plantilla le da a la clase principal mucho control, la clase principal tiene que saber mucho sobre los métodos abstractos (su firma) porque tiene que 'controlar' el algoritmo. Por cierto, el método concreto en la clase padre tiene que ser final.

No tiene ninguna ventaja con sus métodos firstStep secondStep, podría implementar lo que quiero en stepOne y no hacer nada en stepTwo ...

La pregunta es cuándo querría usar el Patrón de método de plantilla, no cómo reescribirlo para darle más flexibilidad :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top