Decorator模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许用户在不修改原有对象结构的情况下,为对象添加新的功能。这种模式创建了一个装饰类,用来包装原有的类,并在保持原有类方法签名不变的前提下,提供了额外的功能。

  • 目的:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
  • 主要解决:在不想增加很多子类的情况下扩展类。
  • 何时使用:在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 如何解决:使用组合而非继承的技术,动态地给对象添加功能。
  • 关键代码:装饰器和被装饰类有相同的接口,装饰器类持有被装饰类的实例。
  • 应用实例:1. Java IO 中的输入流和输出流的设计;2. Swing 包中图形界面构件功能;3. Java Servlet API 中的HttpServletRequestWrapper和HttpServletResponseWrapper。

Java

假设我们有一个Shape接口和实现了Shape接口的具体类RectangleCircle。我们将创建一个实现了Shape接口的抽象装饰类ShapeDecorator,并将Shape对象作为其实例变量。

interface Shape {
    void draw();
}

class Rectangle implements Shape {
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Shape: Circle");
    }
}

abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    public void draw() {
        decoratedShape.draw();
    }
}

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");
    }
}

Golang

package main

import "fmt"

type Shape interface {
    Draw()
}

type Rectangle struct{}

func (r Rectangle) Draw() {
    fmt.Println("Shape: Rectangle")
}

type Circle struct{}

func (c Circle) Draw() {
    fmt.Println("Shape: Circle")
}

type ShapeDecorator struct {
    decoratedShape Shape
}

func NewShapeDecorator(shape Shape) *ShapeDecorator {
    return &ShapeDecorator{
        decoratedShape: shape,
    }
}

func (s *ShapeDecorator) Draw() {
    s.decoratedShape.Draw()
}

type RedShapeDecorator struct {
    ShapeDecorator
}

func NewRedShapeDecorator(decoratedShape Shape) *RedShapeDecorator {
    return &RedShapeDecorator{ShapeDecorator{decoratedShape}}
}

func (r *RedShapeDecorator) Draw() {
    r.ShapeDecorator.Draw()
    fmt.Println("Border Color: Red")
}

func main() {
    circle := Circle{}
    redCircle := NewRedShapeDecorator(&circle)
    redCircle.Draw()
}

Python

Python的动态性使得装饰器模式的实现非常直接和灵活。

class Shape:
    def draw(self):
        pass

class Rectangle(Shape):
    def draw(self):
        print("Shape: Rectangle")

class Circle(Shape):
    def draw(self):
        print("Shape: Circle")

class ShapeDecorator(Shape):
    def __init__(self, decorated_shape):
        self.decorated_shape = decorated_shape

    def draw(self):
        self.decorated_shape.draw()

class RedShapeDecorator(ShapeDecorator):
    def draw(self):
        self.decorated_shape.draw()
        self.set_red_border()

    def set_red_border(self):
        print("Border Color: Red")

if __name__ == "__

main__":
    circle = Circle()
    red_circle = RedShapeDecorator(circle)
    red_circle.draw()