设计模式之桥接模式

// 桥接方式 (将抽象部分与实现部分分离,使它们都可以独立的变化)
// 例子 : <消息通知> 信息分类作为抽象部分, 信息发送方式作为实现部分
// 桥接,就是让抽象部分拥有实现部分的接口对象

abstract class MsgType
{
    public function __construct(SendMsgOperator $impl) 
    {
        $this->_impl = $impl;
    }

    abstract public function getType();
}


interface SendMsgOperator
{
    public function send($msg);
    public function getType();
}

class SendSms implements SendMsgOperator
{
    public function send($msg)
    {
        echo "发送短信消息:$msg";
    }

    public function getType()
    {
        return '短信';
    }
}

class SendEmail implements SendMsgOperator
{
    public function send($msg)
    {
        echo "发送邮件消息:$msg";
    }

    public function getType()
    {
        return '邮件';
    }
}

class CommonMsg extends MsgType
{
    public function sendMsg($msg)
    {
        $msg = "$msg(普通)";
        $this->_impl->send($msg);
    }

    public function getType()
    {
        return '普通消息';
    }
}

class SpecialMsg extends MsgType
{
    public function sendMsg($msg)
    {
        $msg = "$msg(特别)";
        $this->_impl->send($msg);
    }

    public function getType()
    {
        return '特别消息';
    }
}

// 第三个纬度(抽象)
class LogType
{
    public function __construct(MsgType $msgType)
    {
        $this->_msgType = $msgType;
        $this->msgType = $this->_msgType->getType();
        $this->sendType = $this->_msgType->_impl->getType();
    }

    public function logFile()
    {
        echo <<<EOT
        写入文件 :
        发送类型 : {$this->sendType}
        消息类型 : {$this->msgType}
EOT;
    }

    public function logDb()
    {
        echo <<<EOT
        写入数据库 :
        发送类型 : {$this->sendType}
        消息类型 : {$this->msgType}
EOT;
    }
}



$smsImpl = new SendSms();

$emailImpl = new SendEmail();

$commonMsg = new CommonMsg($smsImpl); // 通过对象组合方式实现桥接

$commonMsg->sendMsg('haha');

echo '<br/>';

$specialMsg = new SpecialMsg($emailImpl);

$specialMsg->sendMsg('kaka');

$fileLog = new LogType($commonMsg);

echo '<br/>';

$fileLog->logFile();

$dbLog = new LogType($specialMsg);

echo '<br/>';

$dbLog->logDb();

标签: none