前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >装饰器和代理模式的区别,从一碗小米粥谈起

装饰器和代理模式的区别,从一碗小米粥谈起

作者头像
AlbertYang
发布2020-09-08 15:00:20
4130
发布2020-09-08 15:00:20
举报

代理与装饰器

场景描述

代理即代替意思,可替代原类的所有功能,即和原类实现相同的规范。代理模式和装饰器模式很像。

每天清晨起来,紧张的洗漱之后,来到楼下的早餐店,我通常都会要一碗小米粥,这时候盛粥的大姐姐通常会问一句加不加糖,我回答不加,这时候我就会得到一碗热腾腾香喷喷的小米粥。

基础实现

一个小米粥的接口:

publicinterface MilletCongee {

     /**

     * 打印小米粥中含有的成分

     */

    void printIngredient ();

}

默认的不加糖的小米粥的实现:

publicclass GeneralMilletCongee implements MilletCongee{
 
  @Override
  publicvoid printIngredient() {
    System.out.println("不加糖的小米粥,组成成分是小米和水");
  }
 
}

点餐:

publicclass Order{
 
  publicstaticvoid main(String[] args) {
    MilletCongee milletCongee=new GeneralMilletCongee();
    milletCongee.printIngredient();
  }
 
} 

一碗小米粥,不加糖:

装饰器模式

得到一碗热腾腾香喷喷的小米粥,尝了一口,感觉不是很好喝,接着又尝了一口,嗯感觉还是加点糖比较好,于是我又来到盛小米粥的大姐姐旁边,让她帮我加了点糖。

/**
 * 糖装饰器,用来给小米粥加糖
 */
publicclass SugarDecorator implements MilletCongee {
 
    /**
     * 拥有的小米粥对象
     */
    privatefinal MilletCongee milletCongee;
 
    public SugarDecorator(MilletCongee milletCongee) {
        this.milletCongee = milletCongee;
    }
 
  @Override
  publicvoid printIngredient() {
    System.out.println("糖");
        this.milletCongee.printIngredient();
  }
}

大姐姐把加好糖的小米粥重新递给了我,尝了一口,嗯真是香甜可口。

publicclass Order {
 
  publicstaticvoid main(String[] args) {
    MilletCongee milletCongee=new GeneralMilletCongee();
    milletCongee=new SugarDecorator(milletCongee);
    milletCongee.printIngredient();
   
  }
 
}

看了一下小米粥的成分,加上了糖。

注意这两行:

MilletCongeemilletCongee=new GeneralMilletCongee();//点了一碗小米粥
milletCongee=newSugarDecorator(milletCongee);//给小米粥加了点糖

装饰器模式适合什么场景呢?假设我有一个对象,但是这个对象的功能不能令我满意,我想给他加上一些功能,如何才能实现呢,那我就拿装饰器给他装饰一下就ok了。

代理模式

第二天早上,吃早餐的时候我又点了一碗小米粥,这时候盛粥的大姐姐抛出了昨天同样的问题给我,加不加糖?想起昨天的情景和味道,感觉还是加糖好一点,我干净利落的回答道,加。


publicclass MilletCongeeWithSugar implements MilletCongee {
   
    privatefinal MilletCongee milletCongee;
 
    publicMilletCongeeWithSugar() {
        this.milletCongee = new GeneralMilletCongee();
    }
   
    @Override
    publicvoid printIngredient() {
       System.out.println("糖");
        this.milletCongee.printIngredient();
    }
 
}

这是加糖的小米粥,内部仍然是普通的小米粥,加了糖之后就产生了一个新的种类,叫加糖的小米粥。

直接点加糖的小米粥:

publicclass Order {
 
  publicstaticvoid main(String[] args) {
    MilletCongee milletCongee=new MilletCongeeWithSugar();
    milletCongee.printIngredient();
  }
 
}

拿到加糖的小米粥尝了一口,嗯正合我意,香甜可口的一碗小米粥下肚,又是一个元气满满的早晨。

区别

装饰器模式和代理模式,都是对原对象进行包装,都需要用到原对象的实例,他们的区别主要在于对外的表现不同。

装饰器模式:点了小米粥,发现不好喝,然后用装饰器加了点糖。
MilletCongeemilletCongee=new GeneralMilletCongee();//点了一碗小米粥
milletCongee=newSugarDecorator(milletCongee);//给小米粥加了点糖
代理模式:直接就点加了糖的小米粥
MilletCongeemilletCongee=new MilletCongeeWithSugar();
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlbertYang 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础实现
  • 区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档