Adapter pattern适用情景:
- 如果想使用已有的类(Adaptee),并且自身(Target)的接口并不满足需求
- 想要创建一个可以重复使用的类(Adapter),这个类要与另一个无关的类(Adaptee)交互,也就是说两个类之间不一定有兼容的接口
- (只用于对象适配器-Object adapter)需要使用多个已有的子类(Adaptee1, Adaptee2),但是为这些子类(Adaptee1, Adaptee2)分别创建子类是不切实际的,这时可以创建一个对象适配器(Adapter)用来适配其父类(Target)的接口
例子:
接口Shape:
/**
* Target
*/
public interface Shape {
//画图
void draw();
//调整大小
void resize();
//描述
String description();
//是否隐藏
boolean isHide();
}
实现Shape的两个接口Circle和Rectangle:
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
@Override
public void resize() {
System.out.println("Resizing Circle");
}
@Override
public String description() {
return "Circle object";
}
@Override
public boolean isHide() {
return false;
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
@Override
public void resize() {
System.out.println("Resizing Rectangle");
}
@Override
public String description() {
return "Rectangle object";
}
@Override
public boolean isHide() {
return false;
}
}
另一个与Shape无关的接口GeometricShape:
public interface GeometricShape {
//面积
double area();
//周长
double perimeter();
//画图
void drawShape();
}
实现GeometricShape接口的两个类Triangle和Rhombus:
public class Triangle implements GeometricShape {
private final double a;
private final double b;
private final double c;
public Triangle() {
this(1.0d, 1.0d, 1.0d);
}
public Triangle(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public double area() {
double s = (a + b + c) / 2;
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
@Override
public double perimeter() {
return a + b + c;
}
@Override
public void drawShape() {
System.out.println("Drawing Triangle with area: " + area() + " and perimeter: " + perimeter());
}
}
public class Rhombus implements GeometricShape {
private final double a;
private final double b;
public Rhombus() {
this(1.0d, 1.0d);
}
public Rhombus(double a, double b) {
this.a = a;
this.b = b;
}
@Override
public double area() {
return a * b;
}
@Override
public double perimeter() {
return 2 * (a + b);
}
@Override
public void drawShape() {
System.out.println("Drawing Rhombus with area: " + area() + " and perimeter: " + perimeter());
}
}
Client类 Drawing:
/**
* Client
*/
public class Drawing {
List<Shape> shapes = new ArrayList<>();
public Drawing() {
super();
}
public void addShape(Shape shape) {
shapes.add(shape);
}
public List<Shape> getShapes() {
return new ArrayList<>(shapes);
}
public void draw() {
if (shapes.isEmpty()) {
System.out.println("Nothing to draw!");
} else {
shapes.stream().forEach(shape -> shape.draw());
}
}
public void resize() {
if (shapes.isEmpty()) {
System.out.println("Nothing to resize!");
} else {
shapes.stream().forEach(shape -> shape.resize());
}
}
}
Object Adapter pattern:
/**
* Object adapter
*/
public class GeometricShapeObjectAdapter implements Shape {
// Adaptee
private GeometricShape adaptee;
public GeometricShapeObjectAdapter(GeometricShape adaptee) {
super();
this.adaptee = adaptee;
}
@Override
public void draw() {
adaptee.drawShape();
}
@Override
public void resize() {
System.out.println(description() + " can't be resized. Please create new one with required values.");
}
@Override
public String description() {
if (adaptee instanceof Triangle) {
return "Triangle object";
} else if (adaptee instanceof Rhombus) {
return "Rhombus object";
} else {
return "Unknown object";
}
}
@Override
public boolean isHide() {
return false;
}
}
测试代码:
System.out.println("Creating drawing of shapes...");
Drawing drawing = new Drawing();
drawing.addShape(new Rectangle());
drawing.addShape(new Circle());
drawing.addShape(new GeometricShapeObjectAdapter(new Triangle()));
drawing.addShape(new GeometricShapeObjectAdapter(new Rhombus()));
System.out.println("Drawing...");
drawing.draw();
System.out.println("Resizing...");
drawing.resize();
输出结构:
Creating drawing of shapes...
Drawing...
Drawing Rectangle
Drawing Circle
Drawing Triangle with area: 0.4330127018922193 and perimeter: 3.0
Drawing Rhombus with area: 1.0 and perimeter: 4.0
Resizing...
Resizing Rectangle
Resizing Circle
Triangle object can't be resized. Please create new one with required values.
Rhombus object can't be resized. Please create new one with required values.
Class Adapter pattern:
/**
* Class adapter
*/
public class RhombusAdapter extends Rhombus implements Shape {
public RhombusAdapter() {
super();
}
@Override
public void draw() {
drawShape();
}
@Override
public void resize() {
System.out.println("Triangle can't be resized. Please create new one with required values.");
}
@Override
public String description() {
return "Triangle object";
}
@Override
public boolean isHide() {
return false;
}
}
/**
* Class adapter
*/
public class TriangleAdapter extends Triangle implements Shape {
public TriangleAdapter() {
super();
}
@Override
public void draw() {
drawShape();
}
@Override
public void resize() {
System.out.println("Triangle can't be resized. Please create new one with required values.");
}
@Override
public String description() {
return "Triangle object";
}
@Override
public boolean isHide() {
return false;
}
}
测试代码:
System.out.println("Creating drawing of shapes...");
Drawing drawing = new Drawing();
drawing.addShape(new Rectangle());
drawing.addShape(new Circle());
drawing.addShape(new TriangleAdapter());
drawing.addShape(new RhombusAdapter());
System.out.println("Drawing...");
drawing.draw();
System.out.println("Resizing...");
drawing.resize();
测试结果:
Creating drawing of shapes...
Drawing...
Drawing Rectangle
Drawing Circle
Drawing Triangle with area: 0.4330127018922193 and perimeter: 3.0
Drawing Rhombus with area: 1.0 and perimeter: 4.0
Resizing...
Resizing Rectangle
Resizing Circle
Triangle can't be resized. Please create new one with required values.
Triangle can't be resized. Please create new one with required values.