设计模式之适配器模式

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之适配器模式相关的知识,希望对你有一定的参考价值。

1.简要概述

  • 适配器模式就是将一个类的接口转换成客户需要的另外一个接口。

  • 适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

  • 适配器模式中,对用户来说,他调用的只是目标接口中的方法,而对于内部被适配的类的方法是透明的,实现了用户与适配类之间的解耦。

2.模式分类

适配器模式主要有三种:类适配器模式、对象适配器模式、接口适配器模式。

  • 类适配器模式中,由于适配器需要继承待适配的类,这就要求适配目标必须是接口,有一定的局限性。

    public class Adapter extends Adaptee implements Target{
        @Override
        public void targetMethod() {
            // 调用Adaptee中的方法
            ...
        }
    }
    
  • 对象适配器模式中,将待适配的类的实例充当为适配器中的成员变量,而不是继承待适配的类,这就解决了类适配器模式中出现的问题,而且这种方式满足合成复用原则。

    public class Adapter implements Target{
        private Adaptee adaptee;
        
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
        
        @Override
        public void targetMethod() {
            // 调用Adaptee中的方法
            ...
        }
    }
    
  • 接口适配器模式中,它允许我们只使用目标接口中的某些方法,也就是先通过一个抽象类去实现目标接口,然后适配器再去实现这个抽象类。

    public abstract class AbstractTarget implements Target{
        @Override
        public void method1() {...}
        
        @Override
        public void method2() {...}
        
        @Override
        public void method3() {...}
    }
    
    public class Adapter implements AbstractTarget{
        private Adaptee adaptee;
        
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
        
        @Override
        public void method1() {
            // 调用Adaptee中的方法
            ...
        }
    }
    

3.模式结构

👉通常由一个目标接口( 客户所需要的接口 ),一个需要适配的类( 需要适配的类或适配者类 ),一个适配器( 包装一个需要适配的对象,把原接口转换成目标接口 ),一个客户类( 进行调用,完成从一个接口转换为另一个接口 )共同组成。

4.实现代码

举例 💡 :假设现在有一位学生和一位老师,学生负责听课,老师负责讲课。而现在老师有事,该学生需要承担老师的角色进行讲课。那么这个过程就可以用适配器模式来实现。

目标接口

public interface Teacher {
    void teaching();
}

待适配的类

public class Student {
   public void who(){
       System.out.println("我是学生");
   }
}

适配器

public class MyAdapter implements Teacher {
    private Student student;

    public MyAdapter(Student student) {
        this.student = student;
    }

    @Override
    public void teaching() {
        student.who();
        
        System.out.println("我要讲课了");
    }
}

客户类

// 测试客户端
public class PrototypeClient{
    public static void main(String[] args) {
        Student student = new Student();
        
        Teacher tea = new MyAdapter(student);
        
        tea.teaching(); // 我是学生,我要讲课了
    }
}

5.优点好处

  • 将原本不兼容的接口进行适配,使它们能够融合在一起完成某些工作,并且将目标类和适配者类进行了解耦。
  • 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
  • 提高了系统灵活性和可扩展性,符合开闭原则。

6.缺点弊端

由于Java语言不支持多重继承,所以说如果使用类适配器模式的话,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,这就产生了很大程度上的局限性。

7.应用场景

  • 当系统需要使用现有的类不能够满足当前系统需要的时候使用。
  • 当某些系统中的接口需要升级改造,而又想保留原接口的时侯使用。
  • 当我们想要建立一个可以复用的类,然后与一些彼此之间没有太大关联的一些类协同工作的时候使用。

8.应用示例

JDK源码中把InputStream对象转化为Reader对象

上面的代码中,InputStream就好比是待适配的类,而InputStreamReader就好比是适配器,这里明显采用了对象适配器模式,因为这里将inputStream对象传递到了适配器中,然后通过适配器得到了目标接口Reader,然后调用了里面的read()方法,所以整个过程就是采用了适配器模式。

以上是关于设计模式之适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之适配器模式

Java设计模式之适配器模式

php设计模式之适配器模式实例代码

PHP设计模式之适配器模式

设计模式之适配器模式

设计模式之适配器模式