1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<?php //状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式 class Cd{ protected $song = '单曲轮播'; public function QQPlay(){ echo '使用QQ播放器播放:' . $this->song . '...<br>'; } public function BaiDuPlay(){ echo '使用百度播放器播放' . $this->song . '...<br>'; } } $cd = new Cd(); $type = 'qq'; if ( $type == 'qq') { $cd->QQPlay(); } else if ($type == 'baidu') { $cd->BaiDuPlay(); } //那么如果还要添加新浪、搜狐、其他播放器,就要去修改Cd类内部,而且if...else...会越来越多 //此时使用委托模式是一个不错的选择 class Cd1{ protected $song = '单曲轮播'; protected $player = null; public function setPlayer(Player $player){ $this->player = $player; } public function play(){ $this->player->play($this->song); } } interface Player { public function play($song); } class QQPlayer implements Player { public function play($song){ echo '使用QQ播放器播放:' . $song . '...<br>'; } } class BaiDuPlayer implements Player { public function play($song){ echo '使用百度播放器播放:' . $song . '...<br>'; } } //此时需要使用指定播放器来播放,则委托不同的播放器即可 $qqPlayer = new QQPlayer(); $cd = new Cd1(); $cd->setPlayer($qqPlayer); $cd->play(); $cd->setPlayer(new BaiDuPlayer()); $cd->play(); //当然以上demo也可以使用继承来实现,但是用一个播放器来继承一个CD,从语义上来讲不太合理 //如果说是一个人类,中国人继承他说中国话,英国人继承他说英国话...从语义上更为合理 //而且继承会破坏封装性,或者父类较为臃肿,有很多方法子类使用不到时,也不建议使用 //现在很多MVC框架中的Controller、Model、View都使用继承,可能是要定义一种规范,也不能说继承一无是处 //具体使用继承还是委托需要看不同的应用场景 //附:http://www.cnblogs.com/nuaalfm/archive/2010/04/23/1718453.html |