设计模式-结构型模式之装饰者模式(DecoratorPattern)

定义

装饰者模式(DecoratorPattern):对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。

相关角色

  • 抽象构件(Component)角色:给出一个抽象接口,以规范准备接受附加责任的对象;
  • 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类;
  • 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口;
  • 具体装饰(ConcreteDecorator)角色:负责给构件对象 ”贴上“附加的责任。

解决问题

动态地将责任附加到对象身上,比继承更具有弹性。

UML类图

设计模式-结构型模式之装饰者模式(DecoratorPattern)_第1张图片
decorator.png

Component

public interface Component {
    void sampleMethod();
}

Decorator

public class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void sampleMethod() {
        // 委派给构件
        component.sampleMethod();
    }
}

ConcreteComponent

public class ConcreteComponent implements Component {
    @Override
    public void sampleMethod() {
        System.out.println("I'm ConcreteComponent");
    }
}

ConcreteDecorator

public class ConcreteDecorator extends Decorator {

    public ConcreteDecorator(Component component) {
        super(component);
    }

    @Override
    public void sampleMethod() {
        //写相关的业务代码
        super.sampleMethod();
        addFunction();
    }

    public void addFunction() {
        System.out.println(" add Function ConcreteDecorator");
    }

}

例子

在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类)、AccessoriesPhone(挂件手机类)等,这样就会导致 ”子类爆炸“问题,为了解决这个问题,我们可以使用装饰者模式来动态地给一个对象添加额外的职责。

类图

设计模式-结构型模式之装饰者模式(DecoratorPattern)_第2张图片
decorator_phone.png

Phone

public abstract class Phone {
    public abstract void print();
}

Decorator

public abstract class Decorator extends Phone {
    Phone phone;

    public Decorator(Phone phone) {
        this.phone = phone;
    }

    @Override
    public void print() {
        if (phone != null)
            phone.print();
    }
}

XiaoMiPhone

public class XiaoMiPhone extends Phone {

    @Override
    public void print() {
        System.out.println("小米手机");
    }

}

Accessories

public class Accessories extends Decorator {

    public Accessories(Phone phone) {
        super(phone);
    }

    @Override
    public void print() {

        super.print();
        addAccessories();
    }

    public void addAccessories() {
        System.out.println("我是带挂件的手机");
    }

}

优缺点

优点:

  • 装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活;
  • 通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合;
  • 装饰者模式有很好地可扩展性。

缺点:

  • 装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

延伸

使用场景

下面让我们看看装饰者模式具体在哪些情况下使用,在以下情况下应当使用装饰者模式:

  • 需要扩展一个类的功能或给一个类增加附加责任;

  • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销;

  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能。

相关源码

Design-Model

你可能感兴趣的:(设计模式-结构型模式之装饰者模式(DecoratorPattern))