桥接模式是一种结构型设计模式,可以将一个大类或者一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用
问题模型
假如现在有一个 Dog
类,而你在这个类的基础上扩展出了Poodle Dog
和Teddy Dog
这两种类型的Dog
,之后又希望在添加新的类Size
来区分不同大小的 Dog
,那么此时你就需要添加新的类SmallPoodleDog,BigPoodleDog,SmallTeddyDog
和BigTeddyDog
当然,如果此时有需要一个Color
类来区分Dog
的颜色,那么这时候就要再进行扩展了,就会出现RedSamllPoodleDog
这样的类;这时每增加一种维度的变化就需要增加很多的类,同样每增加一种品种的 Dog
,也需要添加很多的类
但是,如果此时直接将这些Small
类,Red
类组合到PoodleDog
中的话,又会增加代码的耦合性,每次Red
类的变化都会引起PoodleDog
的更改;
那如何才能解决这个问题呢?这就需要用到桥接模式
解决方案
桥接模式就是明确识别系统中的独立变化的几个维度,拆分抽象和实现这两个独立的层次结构,降低程序中类的耦合度
也就是说,不能直接让PooleDog
组合Red
类,中间需要一个桥梁,而这个桥梁就是Red,Blue
等同一维度的抽象表示,然后在这个PooleDog
中组合这个抽象类,这样就将PooleDog
和Red
类分离开来了,PooleDog
类的变化不会影响Red
类,同样的Red
的变化也不会影响PooleDog
类
这就是设计模式中的依赖倒置原则:要针对接口进行编程,而不是针对实现进行编程;并且能够增加程序的扩展性,降低了程序之间的耦合性
UML类图
示例代码:
package main
import "fmt"
func main() {
b := &BlueColor{}
m := &Medium{}
c := &Dog{
c: b,
s: m,
}
c.WithMediumBlue()
}
type Dog struct {
c color
s Size
}
func (c *Dog) WithMediumBlue() {
c.c.SetColor()
c.s.SetSize()
}
type color interface {
SetColor()
}
type BlueColor struct {}
func (b *BlueColor) SetColor() {
fmt.Println("color blue")
}
type Size interface {
SetSize()
}
type Medium struct {}
func (m *Medium) SetSize() {
fmt.Println("medium size")
使用场景
当一个类的内部有两种或者多种不同维度的变化时,使用桥接模式可以解耦这些变化的维度,减少程序的耦合性,使代码结构更加的稳定
优点
- 降低代码的耦合性
- 减少了不同维度造成的类的数量的增加
- 可以很好的对程序进行扩展
缺点
- 增加了代码的复杂度