组合&把不同的实现隐藏在父类所定义的共同接口下

组合使用对象比集成体系更灵活,因为组合可以以多种方式动态的处理任务。

把不同的实现隐藏在父类所定义的共同接口下.

然后客户端代码需要一个父类的对象,从而使客户端代码可以不用关心它实际得到的是哪个具体的实现.

<?php

abstract class Lesson{
	private $duration;
	private $costStrategy;//支付策略

	function __construct($duration, CostStrategy $strategy)
    {
        $this->duration = $duration;
        $this->costStrategy = $strategy;
    }

    function cost(){
	    return $this->costStrategy->cost($this);
    }

    function chargeType(){
        return $this->costStrategy->chargeType();
    }

    function getDuration(){
        return $this->duration;
    }

    //Lesson类的更多方法
}

class Lecture extends Lesson{
    //Lecture特定的实现
}

 class Seminar extends Lesson{
    //Seminar特定的实现
 }

 abstract class CostStrategy{
    abstract function cost(Lesson $lesson);
    abstract function chargeType();
 }

class TimedCostStrategy extends CostStrategy{
    function cost(Lesson $lesson){
        return ($lesson->getDuration() * 5);
    }

    function chargeType(){
        return "hourly rate";
    }
}

class FixedCostStrategy extends CostStrategy{
    function cost(Lesson $lesson){
        return 30;
    }

    function chargeType(){
        return "fixed rate";
    }
}

$lessons[] = new Seminar(4, new TimedCostStrategy());
$lessons[] = new Lecture(4, new FixedCostStrategy());

foreach($lessons as $lesson){
    print "lesson charge {$lesson->cost()}.";
    print "Charge type: {$lesson->chargeType()} <br />";
}


?>