设计模式-Bridge(桥接模式)GO语言版本

前言

Bridge模式核心在于将抽象部分与实现部分分离,使他们都可以独立变化。简单来说就是向一座桥一样,左边和有边都有可能变化,但是他们之间通过一座桥相连接(有些抽象下面还是从实际情况出发)。

问题

在一个电商平台里,有不同类型的商品(比如电子产品、服装、图书等)需要展示商品详情信息给用户,同时用户购买商品时可以选择不同的支付方式(如微信支付、支付宝支付、银行卡支付等)。我们希望能够灵活地添加新的商品类型或者新的支付方式,而不影响现有的代码结构,这时候桥接模式就能派上用场了。

解决方案

首先定义抽象化部分(商品展示抽象接口)

// GoodsDisplay 商品展示抽象接口,定义了展示商品详情的方法
type GoodsDisplay interface {
    ShowDetails() string
}

这个接口规定了商品需要实现展示详情的功能,具体怎么展示由不同类型的商品去实现。

接着定义实现化部分(支付方式接口)

// PaymentMethod 支付方式接口,定义了执行支付的抽象方法
type PaymentMethod interface {
    Pay(amount float64) bool
}

该接口抽象出了支付操作,不管是哪种具体的支付手段,都需要实现这个支付的基本逻辑,即传入支付金额,然后返回支付是否成功的结果。

然后是具体实现化部分(具体支付方式的实现)

// WeChatPayment 微信支付结构体,实现了PaymentMethod接口
type WeChatPayment struct{}

func (w WeChatPayment) Pay(amount float64) bool {
    // 这里模拟微信支付的逻辑,实际中会调用微信支付的相关API
    println("使用微信支付,金额:", amount)
    return true
}

// AlipayPayment 支付宝支付结构体,实现了PaymentMethod接口
type AlipayPayment struct{}

func (a AlipayPayment) Pay(amount float64) bool {
    // 模拟支付宝支付逻辑,实际会涉及支付宝接口调用等
    println("使用支付宝支付,金额:", amount)
    return true
}

// BankCardPayment 银行卡支付结构体,实现了PaymentMethod接口
type BankCardPayment struct{}

func (b BankCardPayment) Pay(amount float64) bool {
    // 模拟银行卡支付的一些验证、支付操作等
    println("使用银行卡支付,金额:", amount)
    return true
}

以上分别实现了微信支付、支付宝支付和银行卡支付三种具体的支付方式,它们都遵循 PaymentMethod 接口定义的 Pay 方法规范,完成各自的支付逻辑模拟(实际应用中会对接相应支付平台的真实接口)。

再来看具体抽象化部分(具体商品类型的实现)

// ElectronicGoods 电子产品结构体,实现了GoodsDisplay接口,内部组合了PaymentMethod
type ElectronicGoods struct {
    payment PaymentMethod
}

func NewElectronicGoods(payment PaymentMethod) *ElectronicGoods {
    return &ElectronicGoods{
        payment: payment,
    }
}

func (e *ElectronicGoods) ShowDetails() string {
    return "这是一款电子产品,详情略,支持以下支付方式:"
}

func (e *ElectronicGoods) Buy(amount float64) bool {
    return e.payment.Pay(amount)
}

// ClothingGoods 服装商品结构体,实现了GoodsDisplay接口,内部同样组合了PaymentMethod
type ClothingGoods struct {
    payment PaymentMethod
}

func NewClothingGoods(payment PaymentMethod) *ClothingGoods {
    return &ClothingGoods{
        payment: payment,
    }
}

func (c *ClothingGoods) ShowDetails() string {
    return "这是一款服装商品,详情略,支持以下支付方式:"
}

func (c *ClothingGoods) Buy(amount float64) bool {
    return c.payment.Pay(amount)
}

// BookGoods 图书商品结构体,实现了GoodsDisplay接口,内部组合了PaymentMethod
type BookGoods struct {
    payment PaymentMethod
}

func NewBookGoods(payment PaymentMethod) *BookGoods {
    return &BookGoods{
        payment: payment,
    }
}

func (b *BookGoods) ShowDetails() string {
    return "这是一本图书商品,详情略,支持以下支付方式:"
}

func (b *BookGoods) Buy(amount float64) bool {
    return b.payment.Pay(amount)
}

这里以电子产品、服装、图书三种商品类型为例,它们都实现了 GoodsDisplay 接口用于展示商品详情,并且内部都组合了 PaymentMethod 类型的对象,意味着它们可以使用不同的支付方式来完成购买操作(通过调用对应的 Pay 方法)。

最后进行测试使用

func TestBridge(t *testing.T) {
	// 创建微信支付实例
	wechat := WeChatPayment{}
	// 创建电子产品实例,并关联微信支付方式
	electronic := NewElectronicGoods(wechat)
	println(electronic.ShowDetails())
	electronic.Buy(1000.0)

	// 创建支付宝支付实例
	alipay := AlipayPayment{}
	// 创建服装商品实例,并关联支付宝支付方式
	clothing := NewClothingGoods(alipay)
	println(clothing.ShowDetails())
	clothing.Buy(200.0)

	// 创建银行卡支付实例
	bankCard := BankCardPayment{}
	// 创建图书商品实例,并关联银行卡支付方式
	book := NewBookGoods(bankCard)
	println(book.ShowDetails())
	book.Buy(50.0)
}

 本来呢桥接模式就像下面这样,中间像个桥,是GoodDisplay这个抽象体包含PaymentMethod抽象类的,这样才像一个桥一样。

但是go语言挺特殊,一般不是像上面那样设计,而是像下面这样,继承的子结构体包含PaymentMethod, GoodsDisplay则是定义成接口形式

优缺点

优点:

  •  你可以创建与平台无关的类和程序。
  •  客户端代码仅与高层抽象部分进行互动, 不会接触到平台的详细信息。
  •  开闭原则。 你可以新增抽象部分和实现部分, 且它们之间不会相互影响。
  •  单一职责原则。 抽象部分专注于处理高层逻辑, 实现部分处理平台细节。

缺点:

  •  对高内聚的类使用该模式可能会让代码更加复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DyingLive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值