Java设计模式之装饰者设计模式Decorator Pattern


目录

一、基本概念

二、结构

1.图示

三、案例演示

被装饰对象的基类     一个接口  有cost()和description()两个抽象方法

具体被装饰的对象     实现上面这个接口

装饰者抽象类  (基类)  实现drink接口

具体的装饰者类    ------  糖

具体装饰者类   ----  黑豆

测试

结果:

四、设计原则

总结

一、基本概念

装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

运用场景

装饰者模式的应用场景:在不改变原有类结构的基础上,新增,限制,或者改造功能。

动态地将功能附加到对象身上。扩展功能,装饰者提供了比继承更有弹性的替代方案,可以防止类爆炸。

二、结构

1.图示

这是一张很经典的图:

Component:被装饰对象的基类   

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

ConcreteComponent:具体被装饰的对象

定义具体的对象,Decorator可以给它增加额外的功能

Decorator:装饰者抽象类

维护指向Component实例的引用,定义Component一致的接口

ConcreteDecorator 具体装饰者

具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责

三、案例演示

被装饰对象的基类     一个接口  有cost()和description()两个抽象方法

public interface Drink {
    float cost();//价格
    String description();// 描述
}

具体被装饰的对象     实现上面这个接口

package com.example.lib4;
/**
 * 被装饰的类
 * 豆浆
 * @author lzy
 * @deprecated
 * */
public class SoyaBeanMilk implements Drink{
    @Override
    public float cost() {
        return 10f;
    }

    @Override
    public String description() {
        return "纯豆浆";
    }
}

装饰者抽象类  (基类)  实现drink接口

public abstract class Decorator implements Drink {
    private Drink drink;
    public  Decorator(Drink drink){
        this.drink = drink;
    }

    @Override
    public float cost() {
        return drink.cost();
    }

    @Override
    public String description() {
        return drink.description();
    }
}

具体的装饰者类    ------  糖

public class SugarDecorator extends Decorator{
    public SugarDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public float cost() {
        return super.cost()+1.0f;
    }

    @Override
    public String description() {
        return super.description()+"糖";
    }
}

具体装饰者类   ----  黑豆

public class BlacbeanDecorator extends Decorator{
    public BlacbeanDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public float cost() {
        return super.cost()+2.0f;
    }

    @Override
    public String description() {
        return super.description()+"黑豆";
    }
}

测试


public class test {
    public static void main(String[] args) {
        Drink drink = new SoyaBeanMilk();  //纯豆浆(被装饰)    cost()  10f  description 纯豆浆
        SugarDecorator sugar = new SugarDecorator(drink);  //装饰者   继承Decorator        cost() +1.f   description  糖
        BlacbeanDecorator blackbean = new BlacbeanDecorator(sugar);//装饰者
        System.out.println("你点的豆浆是"+blackbean.description());
        System.out.println("花了"+blackbean.cost());
        /**
         * Decorator  装饰者抽象类    传入drink对象  然后重写cost()    description()方法
         *
         * 对类理解的不是很继承 抽象类 理解不是很好
         * */
    }
}

结果:

 这个案例的背景是      豆浆有很多口味的豆浆 ,有加糖的,加黑豆的 ,纯豆浆,又加糖又加黑豆的,等等 ,如果采用继承来添加这些功能,那可能子类太多了,类爆炸,不利于开发。所以采用设计者模式来代替类的继承。

再加一个小例子

File file = new File("D:\\io\\lzy1.txt");
        OutputStream out = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(out);
        DataOutputStream dos = new DataOutputStream(bos);

是不是很熟悉,其实已经在不知不觉已经使用过装饰者设计模式了。

四、设计原则

要使用装饰者模式,需要满足以下设计原则:

(1)封装变化多

(2)用组合,少用继承

(3).针对接口编程,不针对实现编程

(4)开放-关闭原则:类应该对扩展开放,对修改关闭

(5)为交互对象之间的松耦合设计而努力


总结

优点:

(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性

(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难

tip:这个例子来源于Java之io的学习整理

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值