装饰模式的抽象介绍与简单实现

装饰模式的抽象介绍与简单实现

何为装饰模式?

动态地给对对象添加一些额外的职责,就增加功能来说,装饰子类比生成子类更加灵活。

首先看看装饰模式的UML图
在这里插入图片描述

Component类

定义一个对象接口,可以给这些对象动态的添加职责

public abstract class Component {
    public abstract void Operation();
}

ConcreteComponent类

继承Component类定义一个具体的对象,也可添加职责

public class ConcreteComponent extends Component{
    @Override
    public void Operation() {
        //实现操作
        System.out.println("基础对象的操作");
    }
}

Decorator类

装饰抽象类,继承Component类,从外类扩展Component的功能

public class Decorator extends Component{
    protected Component component;

    public Component getComponent() {
        return component;
    }

    public void setComponent(Component component) {
        this.component = component;
    }

    @Override
    public void Operation() {
        if(component != null){
            component.Operation();
        }
    }
}

ConcreteDecorator类

具体的装饰对象,起到给Component类添加职责的功能

public class ConcreteDecoratorA extends Decorator{
    //本类特有的状态
    private String addedState;

    @Override
    public void Operation() {
        super.Operation();
        addedState = "new state";
        System.out.println("A装饰对象的操作");
    }
}
public class ConcreteDecoratorB extends Decorator{

    @Override
    public void Operation() {
        super.Operation();
        addBehavior();
        System.out.println("具体装饰对象B的操作");
    }

    public void addBehavior(){
        //特有方法
        System.out.println("B类的特有方法");
    }
}
...

客户端类

使用,中间的注释是代码流程和我的解析

public class Client {
    public static void main(String[] args) {
        ConcreteComponent c = new ConcreteComponent();
        ConcreteDecoratorA a = new ConcreteDecoratorA();
        ConcreteDecoratorB b = new ConcreteDecoratorB();

        a.setComponent(c);
        b.setComponent(a);
        b.Operation();
        //首先使用ConcreteComponent实例化一个对象c,a包装c,b包装a,最后执行b的操作
        //b的super.operation()操作此时为a.operation()操作,a的super.operation()操作此时为c.operation()操作
        //b.Operation()->b.super.Operation()->b.component.Operation()
        // ->a.Operation()->a.super.Operation()->a.component.Operation()->c.Operation()
        // b.component=>a,a.component=>c
    }
}
/*	基础对象的操作
    A装饰对象的操作
    B类的特有方法
    具体装饰对象B的操作 */

总解析

装饰模式利用setComponent方法对对象进行包装,使得每个装饰对象的实现与如何使用这个对象的使用操作分离了,每个装饰对象只关心自己的功能,不需要关心如何被添加到装饰链中。

实例:穿衣搭配

问题:小菜搭配好衣服去约会,请你协助他

ConcreteComponent类
public class Person {//人类
    private String name;

    public Person(String name) {
        this.name = name;
    }
    public Person(){}

    public void show(){
        System.out.print("装扮的"+name);
    }
}
Decorator类
public class Finery extends Person {
    protected Person component;

    public void decorate(Person component){
        this.component = component;
    }

    @Override
    public void show() {
        if(component!=null){
            component.show();
        }
    }
}
ConcreteDecorator类
public class Tie extends Finery {
    @Override
    public void show() {
        System.out.print("打领带");
        super.show();
    }
}

public class TShirts extends Finery{
    @Override
    public void show() {
        System.out.print("穿大衣");
        super.show();
    }
}
客户端类
public class Client {
    public static void main(String[] args) {
        Person person = new Person("小菜");
        Finery f1 = new Tie();
        Finery f2 = new TShirts();
        f1.decorate(person); f2.decorate(f1);
        f2.show();
    }
}
//输出:穿大衣打领带装扮的小菜

我们注意到此时无component类,这是因为ConcreteComponent只需要一个,那么我们不需要让ConcreteComponent继承component类再使用,我们应该灵活使用,而不是照搬模式。Decorator也是如此,如果ConcreteDecorator只有一个那么我们则不使用Decorator类。

具体与抽象对应

  • decorate方法即是setComponent方法
  • show方法即是Operation方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值