我和王争学设计模式|桥接模式

极客时间《设计模式》(王争)

定义

  1. GoF 的《设计模式》一书中

将抽象部分与它的实现相分离,是他们可以独立变化。

  1. 其他书中

一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。

对于第二种的解读,它非常类似“组合优于继承”设计原则,通过组合关系来替代继承关系,避免继承层次的指数级爆炸。

理解

假如我们去买车,从品牌、变速箱、天窗、发动机等四个维度去选择汽车,如下图所示,每一维度看着像桥上的木板,每一个维度中只能选择一个选项,然后通过箭头把4块木板连接起来,这样就形成了一个桥(桥接模式)。如果使用继承的方式来实现,那么需要实现432*5=120个类,而采用桥接模式后,需要实现4+3+2+5=14个类,可以极大解放敲代码的双手了。使用的时候车 = new 品牌(new 变速箱(new 天窗(new 发动机()))),看着像套娃的结构。

在这里插入图片描述

题目

根据不同的告警规则,触发不同类型的告警。告警支持多种通知渠道,包括:邮件、短信、微信、自动语音电话。通知的紧急程度有多种类型,包括:SEVERE(严重)、URGENCY(紧急)、NORMAL(普通)、TRIVIAL(无关紧要)。不同的紧急程度对应不同的通知渠道。比如,SERVE(严重)级别的消息会通过“自动语音电话”告知相关人员。

程度/方式短信邮件微信语音电话
重要重要-短信重要-邮件重要-微信重要-语音电话
紧急紧急-短信紧急-邮件紧急-微信紧急-语音电话
普通普通-短信普通-邮件普通-微信普通-语音电话
无关紧要无关紧要-短信无关紧要-邮件无关紧要-微信无关紧要-语音电话

实现

Notification 是抽象,MsgSender 是实现,两者可以独立开发,通过组合关系(也就是桥梁)任意组合在一起。所谓任意组合的意思就是,不同紧急程度的消息和发送渠道之间的对应关系,不是在代码中固定写死的,我们可以动态地去指定(比如,通过读取配置来获取对应关系)。
查看代码 GitHub Gitee

<?php

namespace App;


abstract class Notification
{

	protected $msgSender;

	public function __construct(MsgSender $msgSender)
	{
		$this->msgSender = $msgSender;
	}

	abstract public function notify($message);

}
<?php

namespace App;


class NormalNotification extends Notification
{
	public function notify( $message)
	{
		$this->msgSender->send($message);
	}
}
<?php

namespace App;


class SevereNotification extends Notification
{

	public function notify( $message)
	{
		$this->msgSender->send($message);
	}
}
<?php

namespace App;


class TelephoneSender implements MsgSender
{
	private $telephone;

	public function __construct($telephone)
	{
		$this->telephone = $telephone;
	}

	public function send($message)
	{
		echo "Send $message  $this->telephone by telephone" . PHP_EOL;
	}
}
<?php

namespace App;


class TrivialNotification extends Notification
{
	public function notify( $message)
	{
		$this->msgSender->send($message);
	}
}
<?php
namespace App;


class UrgencyNotification extends Notification
{
	/**
	 * 覆盖父类方法
	 * UrgencyNotification constructor.
	 * @param $msgSender
	 */
	public function __construct( $msgSender )
	{
		$this->msgSender = $msgSender;
	}

	public function notify( $message)
	{
		if(is_array($this->msgSender))
		{
			foreach ($this->msgSender as  $sender){
				$sender->send($message);
			}
		} else{
			$this->msgSender->send($message);
		}
	}
}
<?php
namespace App;


interface MsgSender
{
	public function send($message);
}
<?php
namespace App;


class EmailSender implements MsgSender
{
	private $email;

	public function __construct($email)
	{
		$this->email = $email;
	}

	public function send($message)
	{
		echo "Send $message to $this->email by email" . PHP_EOL;
	}
}
<?php

namespace App;


class TelephoneSender implements MsgSender
{
	private $telephone;

	public function __construct($telephone)
	{
		$this->telephone = $telephone;
	}

	public function send($message)
	{
		echo "Send $message  $this->telephone by telephone" . PHP_EOL;
	}
}
<?php

namespace App;


class WechatSender implements MsgSender
{
	private $wechatId;

	public function __construct($wechatId)
	{
		$this->wechatId = $wechatId;
	}

	public function send($message)
	{
		echo "Send $message by Wechat $this->wechatId" . PHP_EOL;
	}
}
<?php

require __DIR__.'/vendor/autoload.php';


$notification = new \App\SevereNotification(new \App\TelephoneSender('182xxxx0001'));
$notification->notify("Severe notification");

$notification = new \App\SevereNotification(new \App\EmailSender('alexwalt@xxx.com'));
$notification->notify("Severe notification");

$notification = new \App\NormalNotification(new \App\EmailSender('alexwalt@xxx.com'));
$notification->notify("Normal notification");

$notification = new \App\TrivialNotification(new \App\WechatSender('wechattoken'));
$notification->notify("Trivial notification");

$notification = new \App\UrgencyNotification(new \App\WechatSender('wechattoken'));
$notification->notify("Urgency notification");

$notification = new \App\UrgencyNotification(new \App\TelephoneSender('182xxxx0001'));
$notification->notify("Urgency notification");

$notification = new \App\UrgencyNotification(new \App\ShortMessageSender('182xxxx0001'));
$notification->notify("Urgency notification");

其他参考

[1]. 极客时间《设计模式》(王争)
[2].《研磨设计模式》(陈臣、王斌)
[3]. 《Learning PHP设计模式》
[4]. 从零使用composer初始化PSR-4项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值