20

Go设计模式:桥接模式

 3 years ago
source link: https://jiajunhuang.com/articles/2020_06_21-go_design_pattern_bridge.md.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

桥接模式在日常编码中还是经常用到的,这也是我比较喜欢的一个设计模式。从定义上来说,桥接模式比较晦涩难懂:

“桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。”。

它的重要特征是,将一个实例(具体实现A)传入到另外一个类(类B),供初始化,当类B的实例B1调用某些方法时,实际上调用的是 具体实现A的某些方法,听起来就很绕对不对,我们来看一个简单地例子(Python):

class EatApple:
    def eat(self):
        print("eating apple...")


class Eat:
    def __init__(self, sth):
        self.__sth = sth

    def eat(self):
        self.__sth.eat()


if __name__ == "__main__":
    Eat(EatApple()).eat()

看这个例子,这里就使用了桥接模式,分别是用Eat和EatApple,Eat抽象了吃这个动作,但是具体怎么吃,吃什么是由EatApple来实现 的,而要使用Eat类,你必须在初始化的时候传入一个EatApple,这样就把动作和实现分离了,这就是桥接模式。那为啥说在Go语言里, 经常可以看到桥接模式的身影呢?你是不是经常看到类似的代码?

package main

import (
	"fmt"
)

type Set struct {
	impl map[string]bool
}

func NewSet() *Set {
	return &Set{make(map[string]bool)}
}

func (s *Set) Add(key string) {
	s.impl[key] = true
}

func (s *Set) Iter(f func(key string)) {
	for key := range s.impl {
		f(key)
	}
}

func main() {
	s := NewSet()
	s.Add("hello")
	s.Add("world")
	s.Iter(func(key string) {
		fmt.Printf("key: %s\n", key)
	})
}

我们在Set这个结构体里,封装了其他底层实现,Set规定了它所提供的方法,但是底层具体的实现,确是由 map[string]bool 真正 提供的,但是Set的使用者并不知道这个事实,因此对调用者而言,Set实现提供了功能,但是没有暴露底层实现。

将功能和实现隔离开来,有什么好处呢?好处就在于解耦,如果我们想要把Set改成并发版本的,那么我们将代码改为如下即可:

package main

import (
	"fmt"
	"sync"
)

type Set struct {
	impl sync.Map
}

func NewSet() *Set {
	return &Set{sync.Map{}}
}

func (s *Set) Add(key string) {
	s.impl.Store(key, true)
}

func (s *Set) Iter(f func(key string)) {
	s.impl.Range(func(key, value interface{}) bool {
		f(key.(string))
		return true
	})
}

func main() {
	s := NewSet()
	s.Add("hello")
	s.Add("world")
	s.Iter(func(key string) {
		fmt.Printf("key: %s\n", key)
	})
}

瞧,我们更改了底层实现,但是 main 函数作为调用者,却不需要更改任何一行代码。这就是桥接模式的威力!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK