设计模式-适配器模式

  1. 适配器模式(Adapter Pattern)

将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

有时,为复用而设计的工具箱类不能够被复用的原因仅仅是它的接口与专业应用领域所需要的接口不匹配。

以下情况使用适配器模式:

  • 你想使用一个已经存在的类,而它的接口不符合你的需求。
  • 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见得类协同工作。
  • 你想使用一些已经存在的子类、但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

 

对象适配器:在这种模式下,适配器包含(非继承或实现的方式)一个它所包装的一个类的实例,适配器通过调用包装类对象的方法来完成适配。

0bfd4db420b4f7ed779cfaa9eee19c1204e.jpg

 

类适配器:这种模式用于预期的和已经存在的接口的多个实现和继承,典型情况下,预期的接口被创建为单纯的接口类,尤其对于java这种不支持多继承的语言来说更是这样。

 

88d6984b9a574c5b821c92ce5a74fa12d7a.jpg 

二者区别:

类适配器的重点在于类,是通过构造一个继承Adaptee类来实现适配器的功能;
对象适配器的重点在于对象,是通过在直接包含Adaptee类来实现的,当需要调用特殊功能的时候直接使用Adapter中包含的那个Adaptee对象来调用特殊功能的方法即可。

 

示例:

  1. 对象适配器

RowingBoat.java

public interface RowingBoat {



  void row();



}

FishingBoat.java

public class FishingBoat {



  public void sail() {

    System.out.println("The fishing boat is sailing");

  }



}

 

FishingBoatAdapter.java

public class FishingBoatAdapter implements RowingBoat {



  private FishingBoat boat;



  public FishingBoatAdapter() {

    boat = new FishingBoat();

  }



  @Override

  public void row() {

    boat.sail();

  }

}

 

Caption.java

public class Captain {



  private RowingBoat rowingBoat;



  public Captain() {}



  public Captain(RowingBoat rowingBoat) {

    this.rowingBoat = rowingBoat;

  }



  public void setRowingBoat(RowingBoat rowingBoat) {

    this.rowingBoat = rowingBoat;

  }



  public void row() {

    rowingBoat.row();

  }



}

 

App.java

public class App {



  public static void main(String[] args) {

    // The captain can only operate rowing boats but with adapter he is able to use fishing boats as well

    Captain captain = new Captain(new FishingBoatAdapter());

    captain.row();

  }

}

Caption并不操作Rowingboat,而是通过适配器来操作。

如果有另外一种类的船只,可以实现新的适配器,而对于Caption来说也是透明的,调用方式相同。

 

  1. 类适配器

EnglishPerson.java

public interface EnglishPerson {

    void sayEnglish();

}

FrenchPerson.java

public interface FrenchPerson {

    void sayFrench();

}

Person.java

public class Person {

    private int id;

    private String name;

    /**

     * person可以现在只能说英语

     */

    public void sayEnglish(){

        System.out.println("Person can say english!");

    }



    /**

     * 省略setter,getter.

     */



}

AdapterPerson.java

public class AdapterPerson extends Person implements EnglishPerson, FrenchPerson{

    @Override

    public void sayEnglish() {

        System.out.println("Person can say English!");

    }



    @Override

    public void sayFrench() {

        System.out.println("Person can say French!");

    }



}

App.java

public class App {

    public static void main(String[] args) {

        EnglishPerson engPerson = new AdapterPerson();

        engPerson.sayEnglish();



        FrenchPerson frcPerson = new AdapterPerson();

        frcPerson.sayFrench();

    }

}

 

  1. 桥接模式(Bridge Pattern)

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

以下一些情况使用桥接模式:

  • 你不希望在抽象和它的实现之间有一个固定的绑定关系。
  • 类的抽象以及它们的实现都应该可以通过生成子类的方法加以补充,这时桥接模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  • (C++)你想对客户完全隐藏抽象的实现部分,在C++中,类的表示在类接口中是可见的。
  • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

 

 

 

 

示例:

DrawingAPI.java

public interface DrawingAPI {

    public void drawCircle(final double x, final double y, final double radius);

}

DrawingAPI1.java

public class DrawingAPI1 implements DrawingAPI {

    public void drawCircle(final double x, final double y, final double radius) {

        System.out.printf("API1.circle at %f:%f radius %f%n", x, y, radius);

    }

}

DrawingAPI2.java

public class DrawingAPI2 implements DrawingAPI {

    public void drawCircle(final double x, final double y, final double radius) {

        System.out.printf("API2.circle at %f:%f radius %f%n", x, y, radius);

    }

}

Shape.java

abstract class Shape {

    protected DrawingAPI drawingAPI;



    protected Shape(final DrawingAPI drawingAPI){

        this.drawingAPI = drawingAPI;

    }



    public abstract void draw();                                 // low-level

    public abstract void resizeByPercentage(final double pct);   // high-level

}

 

CricleShape.java

public class CircleShape extends Shape {

    private double x, y, radius;

    public CircleShape(final double x, final double y, final double radius, final DrawingAPI drawingAPI) {

        super(drawingAPI);

        this.x = x;  this.y = y;  this.radius = radius;

    }



    // low-level i.e. Implementation specific

    public void draw() {

        drawingAPI.drawCircle(x, y, radius);

    }

    // high-level i.e. Abstraction specific

    public void resizeByPercentage(final double pct) {

        radius *= (1.0 + pct/100.0);

    }

}

BridgePattern.java

public class BridgePattern {

    public static void main(final String[] args) {

        Shape[] shapes = new Shape[] {

                new CircleShape(1, 2, 3, new DrawingAPI1()),

                new CircleShape(5, 7, 11, new DrawingAPI2())

        };



        for (Shape shape : shapes) {

            shape.resizeByPercentage(2.5);

            shape.draw();

        }

    }

}

 

 

架构师成长营

转载于:https://my.oschina.net/u/3963977/blog/2985820

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值