装饰模式(三)

91 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

上一篇文章我们通过文字描述的方法讲了装饰模式的具体使用方法,虽然是使用文字的描述,但是看起来毫不费力,流程十分清晰。虽然这样,但是我们还是需要使用具体场景的具体实例来做分析。

使用举例

通过上一篇文章我发知道,一个完成的装饰模式分为四个角色,我们就围绕着这四个角色展开做讲解。

抽象构件角色

对于抽象构建类,我们将业务场景做简化,使其是有一个简单的operation方法:

interface Component
{
    void operation();
}

具体构件角色

具体构件角色需要继承(实现)抽象构建角色,如下:

class ConcreteComponent extends Component
{
    public void operation()
    {
        System.out.println("this is concrete component");
    }
}

抽象装饰角色

抽象装饰角色就是对被装饰的对象的一个修饰,所以这里我们继承(实现)抽象构建角色,为了对外提供一个和抽象构件相同的接口(达到对客户端透明的目的),并且装饰角色中需要有一个抽象构件角色的成员变量,代码如下:

class Decorator extends Component
{
    private Component component;

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

    @Override
    public void operation()
    {
        component.operation();
    }
}

抽象装饰角色这里不做过多的业务逻辑的添加,实际的业务逻辑需要放到具体装饰角色中。

同时,抽象装饰角色需要包含一个抽象构件的私有成员,这样就可以通过setter或者构造方法向其中注入不同的具体构件;这样做就可以在业务方法中方便调用具体构件角色未被装饰之前的方法,这样我们就可以针对不同的业务场景添加不同的装饰逻辑。

具体装饰角色

具体装饰角色就按照不同的业务需求来完成不同的定制,它需要继承抽象装饰角色,代码如下:

class ConcreteDecorator extends Decorator
{
    public ConcreteDecorator(Component component)
    {
        super(component);
    }

    public void operation()
    {
        super.operation();
        newBehavior();
    }

    private void newBehavior()
    {
        System.out.println("this is decorate logic");
    }
}

在对外提供的接口operation中,我们首先调用父类(抽象装饰角色)的operation方法,然后再调用新的装饰方法newBehavior

总结

通过如上具体的代码,我们就可以清晰地看出装饰模式的使用步骤了。针对我们不同的业务场景,可以套用这个模板来完成相应的需求开发。

在客户端调用的时候,我们可以直接使用如下代码:

// 某个具体的构件角色
Component component = new ConcreteComponent();
// 某个具体的装饰角色
Component decorator = new ConcreteDecorator(component);
// 调用操作方法
decorator.operation();

通过上面的代码我们可以看出,直接调用operation方法,我们就可以实现对原始构件的装饰,但是对于客户端而言,他们调用搜到api 并没有变化,依旧是operation方法,但是实际我们却为其增加了许多新功能。