[设计模式](五):适配器模式(Adapter)[类适配器、对象适配器、接口适配器]

>什么是适配器模式?

    适配器模式是一种结构性模式,其用处是用来衔接、扩展、适配旧的接口和新的接口,本身也隐含了委托/代理模式的思想。适配器模式本身包含三种:类适配器、对象适配器、接口适配器。本文着重介绍最常用的对象适配器模式。

>适配器模式样例

    观察下面的样例代码:(对象适配器模式,最常用的适配器模式)

注意!本篇讲的是Plugin式的对象适配器,用于在系统中无法引入新类的开发场景。

传统意义上的适配器应该是Wrapper式的,即适配器类实现新类的接口、持有旧类的实例作为强依赖,非常类似于装饰类。

//旧的Mod接口及其实现类
interface OldModInterface{
    fun fire()
}
class OldMod:OldModInterface{
    override fun fire() {
        println(".330mm")
    }
}
//只适配了旧的接口的枪
class Gun{
    lateinit var gunFireMod:OldModInterface
    fun setFireMod(mod:OldModInterface){只适配了旧的接口
        gunFireMod = mod
    }
    fun fire(){
        gunFireMod.fire()
    }
}
//新的Mod接口及其实现类
interface NewModInterface{
    fun fire()
}
class NewMod:NewModInterface{
    override fun fire() {
        println(".340mm")
    }
}
//通过适配器把新的Mod适配到旧的Mod接口上
class ModAdapter:OldModInterface{//继承旧的接口(向上转型)
    lateinit var mod:NewModInterface//对象适配
    fun setAdapter(newMod:NewModInterface){//接受一个新的Mod对象,也可以写在构造函数里
        mod=newMod
    }
    override fun fire() {//重写旧接口中的方法
        mod.fire()//把新的Mod的开火方法,替代旧接口中的开火方法。这里实际上隐藏了委托模式的思想
    }
}

     这又不得不提到我们的老朋友OCP(开闭原则)了。我对Gun的功能做扩展和修改,让他使用新接口的方法。观察到我写了一个适配器类,在保留旧接口及Gun类源代码不动的基础上,通过扩展实现了Gun使用新Mod的需求:

 

fun main(args:Array<String>){
    val g = Gun()
    g.setFireMod(OldMod())
    g.fire() // 射出.330mm子弹

    val newModWithAdapter = ModAdapter()
    newModWithAdapter.setAdapter(NewMod())
    g.setFireMod(newModWithAdapter)
    g.fire() // 射出.340mm子弹
}

     为了更便于阅读,可以看下面这个类图(对象适配器模式):

 

>如何构造对象适配器

     构造对象适配器的要点是:

 

  • 实现旧接口;
  • 重写旧接口的方法,需要被新接口替代的方法,用新接口的对象的相关方法实现;(即委托)
  • 适配器接受一个新接口的对象。

>其他适配器模式:类适配器模式、接口适配器模式

 

    这两种适配器模式比较简单,分别介绍一下:

 

>类适配器模式:

 

 

  • 适配器类实现[旧的接口]并继承[新的接口实现类];
  • 在适配器中,桥接、重写旧接口的适配器方法。

     示例代码:

class OldModInterface{
     fun fire()
}
open class NewMod:NewModInterface{
     override fun newFire(){...}
}
class Adapter:NewMod(),OldModInterface{
     override fun fire(){
           super.newFire()
     }
}

     UML图:

 

     类适配器显然没有对象适配器灵活,但胜在代码简短,在一些简单的接口适配和扩展中要更好用一点。

>接口适配器

     接口适配器与上面的适配器模式都不太一样,其目的是用来优化一个过大的接口的,其符合接口隔离原则。

     示例代码:

 

//一个过于臃肿的接口
interface BigInterface{
    fun a1()
    fun a2()
    fun a3()
    fun a4()
}
//一个抽象类实现了接口的所有方法
abstract class Adapter:BigInterface{
    override fun a1(){}
    override fun a2(){}
    override fun a3(){}
    override fun a4(){}
}
//具体的实现类并不需要重写所有接口中的方法
class Mod12:Adapter(){
    override fun a1(){
        println("a1")
    }
    override fun a2(){
        println("a2")
    }
}
class Mod34:Adapter(){
    override fun a3(){
        println("a3")
    }
    override fun a4(){
        println("a4")
    }
}

    使用时,只需要:

 

 

val d:Adapter = Mod12()
d.a1()//只需要用这个接口的a1和a2方法

    UML图:

 

    接口适配器最常见的就是JAVA GUI中监听器的事件适配器了,例如MouseAdapter类。

>>[设计模式]OOP设计模式·目录

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值