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" import "fmt"
type AbstractMessage interface { //IMessage 发送消息接口
SendMessage(text, to string) type IMessage interface {
NoticeUser(text string)
Priority() int
} }
type MessageImplementer interface { //ISMSMessage send SMS MSG
Send(text, to string) type ISMSMessage interface {
//延迟接口的实现到其他类中
NoticeUser(text string, noticeMessage IMessage)
} }
type MessageSMS struct{} //WSMessage MSG
type WSMessage struct {
func ViaSMS() MessageImplementer { Handler ISMSMessage //持有进一步实现的引用关系
return &MessageSMS{} Level int
} }
func (*MessageSMS) Send(text, to string) { //NoticeUser by SMS
fmt.Printf("send %s to %s via SMS", text, to) func (w *WSMessage) NoticeUser(text string) {
} //转递消息给其他对象,相当于承上启下
fmt.Println("Websocket Notice User...", text)
type MessageEmail struct{} //转递消息给其他对象,相当于承上启下,并且需要把上下文变量传递下去
if w.Handler != nil {
func ViaEmail() MessageImplementer { w.Handler.NoticeUser(text, w)
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,
} }
} }
func (m *CommonMessage) SendMessage(text, to string) { //Priority of SMS
m.method.Send(text, to) func (w *WSMessage) Priority() int {
return w.Level
} }
type UrgencyMessage struct { //EmailMessage MSG
method MessageImplementer type EmailMessage struct {
Handler ISMSMessage
Level int
} }
func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage { //NoticeUser by SMS
return &UrgencyMessage{ func (e *EmailMessage) NoticeUser(text string) {
method: method, //转递消息给其他对象,相当于承上启下,并且需要把上下文变量传递下去
fmt.Println("Email Notice User...", text)
if e.Handler != nil {
e.Handler.NoticeUser(text, e)
} }
} }
func (m *UrgencyMessage) SendMessage(text, to string) { //Priority of SMS
m.method.Send(fmt.Sprintf("[Urgency] %s", text), to) 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 package bridge
func ExampleCommonSMS() { import "testing"
m := NewCommonMessage(ViaSMS())
m.SendMessage("have a drink?", "bob")
// Output:
// send have a drink? to bob via SMS
}
func ExampleCommonEmail() { func TestSendMessage(t *testing.T) {
m := NewCommonMessage(ViaEmail())
m.SendMessage("have a drink?", "bob")
// Output:
// send have a drink? to bob via Email
}
func ExampleUrgencySMS() { //注意看这里,接口的实例关系在初始化时候是固定的
m := NewUrgencyMessage(ViaSMS()) ws := &WSMessage{&EmergencyWSMessage{}, 100}
m.SendMessage("have a drink?", "bob")
// Output:
// send [Urgency] have a drink? to bob via SMS
}
func ExampleUrgencyEmail() { //注意看这里,接口的实例关系在初始化时候是固定的
m := NewUrgencyMessage(ViaEmail()) email := &EmailMessage{&EmergencyEmailMessage{}, 10}
m.SendMessage("have a drink?", "bob")
// Output: ws.NoticeUser("Miss White ,Let's Drink")
// send [Urgency] have a drink? to bob via Email 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")
}
} }