每日学一个设计模式12——装饰器模式

装饰器模式(装饰边框与被装饰物的一致)

用处

为对象添加装饰,使其增加新的功能

角色

  • Component
    增加功能时的核心角色。只定义了方法(API)
  • ConcreteComponent
    该角色是实现了Component角色所定义方法(API)的具体角色
  • Decorator(装饰物)
    该角色是具有与Component角色相同的方法(API),它内部保存了被装饰对象——Component角色。Decorator就角色知道自己要装饰的对象
  • ConcreteDecorator(具体的装饰物)
    该角色是具体的Decorator角色。

类图

在这里插入图片描述
由类图可知

  • 被装饰物ConcreteComponent和装饰器Decorator都是Component类的子类,Decorator类中聚合了Component接口,因此装饰器对象中可以聚合装饰器对象Decorator,也可以聚合被装饰物ConcreteComponent,就像Decorator就像画框一样,ConcreteComponent像画一样,可以在画的外面套无限层画框(装饰器),每个装饰器可以实现不同的功能增强。

举例

public class Main  {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("Hello world");
        Display b2 = new SideBorder(b1,'#');
        Display b3 = new FullBorder(b2);
        b1.show();
        b2.show();
        b3.show();
        Display b4 = new SideBorder(
                new FullBorder(
                    new FullBorder(
                        new SideBorder(
                            new FullBorder(
                                new StringDisplay("你好,世界")
                            ),'*'
                        )
                    )
                ),'/'
        );
        b4.show();
    }
}

//Component角色
abstract class Display {
    public abstract int getColumns();

    public abstract int getRows();

    public abstract String getRowText(int row);

    public final void show(){
        for(int i = 0 ; i<getRows();i++){
            System.out.println(getRowText(i));
        }
    }
}

//ConcreteComponent角色
 class StringDisplay extends Display{
    private String string;
    public StringDisplay(String string){
        this.string = string;
    }
    public int getColumns(){
        return string.getBytes().length;
    }
    public int getRows(){
        return 1;
    }
    public String getRowText(int row){
        if(row == 0 ){
            return string;
        }else{
            return null;
        }
    }
}

//Decorator角色
abstract class Border extends Display{
    protected Display display;
    protected Border(Display display){
        this.display = display;
    }
}


//ConcreteDecorator角色
class SideBorder extends Border{
    private char borderChar;
    public SideBorder(Display display,char ch){
        super(display);
        this.borderChar = ch;
    }
    public int getColumns(){
        return 1 + display.getColumns()+1;
    }
    public int getRows(){
        return display.getRows();
    }
    public String getRowText(int row){
        return borderChar + display.getRowText(row)+ borderChar;
    }
}

//ConcreteDecorator角色
class FullBorder extends Border {
    public FullBorder(Display display) {
        super(display);
    }

    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }

    public int getRows() {
        return 1 + display.getRows() + 1 ;
    }

    public String getRowText(int row) {
        if (row == 0) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else if (row == display.getRows() + 1) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else {
            return "|" + display.getRowText(row - 1) + "|";
        }
    }

    private String makeLine(char ch,int count){
        StringBuffer buf = new StringBuffer();
        for(int i = 0 ;i<count;i++){
            buf.append(ch);
        }
        return buf.toString();
    }

在这里插入图片描述

总结

  • 符合开闭原则
  • 在装饰器模式中,装饰器与被装饰物具有一致性(具有相同的方法API),因此即使被装饰物 被 装饰器 装饰起来了,API也不会隐藏,依然可以调用方法。
  • 使用委托,使类之间弱关联
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑白程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值