【Go-设计模式】适配器模式 详解

shadowLogo

概念:

  1. 适配器模式(Adapter Pattern),又称 包装器(Wrapper)
    某个类的接口 转换成 用户期望的另一个接口表示
    主的目的是 兼容性,让 原本因接口不匹配 不能一起工作的两个类可以 协同工作
  2. 适配器模式属于 结构型模式
  3. 主要分为三类:

类适配器模式
对象适配器模式
接口适配器模式

adapter


类适配器:

概念:

对 被传入的类 进行封装操作,转换为适配当前系统的实现


示例:

被适配的类:

type AdaptedClass struct {
}

func (this AdaptedClass) OutPut404() int64 {
	return 404
}

转换后的接口:

type InterfaceOutput301 interface {
	OutPut301() int64
}

适配器类:

type Adapter struct {
	AdaptedClass
}

func (this Adapter) OutPut301() int64 {
	if this.OutPut404() == 404 {
		return 301
	}
	return this.OutPut404()
}

测试:

package main

import (
	"DemoProject/design/base23"
	"fmt"
)

func output301(executor base23.InterfaceOutput301) int64 {
	return executor.OutPut301()
}

func main() {
	// adapter-class
	adapter := base23.Adapter{}
	fmt.Println(output301(adapter))
}

对象适配器:

概念:

基本思路和 类适配器模式 相同,只是将 Adapter 类作修改
不是继承 src 类,而是持有 src 类的实例,以解决兼容性的问题。
即:持有 src 类,实现 dst 类接口,完成 src->dst 的适配


示例:

被适配的对象:

type AdaptedClass struct {
}

func (this AdaptedClass) OutPut404() int64 {
	return 404
}

inputSourece := base23.AdaptedClass{}

转换后的接口:

type InterfaceOutput200 interface {
	OutPut200() int64
}

适配器类:

type Adapter struct {
	InputSource AdaptedClass
}

func (this Adapter) OutPut200() int64 {
	if this.InputSource.OutPut404() == 404 {
		return 200
	}
	return this.InputSource.OutPut404()
}

测试:

package main

import (
	"DemoProject/design/base23"	// 根据自己的项目路径定制
	"fmt"
)

func output200(executor base23.InterfaceOutput200) int64 {
	return executor.OutPut200()
}

func main() {
	// adapter-obj
	inputSourece := base23.AdaptedClass{}
	adapter := base23.Adapter{
		InputSource: inputSourece,
	}

	fmt.Println(output200(adapter))
}


接口适配器:

概念:

不需要全部实现接口提供的方法 时,可先设计一个 抽象类实现接口,并为该接口中 每个方法 提供一个 默认实现(空方法),那么 该抽象类的子类有选择地覆盖父类的某些方法 来实现需求
适用于一个接口 不想 使用其所有的方法 的情况


示例:

被适配的接口:

type HttpResponseCode interface {
	OutPut200() int64
	OutPut301() int64
	OutPut404() int64
	OutPut500() int64
}

适配器类:

type Adapter struct {
}

func (this Adapter) OutPut200() int64 {
	return 0
}

func (this Adapter) OutPut301() int64 {
	return 0
}

func (this Adapter) OutPut404() int64 {
	return 0
}

func (this Adapter) OutPut500() int64 {
	return 0
}

测试:

package main

import (
	"DemoProject/design/base23"	// 根据自己的项目路径定制
	"fmt"
)

type SystemErrorCode struct {
	base23.Adapter
}

func (this SystemErrorCode) OutPut500() int64 {
	return 500
}

func httpResponse(code base23.HttpResponseCode) int64 {
	return code.OutPut500()
}

func main() {
	// adapter-interface
	httpResponseCode := SystemErrorCode{}
	fmt.Println(httpResponse(httpResponseCode))
}

注意事项:

三种命名方式,是根据 src 是以怎样的形式给到 Adapter(在 Adapter 里的形式)来命名的。

  • 类适配器
    以类给到,在 Adapter 里,就是将 src 当做类,继承
  • 对象适配器
    以对象给到,在 Adapter 里,将 src 作为一个对象,持有接口适配器:
  • 接口适配器
    以接口给到,在Adapter 里,将 src 作为一个接口实现

Adapter 模式最大的作用还是将 原本不兼容的接口 融合在一起工作
实际开发中,实现起来不拘泥于我们讲解的三种经典形式

posted @ 2021-12-12 22:47  在下右转,有何贵干  阅读(163)  评论(0)    收藏  举报