zoukankan      html  css  js  c++  java
  • 设计模式:适配器模式

    适配器模式(Adapter Pattern),别名Wrapper。

    适配器模式分为两种:对象适配器模式;类适配器模式。

    理解类图需要知道的一些基本名词和符号:UML类图的几个名词及对应符号

    对象适配器模式

    Client想要调用某个具体Adaptee的方法,来实现某个功能A。最直接的做法是将Adaptee作为参数传入,然后让Client创建一个方法去调用。
    如果Client也想调用另一个具体Adaptee的方法,也实现某个功能A。此时再将Adaptee作为参数传入,然后让Client创建一个方法去调用。
    ……
    当Client想调用一百个类(甚至不止这些)的方法,来实现同一个功能A,那不就得添加一百个方法?真这么做,这个类就太臃肿了。并且,在某个具体的系统,极大部分的方法都不会被用到。

    那么,提取出一个接口(Target),并让Client调用这个接口的方法不就行了吗?这样Client就不需要为某个具体的类添加方法。 问题就这样解决了,但还没结束。

    既然有一个接口,那么不就意味着每个具体Adaptee都要实现这个接口了么?最理想的情况是,这些类刚好那个被调用的方法的方法名是相同的,直接加个implements xxx就行了(前提是你被允许修改这些类的代码)。

    当然,现实并不是这么理想。它们的方法名往往不同,而你也不被允许修改它们的代码,更不用说去这些类里面去实现这些方法。

    那TM怎么办?

    先把已知条件整理出来:已知Client会调用Target接口的某个方法,但是具体类的方法名与接口的方法名不匹配,不能让具体类实现Target接口并传入Client。
    问:如何让Client只调用Target接口的方法而间接地调用到具体类的方法?

    答:创建一个类(MyAdapter),这个类里有一个方法,其方法名与Target定义的方法名完全一致(假设为sayHello())。接着将具体的类(假设为 RudeMan)传入这个新建的类,在 sayHello() 里面调用具体类的方法(假设为 sayFuck())。这就相当于给RudeMan的sayFuck()方法包装了另一个名字。
    既然MyAdapter的方法名与Target定义的一致,那么就可以加上implements xxx了。

    public class MyAdapter implements Target {
        private RudeMan rudeMan = null;
        
        public MyAdapter(RudeMan man) {
            rudeMan = man;
        }
        
        public void sayHello() {
            rudeMan.sayFuck();
        }
    }
    

    这时,MyAdapter类相当于是一个转接口,将具体类RudeMan的具体方法包装成另一个名字。并且MyAdapter实现了Target接口,可以传入Client供其调用。

    类适配器模式

    由于类适配器模式有时需要多重继承,而JAVA不支持,所以通常不使用类适配器模式。

    对于类适配器模式的方式,你会看到这样的形式:

    public class Adapter extends Adaptee implements Target {
    ……
    }
    

    这里extends是为了调用具体类Adaptee的方法,而implements是为了让Client调用已被Target定义好的方法。

    从UML类图角度来对比两者

    对象适配器模式:基本聚合
    类适配器模式:泛化

  • 相关阅读:
    POJ 1659 Frogs' Neighborhood
    zoj 2913 Bus Pass(BFS)
    ZOJ 1008 Gnome Tetravex(DFS)
    POJ 1562 Oil Deposits (DFS)
    zoj 2165 Red and Black (DFs)poj 1979
    hdu 3954 Level up
    sgu 249 Matrix
    hdu 4417 Super Mario
    SPOJ (BNUOJ) LCM Sum
    hdu 2665 Kth number 划分树
  • 原文地址:https://www.cnblogs.com/schaepher/p/6278538.html
Copyright © 2011-2022 走看看