finish bridge pattern

This commit is contained in:
Edward 2020-04-28 16:37:17 +08:00
parent 1cca759c5d
commit 2eea29f06e
3 changed files with 95 additions and 64 deletions

View File

@ -1,8 +1,21 @@
# 桥接模式
桥接模式分离抽象部分和实现部分。使得两部分独立扩展。
桥接模式类似于策略模式,原因在于他们都将行为交给了另一个接口实现,再组合实现完整功能/流程/业务.
桥接模式类似于策略模式,原因在于他们都将行为交给了另一个接口实现,再组合实现
区别在于策略模式封装一系列算法使得算法可以互相替换,关键点在于可以动态替换,但是桥接模式的特点是,一旦组合运行时一般不会发生变化.
区别在于策略模式封装一系列算法/方法/功能/使得他们可以互相替换,关键点在于策略模式的实现方法可以动态替换,但是桥接模式的特点是,一旦组合运行时一般不会发生变化.
桥接模式的变化点在于调用方是变化的.
在策略模式的例子中,银行就一个,但是储户类型是多个,银行需要为不同类型的用户服务,银行有同一个规则流程和处理方法,但是不同的用户对相同处理过程的响应和处理不一样。
在桥接模式中,消息类型是多个,转给不同的处理对象.
演示1个例子场景如下
对于Web应用系统当平台后端收到消息并需要推送的时候常见有四种选择
1、通过第三方的的Internet通道离线推送到手机通知用户
2、通过邮件通知到用户
3、通过在线的长连接进行websocket推送
4、通过手机4G/5G的短信通道通知到用户
选择其中的二三两类进行演示

View File

@ -2,58 +2,78 @@ package bridge
import "fmt"
type AbstractMessage interface {
SendMessage(text, to string)
//IMessage 发送消息接口
type IMessage interface {
NoticeUser(text string)
Priority() int
}
type MessageImplementer interface {
Send(text, to string)
//ISMSMessage send SMS MSG
type ISMSMessage interface {
//延迟接口的实现到其他类中
NoticeUser(text string, noticeMessage IMessage)
}
type MessageSMS struct{}
func ViaSMS() MessageImplementer {
return &MessageSMS{}
//WSMessage MSG
type WSMessage struct {
Handler ISMSMessage //持有进一步实现的引用关系
Level int
}
func (*MessageSMS) Send(text, to string) {
fmt.Printf("send %s to %s via SMS", text, to)
}
type MessageEmail struct{}
func ViaEmail() MessageImplementer {
return &MessageEmail{}
}
func (*MessageEmail) Send(text, to string) {
fmt.Printf("send %s to %s via Email", text, to)
}
type CommonMessage struct {
method MessageImplementer
}
func NewCommonMessage(method MessageImplementer) *CommonMessage {
return &CommonMessage{
method: method,
//NoticeUser by SMS
func (w *WSMessage) NoticeUser(text string) {
//转递消息给其他对象,相当于承上启下
fmt.Println("Websocket Notice User...", text)
//转递消息给其他对象,相当于承上启下,并且需要把上下文变量传递下去
if w.Handler != nil {
w.Handler.NoticeUser(text, w)
}
}
func (m *CommonMessage) SendMessage(text, to string) {
m.method.Send(text, to)
//Priority of SMS
func (w *WSMessage) Priority() int {
return w.Level
}
type UrgencyMessage struct {
method MessageImplementer
//EmailMessage MSG
type EmailMessage struct {
Handler ISMSMessage
Level int
}
func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage {
return &UrgencyMessage{
method: method,
//NoticeUser by SMS
func (e *EmailMessage) NoticeUser(text string) {
//转递消息给其他对象,相当于承上启下,并且需要把上下文变量传递下去
fmt.Println("Email Notice User...", text)
if e.Handler != nil {
e.Handler.NoticeUser(text, e)
}
}
func (m *UrgencyMessage) SendMessage(text, to string) {
m.method.Send(fmt.Sprintf("[Urgency] %s", text), to)
//Priority of SMS
func (e *EmailMessage) Priority() int {
return e.Level
}
///需要实现具体的消息发送行为
//EmergencyWSMessage 紧急的短信消息
type EmergencyWSMessage struct {
}
//NoticeUser by email
func (e *EmergencyWSMessage) NoticeUser(text string, noticeMessage IMessage) {
fmt.Println("Notice User", text, " By Websocket:", "with Level: ", noticeMessage.Priority())
}
//EmergencyEmailMessage 紧急的短信消息
type EmergencyEmailMessage struct {
}
//NoticeUser by email
func (e *EmergencyEmailMessage) NoticeUser(text string, noticeMessage IMessage) {
fmt.Println("Notice User:", text, " By Email:", "with Level: ", noticeMessage.Priority())
}

View File

@ -1,29 +1,27 @@
package bridge
func ExampleCommonSMS() {
m := NewCommonMessage(ViaSMS())
m.SendMessage("have a drink?", "bob")
// Output:
// send have a drink? to bob via SMS
}
import "testing"
func ExampleCommonEmail() {
m := NewCommonMessage(ViaEmail())
m.SendMessage("have a drink?", "bob")
// Output:
// send have a drink? to bob via Email
}
func TestSendMessage(t *testing.T) {
func ExampleUrgencySMS() {
m := NewUrgencyMessage(ViaSMS())
m.SendMessage("have a drink?", "bob")
// Output:
// send [Urgency] have a drink? to bob via SMS
}
//注意看这里,接口的实例关系在初始化时候是固定的
ws := &WSMessage{&EmergencyWSMessage{}, 100}
func ExampleUrgencyEmail() {
m := NewUrgencyMessage(ViaEmail())
m.SendMessage("have a drink?", "bob")
// Output:
// send [Urgency] have a drink? to bob via Email
//注意看这里,接口的实例关系在初始化时候是固定的
email := &EmailMessage{&EmergencyEmailMessage{}, 10}
ws.NoticeUser("Miss White ,Let's Drink")
email.NoticeUser("Miss White,Fire!,Fire!")
ews := &EmergencyWSMessage{}
eem := &EmergencyEmailMessage{}
list := []IMessage{
&WSMessage{ews, 50},
&WSMessage{ews, 100},
&EmailMessage{eem, 10},
&EmailMessage{eem, 20},
}
for _, v := range list {
v.NoticeUser("Lets go for fun")
}
}