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

来源:互联网 发布:易我数据恢复好用吗 编辑:程序博客网 时间:2024/05/16 13:58

>什么是适配器模式?

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

>适配器模式样例

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

//旧的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 0
原创粉丝点击