java设计模式—装饰者模式(Decorator Pattern)

最近在看IO流相关的内容,然后发现了IO的设计就大量使用了装饰者模式,因此,决定了解一下装饰者模式到底是什么东东?

一、概述

     装饰者模式属于一种结构型模式,结构型类模式采用继承机制来组合接口或实现。装饰者模式可以动态的给一个对象添加额外的职责,就增加功能来说,装饰者模式比生成子类更加灵活。

     类似于qq秀这种虚拟换装功能,各种服饰之间的搭配多种多样,如果增加子类,不仅会导致代码的冗余,也会增加系统复杂度。

二、结构

      

三、适用场景

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类的数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

四、简单小案例

     1. 房子装修小案例

      现在有一个房子需要装修,主题是房子,装修需要的材料有灯,沙发,电视,洗衣机等等。。这种情况下就可以使用装修者模式。

    首先定义房子的抽象基类:

package cn.hzr0523.decorator;

/**
 * 定义一个房子基类
 * hezhi
 * 2018/3/1 14:52
 */
public abstract class House {
    protected String name;

    public String getName() {
        return this.name;
    }

    public abstract double getPrice();
}

具体要装修的房子(我的房子):

package cn.hzr0523.decorator;

/**
 * 被装饰者的初始状态,初始花费0元
 * hezhi
 * 2018/3/1 14:54
 */
public class MyHouse extends House {

    public MyHouse() {
        name = "我的房子";
    }

    @Override
    public double getPrice() {
        return 0;
    }
}

 装修材料的抽象基类:    

package cn.hzr0523.decorator;

/**
 * 装修材料的基类
 * hezhi
 * 2018/3/1 14:59
 */
public abstract class DecoratorNeeded extends House{
    public abstract String getName();
}

具体的装修材料:

电视:

package cn.hzr0523.decorator;

/**
 * 电视
 * hezhi
 * 2018/3/1 15:01
 */
public class TVDeco extends DecoratorNeeded{
    House house;

    public TVDeco(House h) {
        this.house = h;
    }

    @Override
    public String getName() {
        return house.getName() + " 安装电视";
    }

    @Override
    public double getPrice() {
        return house.getPrice() + 4999;
    }
}

灯:

package cn.hzr0523.decorator;

/**
 * 灯
 * hezhi
 * 2018/3/1 15:04
 */
public class LightDeco extends DecoratorNeeded {
    House house ;

    public LightDeco(House h) {
        this.house = h;
    }

    @Override
    public String getName() {
        return house.getName() + " 安装灯";
    }

    @Override
    public double getPrice() {
        return house.getPrice() + 1000;
    }
}

沙发:

package cn.hzr0523.decorator;

/**
 * 沙发
 * hezhi
 * 2018/3/1 15:34
 */
public class SofaDeco extends DecoratorNeeded {
    House house;
    public SofaDeco(House h) {
        this.house = h;
    }

    @Override
    public String getName() {
        return house.getName() + " 安装沙发";
    }

    @Override
    public double getPrice() {
        return house.getPrice() + 3000;
    }
}

测试代码:

package cn.hzr0523.decorator;

/**
 * hezhi
 * 2018/3/1 15:13
 */
public class HouseDecorator {
    public static void main(String args[]) {
        House house = new MyHouse();
        DecoratorNeeded needed1 = new TVDeco(new LightDeco(house));
        DecoratorNeeded needed2 = new TVDeco(new LightDeco(new SofaDeco(house)));

        System.out.println(needed1.getName());
        System.out.println("装修花费:" + needed1.getPrice());

        System.out.println(needed2.getName());
        System.out.println("装修花费:" + needed2.getPrice());
    }
}

运行结果:


五、参与者

  • 抽象构件Component(House):定义一个对象接口,可以给这些对象动态的添加职责。
  • 具体构件ConcreteComponent(MyHouse):定义一个具体的对象,可以给这个对象添加一些职责。
  • 抽象装饰Decorator(DecoratorNeeded):持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
  • 具体装饰ConcreteDecorator(TvDeco):负责给构件对象添加上附加的责任。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值