设计模式之桥接模式

设计模式之桥接模式

概述

桥接模式 是一种结构型设计模式,系统中加入某个类存在两种独立变化的维度,可以通过该模式将这两个维度分离出来

桥接模式: 将抽象部分与其实现部分分离,使他们都可以独立变化,是一种对象结构型模式,又称为柄体模式或接口模式

桥接模式包含了4个角色:

  1. Abstraction(抽象类):用于定义抽象类的接口,既可以包含抽象业务方法,也可以包含具体业务方法
  2. RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,实现了Abstraction中声明的业务方法,并且可以调用在Implementor中定义的业务方法。
  3. Implementor(实现类接口):定义实现类的接口,它提供仅仅是一些基本操作,而Abstraction定义的接口会包含更多,更复杂的操作,在Abstraction中不仅可以拥有自己的方法,还可以调用Implementor中定义的方法
  4. ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的实现类中提供基本操作不同的实现

在使用桥接模式的时候需要识别出类具有两种独立变化的维度

数字和花色组合扑克牌

我们都知道扑克牌都有花色和数字,不同的花色和不同的数字可以用来表示不同的牌。所以我们这里使用扑克牌来举例,因为花色和数字正好是两个独立的维度

package bridge

import "fmt"

// AbstractionPoker 抽象类接口
type AbstractionPoker interface {
   Combination() // 组合
}

// PokerImplementor  实现类接口
type PokerImplementor interface {
   SetColor(string)
   SetNum()
}

// NumberOne 具体实现类
type NumberOne struct {
}

func NewNumberOne() PokerImplementor {
   return &NumberOne{}
}

func (n *NumberOne) SetNum() {
   fmt.Println("poker number is one")
}

func (n *NumberOne) SetColor(color string) {
   fmt.Printf("pocker color is %s\n", color)
}

type NumberTwo struct {
}

func NewNumberTwo() PokerImplementor{
   return &NumberTwo{}
}

func (n *NumberTwo) SetNum() {
   fmt.Println("poker number is two")
}

func (n *NumberTwo) SetColor(color string) {
   fmt.Printf("pocker color is %s\n", color)
}

// ClubPoker 梅花扑克 拓展实现类
type ClubPoker struct {
   pokerImplementor PokerImplementor
}

func NewClubPoker(impl PokerImplementor) *ClubPoker {
   return &ClubPoker{
      pokerImplementor: impl,
   }
}

func (c *ClubPoker) Combination() {
   c.pokerImplementor.SetColor("Club")
   c.pokerImplementor.SetNum()

}

// HeartsPoker 拓展实现类
type HeartsPoker struct {
   pokerImplementor PokerImplementor
}

func (h *HeartsPoker)Combination()  {
   h.pokerImplementor.SetColor("Heart")
   h.pokerImplementor.SetNum()
}

func NewHeartPoker(impl PokerImplementor) *HeartsPoker {
   return &HeartsPoker{
      pokerImplementor: impl,
   }
}

首先我们要明确,拓展实现类,实现的事Abstraction中的方法,而具体实现类实现的是Implementor中的方法,Implementor中定义了一些基础的方法,Abstraction中定义了复杂的方法。

// PokerImplementor  实现类接口
type PokerImplementor interface {
   SetColor(string)
   SetNum()
}

这里定义了PockerImplemetor实现类接口,定义了两个基础的方法,设置颜色和设置数字

// AbstractionPoker 抽象类
type AbstractionPoker interface {
   Combination() // 组合
}

抽象类接口,这里定义了组合的方法作为复杂方法接口,接着我定义了两个扩充的结构体,用来实现Abstraction中的方法,并且在实现的过程中调用了Implementor的方法

// ClubPoker 梅花扑克
type ClubPoker struct {
   pokerImplementor PokerImplementor
}

func NewClubPoker(impl PokerImplementor) *ClubPoker {
   return &ClubPoker{
      pokerImplementor: impl,
   }
}

func (c *ClubPoker) Combination() {
   c.pokerImplementor.SetColor("Club")
   c.pokerImplementor.SetNum()

}

// HeartsPoker 红心扑克
type HeartsPoker struct {
   pokerImplementor PokerImplementor
}

func (h *HeartsPoker)Combination()  {
   h.pokerImplementor.SetColor("Heart")
   h.pokerImplementor.SetNum()
}

func NewHeartPoker(impl PokerImplementor) *HeartsPoker {
   return &HeartsPoker{
      pokerImplementor: impl,
   }
}

同时也定义两个具体实现类去实现Implementor的方法

// NumberOne 拓展实现类
type NumberOne struct {
}

func NewNumberOne() PokerImplementor {
   return &NumberOne{}
}

func (n *NumberOne) SetNum() {
   fmt.Println("poker number is one")
}

func (n *NumberOne) SetColor(color string) {
   fmt.Printf("pocker color is %s\n", color)
}

type NumberTwo struct {
}

func NewNumberTwo() PokerImplementor{
   return &NumberTwo{}
}

func (n *NumberTwo) SetNum() {
   fmt.Println("poker number is two")
}

func (n *NumberTwo) SetColor(color string) {
   fmt.Printf("pocker color is %s\n", color)
}

这样的设置就满足了桥接模式的所有角色设定

测试

package bridge

import (
   "fmt"
   "testing"
)

func TestClubPoker_Combination(t *testing.T) {
   clubPokerOne := NewClubPoker(NewNumberOne())
   clubPokerOne.Combination()

   fmt.Println()

   heartPokerTwo := NewHeartPoker(NewNumberTwo())
   heartPokerTwo.Combination()
}

// 
// === RUN   TestClubPoker_Combination
// pocker color is Club
// poker number is one
// 
// pocker color is Heart
// poker number is two
// --- PASS: TestClubPoker_Combination (0.00s)
// PASS

总结

优点
  • 提高了系统的可拓展型,两个维度任意增加一种维度,都不需要修改原有的系统,符合开闭原则
缺点
  • 复杂,比较难,比较难去抽象,同时叶需要精准识别出两个独立变化的维度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值