• 设计模式之适配器模式(换个包装再度利用)


    适配器模式(Adapter Pattern)有时候也称包装样式或者包装。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中。

    Adapter Pattern有两种

    1. 类的Adapter Pattern(继承)
    2. 对象的Adapter Pattern(委托)

    它们的类图分别为:

    类适配器模式类图

     

     

    对象适配器模式类图

    就是将上图的Target接口改成抽象类,并被Adapter继承。

    下面我们用第一种来实现适配器模式:

    我们首先来看看类图:

    具体实现如下:

    Banner类:

    public class Banner {
        private String string;
    
        public Banner(String string) {
            this.string = string;
        }
    
        public void showWithParen() {
            System.out.println("(" + string + ")");
        }
    
        public void showWithAster() {
            System.out.println("*" + string + "*");
        }
    
    }
    View Code

    Print接口类:

    public interface Print {
        public abstract void printWeak();
    
        public abstract void printStrong();
    
    }

    PrintBanner类:(发挥适配器的功能,先继承Banner在实现Print接口,然后继承其Banner的两个方法并实现Print接口的两个方法)

    public class PrintBanner extends Banner implements Print {
    
        public PrintBanner(String string) {
            super(string);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void printWeak() {
            showWithParen();
    
        }
    
        @Override
        public void printStrong() {
            showWithAster();
    
        }
    
    }
    View Code

    Main类:(利用前面所建立的PrintBanner类(即适配器功能)减弱(小括号)、或增强(前后一个*)字符串Hello后再输出)。

    public class Main {
    
        public static void main(String[] args) {
            Print p = new PrintBanner("Hello");
            p.printWeak();
            p.printStrong();
    
        }
    
    }
    View Code

    最后运行程序的结果为:

    请注意,这里是把PrintBanner的对象实例指定到Print接口类型的变量。Main类只不过是利用Print这个接口来写程序而已。从Main类的源代码完全看不出有Banner类、showWithParen方法或showWithAster方法。就好像是笔记本电脑只要有人提供12V直流电的电流就能正常运行,根本不知道它的原形(适配器的另一端)竟然是220V交流电。

    前面的程序使用“类”的Adapter Pattern,下面我们用第二种方法来实现:

    我们首先依然来看看类图:

    同第一种方法相比,只需修改Print类和PrintBanner类即可,其余的类同第一种方法相同:

    Print类:

    public abstract class Print {
        public abstract void printWeak();
    
        public abstract void printStrong();
    
    }

    PrintBanner类:

    public class PrintBanner extends Print {
        private Banner banner;
    
        public PrintBanner(String string) {
            this.banner = new Banner(string);
        }
    
        @Override
        public void printWeak() {
            banner.showWithParen();
    
        }
    
        @Override
        public void printStrong() {
            banner.showWithAster();
    
        }
    
    }

    其运行结果同第一种相同:

    Addapter Pattern 中所出现过的参与者可整理如下:

    Targer(对象)参与者

      在程序示例中,负责这个参与者的是Print接口(继承)和Print类(委托)

    Client (委托人)参与者

      利用对象参与者的方法来做事的参与者,在程序示例中,负责这个参与者的是Main类。

    Adaptee(被动符合)参与者

      在程序示例中,负责这个但与这的是Banner类。如果担任Adptee参与者的方法与Target参与者的方法相符时,那就不需要后面的Adapter参与者了。

    Adapter(主动符合)参与者

      利用Adaptee参与者的方法努力满足Targetc参与者的要求是Adapter Pattern 的使命,这是Adapter参与者的工作。在程序示例中,负责这个参与者的是PrintBanner类。如果是类的Adapter Pattern,Adapter参与者要通过“继承”的方式来利用Adaptee参与者。

    适用性:

    1. 系统需要使用现有的类,而此类的接口不符合系统的需要。

    2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。

    3. (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

     

    效果及优缺点:

    对于类适配器:

    1. 用一个具体的Adapter类对Adaptee和Taget进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。

    2. 使得Adapter可以override(重定义) Adaptee的部分行为,因为Adapter是Adaptee的一个子类。

    对于对象适配器:

    1. 允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter也可以一次给所有的Adaptee添加功能。

    2. 使得override(重定义)Adaptee的行为比较困难。如果一定要override Adaptee的方法,就只好先做一个Adaptee的子类以override Adaptee的方法,然后再把这个子类当作真正的Adaptee源进行适配。

  • 相关阅读:
    接口默认值引发Qt调用DLL异常
    360杀毒引发的DLL调用异常
    VS2012基于QT5.1自定接口及插件并实现动态加载
    Qt调用C的DLL
    Qt动态多语言的实现(VS2012开发)
    Qt在VS2012中引用QtWidgets时报GLES2/gl2.h无法打开错误的解决办法
    php判断某字符串是否不以数字或其他特殊字符开头
    mysql的数据类型int、bigint、smallint 和 tinyint取值范围
    28个jQuery性能优化的建议
    主题:iframe高度的自适应
  • 原文地址:https://www.cnblogs.com/scetopcsa/p/3707731.html
Copyright © 2020-2023  润新知