适配器模式
目的
将某个类或者接口转化为客户端期望的形式,从而:
- 解决类之间接口不兼容问题。
- 通过增加一个接口,将已存在的子类封装起来,客户端面向接口编程,从而隐藏了具体实现类。
模式的结构与实现
适配器模式(Adapter)包含以下主要角色。
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
实例
适配者类:
public class Adaptee {
public void adapterRequest(){
System.out.println("适配者的方法");
}
}
目标接口:
public interface Target {
void request();
}
现在,我们需要在目标接口中的 request() 调用 Adaptee 的 adapterRequest() 方法。
我们可以构造一个适配器类,该类继承了适配者类,同时实现了目标接口。
public class Adapter extends Adaptee implements Target {
@Override
public void request() {
super.adapterRequest();
}
}
这样,在客户端调用时,我们就可以使用Target接口里的方法调用到适配者类里的方法。打个比方,可以把适配者和适配器看成中国人和外国人,它们之间是不能直接交流的,因而我们需要借助翻译器将中文翻译成外文,这样只要我们实现了翻译器这个目标接口,我们就能顺利地进行交流。
装饰器模式
目的
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
实例
我们定义一个形状接口:
public interface Shape {
void draw();
}
将这个接口分别实现为长方形和圆形:
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
创建抽象装饰类:
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
创建实体装饰类:
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
客户端代码如下:
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
//Shape redCircle = new RedShapeDecorator(new Circle());
//Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
这样可以为shape类的子类提供统一的装饰器实现,而不需要为新添加的功能继续编写子类。