手撸golang 结构型设计模式 适配器模式

手撸golang 结构型设计模式 适配器模式

缘起

最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之golang

适配器模式

适配器模式(Adapter Pattern)又叫做变压器模式,它的功能是将一个类的接口变成客户端所指望的另外一种接口,从而使本来因接口不匹配而致使没法在一块儿工做的两个类可以一块儿工做,属于结构型设计模式。
_设计模式

场景

  • 某智能家居应用, 可接入并显示温度计信息
  • 系统设计的温度计接口, 采用的是摄氏度单位
  • 现按客户需求, 要接入某进口款温度计, 厂家提供的sdk只提供华氏度的温度信息
  • 根据适配器模式, 在不修改系统原有接口的状况下, 兼容新设备接入
  • 华氏度 = 32+ 摄氏度 × 1.8, 摄氏度 = (华氏度 - 32) ÷ 1.8

设计

  • IThermometer: 现有系统的温度计接口, 温度单位为摄氏度. 本次更新但愿保持接口不变, 以避免影响现有系统.
  • IThermometerFactory: 现有系统的温度计工厂接口. 本次更新但愿保持接口不变, 以避免影响现有系统.
  • ISpecialThermometer: 厂家sdk提供的温度计接口, 温度单位为华氏度
  • tMockSpecialThermometer: 厂家sdk提供的温度计实现
  • tMockSpecialAdapter: 根据适配器模式, 实现的温度计适配器, 为新温度计适配现有系统的接口
  • tMockSpecialFactory: 新温度计的工厂类, 实现IThermometerFactory接口

单元测试

adapter_pattern_test.gooop

package structural_patterns

import (
    "learning/gooop/structural_patterns/adapter"
    "testing"
)

func Test_AdapterPattern(t *testing.T) {
    factory := adapter.SpecialThermometerFactory
    thermometer := factory.Create("This is some configuration")
    t.Logf("centigrade = %v", thermometer.Centigrade())
}

测试输出

$ go test -v adapter_pattern_test.go 
=== RUN   Test_AdapterPattern
    adapter_pattern_test.go:11: centigrade = 26.5
--- PASS: Test_AdapterPattern (0.00s)
PASS
ok      command-line-arguments  0.003s

IThermometer.go

现有系统的温度计接口, 温度单位为摄氏度.单元测试

package adapter

// 现有系统的温度计接口, 摄氏度
type IThermometer interface {
    Centigrade() float64
}

IThermometerFactory.go

现有系统的温度计工厂接口.测试

package adapter

type IThermometerFactory interface {
    Create(config string) IThermometer
}

ISpecialThermometer.go

厂家sdk提供的温度计接口, 温度单位为华氏度设计

package adapter

// 新接入的温度计, 华氏度
type ISpecialThermometer interface {
    Fahrenheit() float64
}

tMockSpecialThermometer.go

厂家sdk提供的温度计实现code

package adapter

type tMockSpecialThermometer struct {
    mAddress string
}

func newMockSpecialThermometer(address string) ISpecialThermometer {
    return &tMockSpecialThermometer{
        address,
    }
}

func (me *tMockSpecialThermometer) Fahrenheit() float64 {
    return 79.7
}

tMockSpecialAdapter.go

根据适配器模式, 实现的温度计适配器, 为新温度计适配现有系统的接口接口

package adapter

type tMockSpecialAdapter struct {
    mOrigin ISpecialThermometer
}


func newSpecialAdapter(origin ISpecialThermometer) IThermometer {
    return &tMockSpecialAdapter{
        origin,
    }
}

func (me *tMockSpecialAdapter) Centigrade() float64 {
    return (me.mOrigin.Fahrenheit() - 32) * 5 / 9
}

tMockSpecialFactory.go

新温度计的工厂类, 实现IThermometerFactory接口ci

package adapter

type tMockSpecialFactory struct {
}

func newMockSpecialFactory() IThermometerFactory {
    return &tMockSpecialFactory{}
}

func (me *tMockSpecialFactory) Create(config string) IThermometer {
    t := newMockSpecialThermometer(me.parseAddress(config))
    return newSpecialAdapter(t)
}

func (me *tMockSpecialFactory) parseAddress(config string) string {
    return "http://localhost:8080"
}


var SpecialThermometerFactory IThermometerFactory = newMockSpecialFactory()

适配器模式小结

适配器模式的优势
(1)能提升类的透明性和复用,但现有的类复用不须要改变。
(2)适配器类和原角色类解耦,提升程序的扩展性。
(3)在不少业务场景中符合开闭原则。
适配器模式的缺点
(1)适配器编写过程须要结合业务场景全面考虑,可能会增长系统的复杂性。
(2)增长代码阅读难度,下降代码可读性,过多使用适配器会使系统代码变得凌乱。
_
(end)string

相关文章
相关标签/搜索