概念

通过分配或委托至其他对象,委托模式能够去除核心对象中的判决和复杂的功能性。

实现场景

添加音乐、并且根据音乐类型获取不同的音乐列表(返回字段形式均不一样)

使用委托模式 VS 简单实现 (UML)

使用基本实现方式调用时,需要if-else的判断,并且音乐类型不断增加,会导致PlayList类无限扩大。但是使用委托模式,在初始化类时,已经声明音乐类型$type,例如M3U,根据类型找到M3UPlaySong类,其余的查询列表均在委托类中进行实现。

代码实现

<?php

class Playlist
{
    private $_song;

    public function __construct()
    {
        $this->_song = [];
    }

    public function addSong($location, $title)
    {
        $song = ['loc'=>$location,'title'=>$title];
        $this->_song[] = $song;
    }

    public function getM3UList() {
        $m3u = "#M3U#\n";

        foreach ($this->_song as $song) {
            $m3u .= "音乐位置".$song['loc'];
            $m3u .= "音乐名称".$song['title'];
        }

        return $m3u;
    }

    public function getPLSList() {
        $m3u = "#PLS#\n";

        foreach ($this->_song as $song) {
            $m3u .= "music loc".$song['loc'];
            $m3u .= "music title".$song['title'];
        }

        return $m3u;
    }
}

$obj = new Playlist();
$obj->addSong('ssss','every');
$obj->addSong('dsdsda','one');

$ext = 'm3u';
if ($ext == 'm3u') {
    var_dump($obj->getM3UList());
} else {
    var_dump($obj->getPLSList());
}
echo "\n";
class NewPlaySong {
    private $_song;
    private $_SongType;
    public function __construct($type)
    {
         $this->_song =[];
         $song_type = strtoupper($type).'PlaySong';
         $this->_SongType = new $song_type ();
    }

    public function addSong($location, $title)
    {
        $song = ['loc'=>$location,'title'=>$title];
        $this->_song[] = $song;
    }

    public function getPlayList() {
        $play_list = $this->_SongType->getPlayList($this->_song);
        return $play_list;
    }
}

class M3UPlaySong {
    public function getPlayList($song_list) {
        $m3u = "#M3U#\n";

        foreach ($song_list as $song) {
            $m3u .= "音乐位置".$song['loc'];
            $m3u .= "音乐名称".$song['title'];
        }
        return $m3u;
    }
}

$obj = new NewPlaySong('m3u');
$obj->addSong('ssss','every');
$obj->addSong('dsdsda','one');

var_dump($obj->getPlayList());