From fe0152db45b1b5f4c95bf216776417ec465d78ff Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 30 Apr 2020 16:30:18 +0800 Subject: [PATCH] finish adapter pattern --- structure/02_adapter/README.md | 4 +- structure/02_adapter/adapter.go | 73 ++++++++++++++++++---------- structure/02_adapter/adapter_test.go | 26 ++++++---- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/structure/02_adapter/README.md b/structure/02_adapter/README.md index 967ef4f..00a7e8f 100644 --- a/structure/02_adapter/README.md +++ b/structure/02_adapter/README.md @@ -2,4 +2,6 @@ 适配器模式就是用来做适配的,实际应用过程中最容易遇到的就是,面对多种多样的设备和协议类型,做接入的时候,需要将设备的协议数据转换为系统内部能够识别的统一数据结构,对这就是适配器模式的一个实际场景,适配器用于转换一种形态到另一种形态,这种所谓的形态可能指数据结构、协议、计算方法、处理过程等 -在Adapter中匿名组合Adaptee接口,所以Adapter类也拥有SpecificRequest实例方法,又因为Go语言中非入侵式接口特征,其实Adapter也适配Adaptee接口。 +现实生活中的U形水管接头、插头转换器就是一个简单明了的适配器模式的例子,两针插头,是无法插入三孔插座的,所以三转二的电源插座/插头转换器,就是一个是适配器. + +代码中的适配器模式其实就是要实现一个,`三转二`的插头转换器,使两针插头可以正常充电. diff --git a/structure/02_adapter/adapter.go b/structure/02_adapter/adapter.go index a18aba2..940882f 100644 --- a/structure/02_adapter/adapter.go +++ b/structure/02_adapter/adapter.go @@ -1,41 +1,64 @@ package adapter -//Target 是适配的目标接口 -type Target interface { - Request() string +import "fmt" + +//IPlug 插头 +type IPlug interface { + GetPin() int } -//Adaptee 是被适配的目标接口 -type Adaptee interface { - SpecificRequest() string +//TwoPinPlugin 造一个两针的插头 +type TwoPinPlugin struct { } -//NewAdaptee 是被适配接口的工厂函数 -func NewAdaptee() Adaptee { - return &adapteeImpl{} +//GetPin 获取插头针数 +func (t *TwoPinPlugin) GetPin() int { + return 2 } -//AdapteeImpl 是被适配的目标类 -type adapteeImpl struct{} - -//SpecificRequest 是目标类的一个方法 -func (*adapteeImpl) SpecificRequest() string { - return "adaptee method" +//IPowerSocket 电源插座 +type IPowerSocket interface { + PlugCharging(p IPlug) } -//NewAdapter 是Adapter的工厂函数 -func NewAdapter(adaptee Adaptee) Target { - return &adapter{ - Adaptee: adaptee, +//IThreePinPowerSocket 三孔插座 +type IThreePinPowerSocket interface { + ThreePinCharging(p IPlug) +} + +//ThreePinPowerSocket 是被适配的目标类 +type ThreePinPowerSocket struct{} + +//ThreePinCharging 只能为三针的插头通电 +func (*ThreePinPowerSocket) ThreePinCharging(p IPlug) { + if p.GetPin() != 3 { + fmt.Println("i can not charge for this type") + return } + fmt.Println("charging for three pin plug") } -//Adapter 是转换Adaptee为Target接口的适配器 -type adapter struct { - Adaptee +//NewPowerAdapter 生产一个新的电源适配器 +func NewPowerAdapter(threePinPowerSocket IThreePinPowerSocket) IPowerSocket { + return &PowerAdapter{IThreePinPowerSocket(threePinPowerSocket), 0} } -//Request 实现Target接口 -func (a *adapter) Request() string { - return a.SpecificRequest() +//PowerAdapter 是能充电的关键电源转换器 +type PowerAdapter struct { + IThreePinPowerSocket + pin int +} + +//GetPin Adapter 的兼容能力 +func (p *PowerAdapter) GetPin() int { + return p.pin +} + +//PlugCharging 在PowerAdapter上进行实现 +func (p *PowerAdapter) PlugCharging(ip IPlug) { + if ip.GetPin() == 2 { + p.pin = 3 + p.ThreePinCharging(p) + } + } diff --git a/structure/02_adapter/adapter_test.go b/structure/02_adapter/adapter_test.go index 1b22ec2..fd5eccf 100644 --- a/structure/02_adapter/adapter_test.go +++ b/structure/02_adapter/adapter_test.go @@ -1,14 +1,22 @@ package adapter -import "testing" +import ( + "testing" +) -var expect = "adaptee method" +func TestPowerSocketAdapter(t *testing.T) { + + plug := &TwoPinPlugin{} + + threePinSocket := ThreePinPowerSocket{} + + //三孔插头是不能为两针插头充电的,可以试试看 + threePinSocket.ThreePinCharging(plug) + + //只好加一个电源适配器 + powersocket := NewPowerAdapter(&threePinSocket) + + //再试试能不能充电 + powersocket.PlugCharging(plug) -func TestAdapter(t *testing.T) { - adaptee := NewAdaptee() - target := NewAdapter(adaptee) - res := target.Request() - if res != expect { - t.Fatalf("expect: %s, actual: %s", expect, res) - } }