模板方法设计模式中的对象状态

时间:2009-03-11 06:56:05

标签: php design-patterns template-method-pattern

以下是来自http://sourcemaking.com/design_patterns/template_method/php

的基础absctract类中的算法的实现示例
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;
}

我不喜欢它,因为我觉得“showBookTitleInfo”对它所调用的方法了解太多。

这是另一个例子     abstract class template_method {         var $ state;         public function __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++;
    }
}

为什么我们将事件作为按引用传递,如果我们不更改其值? 我应该如何实现“我的步骤”逻辑,如果它们使用当前状态,可以修改它的值,其他步骤可以读取修改后的值并且也可以修改它吗?

例如,我想为预定的消息发送实现成本计算机制 - 简单和重新安排(例如:每个星期一,星期五至2009年5月23日)。

所以,我在抽象类中实现了如下算法:

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

我是朝着正确的方向前进吗? 是应该实现模板方法设计模式的地方吗? 如果此代码有问题,请告诉我。

P.S。成本计数器不是生产代码。我写这篇文章是因为我想给你一个想法。

先谢谢

1 个答案:

答案 0 :(得分:1)

模板方法模式为父类提供了很多控制,父类必须对抽象方法(它们的签名)有很多了解,因为它必须“控制”算法。顺便说一句,父类中的具体方法必须是最终的。

你的firstStep secondStep方法没有优势,我可以在stepOne中实现我想要的东西,并且在stepTwo中什么都不做......

问题是你想什么时候使用模板方法模式,而不是如何重写它以提供更大的灵活性:)