动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

Java装饰者模式

03-29 16:53 493浏览
举报 T字号
  • 大字
  • 中字
  • 小字

优点:它可以动态为对象添加功能。

场景:我们希望为某个对象而不是整个类添加一些功能。

1.角色及作用

装饰者和被装饰者拥有相同的组件接口。被装饰者是系统的核心组件,完成特定功能。装饰者则可以在被装饰者的方法前后,加上特定的前置处理和后置处理,增强被装饰者的功能(怎么和代理模式好像!_!,一脸懵逼)

角色 作用
组件接口 为装饰者和被装饰者的超类或接口。定义被装饰者的核心功能,以及装饰者需要加强的功能
具体组件(被装饰者) 实现组件接口的的核心方法,完成具体业务逻辑
装饰者 实现组件接口,持有一个被装饰对象
具体装饰者 具体实现装饰的业务逻辑。各个具体装饰者是可以相互叠加的

2.装饰者模式

场景:奶茶哥哥的奶茶店开张了,我们推出了两种产品—奶茶和茶叶茶。我们的饮料需要实现自己的描述和自己的价格。

// 饮料的基类(组件接口)
public interface Beverage {

    public String getDescription();

    public double cost();
}
// 奶茶(被装饰者)
public class Milk implements Beverage {


    @Override
    public double cost() {
        return .56;
    }

    @Override
    public String getDescription() {
        return "Milk";
    }
}
// 茶叶茶(被装饰者)
public class Tea implements Beverage {
    
    @Override
    public double cost() {
        return 1.44;
    }

    @Override
    public String getDescription() {
        return "Tea";
    }

}

奶茶店开张后,我们的饮料很畅销,但是没有新的产品是无法满足客户的。于是,我们研制了调料,让我们的饮料喝起来味道更好。

/ 调料的基类(装饰者)
public abstract class CondimentDecorator implements Beverage {

    Beverage beverage;

    public CondimentDecorator(Beverage beberage) {
        this.beverage = beberage;
    }

}
// 抹茶粉(具体装饰者)
public class Matcha extends CondimentDecorator {


    public Matcha(Beverage beberage) {
        super(beberage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",Matcha";
    }

    @Override
    public double cost() {
        return .5 + beverage.cost();
    }

}
// 珍珠(具体装饰者)
public class Pearl extends CondimentDecorator {


    public Pearl(Beverage beberage) {
        super(beberage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",Pearl";
    }

    @Override
    public double cost() {
        return .2 + beverage.cost();
    }

}

现在我们提供奶茶的方法如下:

   public static void main(String[] args) {
    Beverage be = new Tea();
    System.out.println(be.getDescription() + "---" + be.cost());
    Beverage b2 = new Pearl(new Milk());
    System.out.println(b2.getDescription() + "---" + b2.cost());
    b2 = new Matcha(b2);
    System.out.println(b2.getDescription() + "---" + b2.cost());
}

输出如下:

Tea---1.44Milk,
Pearl---0.76Milk,
Pearl,Matcha---1.26

可见,我们根据所需要的饮料和调料,奶茶哥哥就提供对应的饮料和价格数据。

3.装饰者模式和代理模式的区别

首先,这两个模式真心在实现上太像了,都是对业务处理的前后增加前置后置的实现。网上找了很多人对这两者的理解,这里总结下我的看法。

装饰模式:

  • 以对客户端透明的方式扩展对象的功能
  • 可以说是继承关系的一个替代方案
  • 用户更关心装饰后的功能

比如上面的奶茶,用户希望得到的是—奶茶+珍珠+抹茶,以及他们的总价

代理模式:

  • 代理模式对代理的对象施加控制,并不提供对象本身的增强功能
  • 用户通过代理来访问目标的功能,使用者关心的是原始功能都有什么功能,而对于代理的时候的处理却不知道
0人推荐
共同学习,写下你的评论
0条评论
我是码农
程序员我是码农

25篇文章贡献87343字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

提枪策马乘胜追击04-21 20:01

Spring常见面试题

代码小兵92504-17 16:07

Java零基础实战项目——五子棋

代码小兵98804-25 13:57

Java string类详解

杨晶珍05-11 14:54

6道经典算法面试题

杨晶珍05-12 16:39

发评论

举报

0/150

取消