为了账号安全,请及时绑定邮箱和手机立即绑定
首页 手记 【九月打卡】第16天+ 装饰者模式

【九月打卡】第16天+ 装饰者模式

2022.09.20 21:14 32浏览

课程名称:Java设计模式精讲 Debug方式+内存分析

课程章节:第11章 装饰者模式讲解+Coding+源码解析

主讲老师:Geely

课程内容:

问题1)定义和作用,实现方式?

不改变原有对象基础之上,将功能附加到对象上

提供了比继承更有弹性的替代方案(扩展原有对象功能上) 1,**作用:**现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

**2,****具体操作:**装饰者类和被装饰者都继承被装饰者抽象类。被装饰抽象类作为成员变量传入装饰者类中(通过构造器), 这样就是可以在装饰者类中操作被装饰对象。

_装饰模式实现方式:_A接口和A接口实现, B装饰器抽象类实现A接口(引入接口引用),B实现类实现A装饰抽象类(调用A接口的实现方法做扩展)

3,包含的类和接口;

装饰器模式主要包含以下角色:

1.抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

2.具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。

3.抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

4.具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

简化理解:

1,A接口 2,实现A接口类 3,B抽象实现接口类(接口引用,要求传入实现类) 4,实现B抽象类 (传入实现类,调用实现类方法 + 附加功能)

问题2)使用场景?

扩展一个类的功能或给一个类添加附加职责。

动态的给一个对象添加功能,这些功能可以再动态的撤销。

场景:买煎饼可以加鸡蛋,加香肠。要一个加三个鸡蛋和两个香肠的煎饼,使用继承就得创建(三个鸡蛋和两个香肠的煎饼子类)一个子类进行实现,而装饰器只需要创建一个鸡蛋子类和香肠子类。

问题3)优点和缺点?

优点第五条是主要的优点: 1, 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用 2,通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果 3,装饰器模式完全遵守开闭原则 4, 扩展一个类的功能,动态增加功能,动态撤销。 5**,为什么继承无法实现的要用装饰,例如:鸡蛋煎饼,接口是煎饼,煎饼实现类加了一个鸡蛋,若加2个鸡蛋,就要再做一个实现类,加三个又是一个实现类,加两根辣条,加三根辣条。装饰:只需要实现煎饼接口,加几个鸡蛋和几根辣条都是可以直接添加,不需要继承实现更多子类**

缺点:

1,子类增多

2,动态装饰时候,多层装饰时会更复杂。

问题4)装饰者和代理模式,装饰者和适配器模式区别?

装饰者模式和代理模式:装饰者模式关注对象的动态添加方法。

代理模式关注控制对对象的访问。

**在使用上:**代理模式中的代理类创建被代理对象的实例,对于客户端代理对象是被代理类隐藏的。

装饰者模式是不隐藏被装饰类的,被装饰者作为构造器参数传入装饰类。

装饰者模式和适配器模式都是包装模式。

装饰者和被装饰者可以实现相同的接口。

适配器和被适配器是实现不同的接口。

图片描述

问题5)装饰者模式的例子?

**场景:买煎饼可以加鸡蛋,加香肠。**要一个加三个鸡蛋和两个香肠的煎饼,使用继承就得创建(三个鸡蛋和两个香肠的煎饼子类)一个子类进行实现,而装饰器只需要创建一个鸡蛋子类和香肠子类。

图片描述

public class decorateTest02 {
    public static void main(String[] args) {
        //来个炒面
        FastFood fastFood=new FriedNoodles();
        System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");

        //加个鸡蛋
        fastFood=new Egg(fastFood);
        System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");

        //再加个鸡蛋
        fastFood=new Egg(fastFood);
        System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");

        //再加个培根
        fastFood=new Bacon(fastFood);
        System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");

    }
}
//快餐接口--抽象类或接口实现都可以
  abstract class FastFood {
    private float price;
    private String desc;

      FastFood() {
    }

      FastFood(float price, String desc) {
        this.price = price;
        this.desc = desc;
    }

      void setPrice(float price) {
        this.price = price;
    }

      float getPrice() {
        return price;
    }

      String getDesc() {
        return desc;
    }

      void setDesc(String desc) {
        this.desc = desc;
    }

      abstract float cost();  //获取价格
}

//炒饭
  class FriedRice extends FastFood {

      FriedRice() {
        super(10, "炒饭");
    }

      float cost() {
        return getPrice();
    }
}

//炒面
  class FriedNoodles extends FastFood {

      FriedNoodles() {
        super(12, "炒面");
    }

      float cost() {
        return getPrice();
    }
}

/**
 * 抽象装饰
 * 即继承自FastFood,又聚合FastFood
 */
  abstract class Garnish extends FastFood{
    private FastFood fastFood;

      Garnish() {
    }

      FastFood getFastFood() {
        return fastFood;
    }

      void setFastFood(FastFood fastFood) {
        this.fastFood = fastFood;
    }

      Garnish(FastFood fastFood,float price, String desc) {
        super(price, desc);
        this.fastFood = fastFood;
    }
}


  class Egg extends Garnish{
      Egg(FastFood fastFood) {
        super(fastFood, 2, "鸡蛋");
    }

    @Override
      float cost() {
        return getPrice()+getFastFood().cost();
    }

    @Override
      String getDesc() {
        String str1=super.getDesc();
        String str2=getFastFood().getDesc();
        return str1+str2;
    }
}

  class Bacon extends Garnish{

      Bacon(FastFood fastFood) {
        super(fastFood, 5, "培根");
    }

      float cost() {
        return getPrice()+getFastFood().cost();
    }

    @Override
      String getDesc() {
        return super.getDesc()+getFastFood().getDesc();
    }
}

问题6)装饰者模式在jdk源码中的应用?

Decorator肯定是装饰者模式、

但是wrapper有可能是适配器模式也有可能是装饰者模式。要看类当中的具体实现。

因为两个设计模式都叫包装类模式。

点击查看更多内容
0人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1
获赞与收藏
5

关注TA,一起探索更多经验知识

同主题相似文章浏览排行榜

风间影月说签约讲师

50篇手记,涉及Java、MySQL、Redis、Spring等方向

进入讨论

Tony Bai 说签约讲师

146篇手记,涉及Go、C、Java、Python等方向

进入讨论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消