一、Structural patterns(结构型模式)
1.Adapter,适配器模式
概念:适配器模式是作为两个互不相容的接口的桥梁,将某个类/接口转换为client期望的其他形式。适配器模式使得原本由于接口不兼容而不能一起工作的的那些类/接口可以一起工作。
用途:主要解决在软件系统中,需要将现存的类放到新的环境中,而环境要求的接口是现对象不能满足的。
如何实现:通过增加一个新的接口,将已存在的子类封装起来,client直接面向接口编程,从来隐藏了具体子类。适配器继承或依赖已有的对象,实现想要的目标接口。
有下面这样一个实例:
其中LegacyRectangle是已有的类(需要传入矩形的一个顶点、长和宽),但是与client要求的接口不一致(需要给出对角线两个顶点坐标),我们此时建立一个新的接口Shape以供客户端调用,用户通过Shape接口传入两个点的坐标。Rectangle作为Adapter,实现该抽象接口,通过具体的方法实现适配
public interface Shape { //新增的接口,client调用
public void display(int x1, int y1, int x2, int y2);
}
public class RectangleAdapter implements Shape { //Adapter,实现该抽象接口,给出适配方法。
LegacyRectangle legacy = new LegacyRectangle(); //使用delegation
@Override
public void display(int x1, int y1, int x2, int y2) {
legacy.display(x1, x2, x1-x1, y2-y1);
}
}
public class LegacyRectangle { //原来的实现类/接口,但是不适用于新系统
public void display(int x1, int y1, int w, int h) {…}
}
public class Client {
Shape shape = new RectangleAdapter(); //用户调用新增的接口即可,忽略了内部实现
public display() {
shape.display(x1, x2, y1, y2);
}}
上面过程可以抽象为:
2.Decorator,装饰器模式
装饰器模式允许向一个现有的对象添加新的功能,同时又不该边其结构,它是作为一个现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保证类方法签名完整性的前提下,提供额外的功能。
装饰模式是继承的一个代替模式,装饰模式可以动态地给一个对象添加一些额外地功能。就增加功能来说,装饰器模式比生成子类更为灵活。
实现方法:将具体功能职责划分,对每一个特性构造子类,通过委派机制增加到对象上。
·Component 类充当抽象角色,不应该具体实现
·Decorator 修饰类引用和继承Component类,具体扩展类重写父类方法
下面这个例子:
我们创建了一个Shape接口和它的两个具体实现:
public interface Shape { //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");
}
}
然后我们创建了一个实现了Shape接口的抽象装饰类ShapeDecorator,并把Shape对象作为它的实例变量
public abstract class ShapeDecorator implements Shape { //继承Component类,并实现父类方法
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
RedShapeDecorator是实现了ShapeDecorator的实体类
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw(); //基础功能通过delegation实现
setRedBorder(decoratedShape); //增加了新特性
}
private void setRedBorder(Shape decoratedShape){ //通过装饰器动态增加的额外功能
System.out.println("Border Color: Red");
}
}
使用RedShapeDecorator来装饰Shape对象
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
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();
}
}
输出结果
Circle with normal border
Shape: Circle
Circle of red border
Shape: Circle
Border Color: Red
Rectangle of red border
Shape: Rectangle
Border Color: Red
Decorator的缺点是
多层装饰比较复杂,
客户端需要一个具有多特性的object,需要一层一层的装饰来实现,比如要构造一个实心的红色的长方形,
Shape SolidRectangle = new SolidShapeDecorator(new RedShapeDecorator(new Rectangle()));
Decorator是动态地在运行阶段给对象增加新特性;Decorator有多个合作对象组成,由继承产生的一个个简单地、定义清晰地对象,如本例中的 RedShapeDecorator 和 SolidShapeDecorator(未给出);可以混合匹配多个装饰,即多层修饰。
3.Facade, 外观模式
外观模式隐藏系统的复杂性,它向现有的系统添加一个接口,客户端通过一个简化的接口来访问复杂系统的功能。相当于对复杂系统做了一个封装,简化客户端使用。
下面这个例子:
先创建一个Shape接口和实现了Shape接口的实现类,这里省略。
下一步是定义一个外观类ShapeMaker。
public class ShapeMaker {
public static void drawShape(String type){
switch(type) {
case Circle:
new Circle.draw();
break;
case Rectangle:
new Rectangle.draw();
break;
case Square:
new Square.draw();
break;
default:
System.out.println("type error");
}
}
}