1

これは、 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;
}

「showBookTitleInfo」が呼び出すメソッドについてあまりにも多くのことを知っていると思うので、私はそれが好きではありません。

別の例を次に示します。抽象クラス 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++;
    }
}

値を変更しないのに、なぜイベントを参照として渡すのでしょうか? 現在の状態を使用していて、その値を変更でき、他のステップが変更された値を読み取って変更できる場合、「私のステップ」ロジックをどのように実装すればよいですか?

たとえば、スケジュールされたメッセージ送信のコスト カウント メカニズムを実装したいと考えています。

したがって、次のように抽象クラスにアルゴリズムを実装します。

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

私は正しい方向に進んでいますか?Template メソッドの設計パターンを実装する必要がある場所ですか? このコードに問題がある場合はお知らせください。

PS コストカウンターは生産コードではありません。感想を言いたくて書きました。

前もって感謝します

4

1 に答える 1

1

テンプレートメソッドパターンは、親クラスに多くの制御を与えます。親クラスは、アルゴリズムを「制御」する必要があるため、抽象メソッド (そのシグネチャ) について多くのことを知っている必要があります。ところで、親クラスの具象メソッドは final でなければなりません。

あなたの firstStep secondStep メソッドには何の利点もありません。stepOne で必要なものを実装し、stepTwo では何もしません...

問題は、どのように書き換えて柔軟性を高めるかではなく、テンプレート メソッド パターンをいつ使用するかです:)

于 2009-03-11T07:22:20.147 に答える