首页 > 其他分享 >装饰者模式

装饰者模式

时间:2022-12-16 23:34:06浏览次数:35  
标签:FastFood float fastFood 模式 public 装饰 desc

装饰者模式

不改变现有对象的结构的情况下, 动态地给该对象增加一些职责(额外功能)的模式

结构

  • 抽象构件: 定义一个抽象接口以规范准备接受附加责任的对象

  • 具体构件: 实现抽象构件, 通过装饰角色为其添加一些职责

  • 抽象装饰: 实现或继承抽象构件, 并包含具体构件的实例, 可以通过其子类扩展具体构件的功能

  • 具体装饰角色: 实现抽象装饰类的相关方法, 并给具体构件对象添加附加的责任

案例

我们使用装饰者模式对快餐店案例进行改进,体会装饰者模式的精髓。

代码如下:

//快餐接口
public abstract class FastFood {
    private float price;
    private String desc;
​
    public FastFood() {
    }
​
    public FastFood(float price, String desc) {
        this.price = price;
        this.desc = desc;
    }
​
    public void setPrice(float price) {
        this.price = price;
    }
​
    public float getPrice() {
        return price;
    }
​
    public String getDesc() {
        return desc;
    }
​
    public void setDesc(String desc) {
        this.desc = desc;
    }
​
    public abstract float cost();  //获取价格
}
​
//炒饭
public class FriedRice extends FastFood {
​
    public FriedRice() {
        super(10, "炒饭");
    }
​
    public float cost() {
        return getPrice();
    }
}
​
//炒面
public class FriedNoodles extends FastFood {
​
    public FriedNoodles() {
        super(12, "炒面");
    }
​
    public float cost() {
        return getPrice();
    }
}
​
//配料类
public abstract class Garnish extends FastFood {
​
    private FastFood fastFood;
​
    public FastFood getFastFood() {
        return fastFood;
    }
​
    public void setFastFood(FastFood fastFood) {
        this.fastFood = fastFood;
    }
​
    public Garnish(FastFood fastFood, float price, String desc) {
        super(price,desc);
        this.fastFood = fastFood;
    }
}
​
//鸡蛋配料
public class Egg extends Garnish {
​
    public Egg(FastFood fastFood) {
        super(fastFood,1,"鸡蛋");
    }
​
    public float cost() {
        return getPrice() + getFastFood().getPrice();
    }
​
    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
}
​
//培根配料
public class Bacon extends Garnish {
​
    public Bacon(FastFood fastFood) {
​
        super(fastFood,2,"培根");
    }
​
    @Override
    public float cost() {
        return getPrice() + getFastFood().getPrice();
    }
​
    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
}
​
//测试类
public class Client {
    public static void main(String[] args) {
        //点一份炒饭
        FastFood food = new FriedRice();
        //花费的价格
        System.out.println(food.getDesc() + " " + food.cost() + "元");
​
        System.out.println("========");
        //点一份加鸡蛋的炒饭
        FastFood food1 = new FriedRice();
​
        food1 = new Egg(food1);
        //花费的价格
        System.out.println(food1.getDesc() + " " + food1.cost() + "元");
​
        System.out.println("========");
        //点一份加培根的炒面
        FastFood food2 = new FriedNoodles();
        food2 = new Bacon(food2);
        //花费的价格
        System.out.println(food2.getDesc() + " " + food2.cost() + "元");
    }
}

好处:

  • 装饰者模式可以比继承更加灵活的功能, 使用更加方便, 可以通过组合不同的装饰者对象来获取具有不同行为的状态的多样化结构, 装饰者比继承更具良好的扩展性, 完美的遵循开闭原则, 继承是静态的附加责任, 装饰者则是动态的附加责任。

  • 装饰类和被装饰类可以独立发展, 不会相互耦合, 装饰模式是继承的一个替代模式, 装饰模式可以动态扩展一个实现类的功能

使用场景

  1. 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护

    • 系统中存在大量独立的扩展, 为支持每一种组合将产生大量的子类, 使子类数目呈爆炸式增长

    • 类定义final不能继承

  2. 不影响其他对象的情况下, 以动态、透明的方式给单个对象添加职责

  3. 对象的功能要求可以动态的添加, 也可以再动态的撤销时, 比如快餐店的鸡蛋卖完了, 直接把鸡蛋这个类给移除就OK

JDK源码解析

O流中的包装类使用到了装饰者模式。BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter。

我们以BufferedWriter举例来说明,先看看如何使用BufferedWriter

public class Demo {
    public static void main(String[] args) throws Exception{
        //创建BufferedWriter对象
        //创建FileWriter对象
        FileWriter fw = new FileWriter("C:\\Users\\Think\\Desktop\\a.txt");
        BufferedWriter bw = new BufferedWriter(fw);
​
        //写数据
        bw.write("hello Buffered");
​
        bw.close();
    }
}

BufferedWriter使用装饰者模式对Writer子实现类进行了增强,添加了缓冲区,提高了写数据的效率。

 

静态代理和装饰者的区别

相同点:

  • 都要实现与目标类相同的业务接口

  • 在两个类中都要声明目标对象

  • 都可以在不休该目标类的前提下增强目标方法

不同点:

  • 目的不同

    • 装饰者是为了增强目标对象

    • 静态代理是为了保护和隐藏目标对象

  • 获取目标对象构建的地方不同

    • 装饰者是由外界传递进来, 可以通过构造方法传递

    • 代理是在代理类的内部创建, 以此来隐藏目标对象

标签:FastFood,float,fastFood,模式,public,装饰,desc
From: https://www.cnblogs.com/phonk/p/16988489.html

相关文章

  • 设计模式--行为型模式
    行为型模式模板模式在含有继承结构的代码中,模板方法模式是非常常用的。用一个统一的父类实现定义所有的方法和接口。不同的子类来完成自己具体的实现。父类定义了骨架(调......
  • 设计模式--创建型模式
    创建型模式      创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是new一个对象,然后set相关属性。但是,在很多场景下,我们需要给客户端提供更加友......
  • 设计模式--结构型模式
    结构型模式建型模式介绍了创建对象的一些设计模式,这节介绍的结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展。代理模式第一个要介绍的代......
  • 25selenium的无头模式,线程池,随机ua
    1.selenium的无头模式,后期有需要可直接提取#实现无可视化界面fromselenium.webdriver.chrome.optionsimportOptions#实现无头模式的操作chrome_options=Optio......
  • USSD模式
    USSD(UnstructuredSupplementaryServiceData)即非结构化补充数据业务,是一种新型基于GSM网络的交互式数据业务。当你使用手机键盘输入一些网络已预先制定的数字或者符号比......
  • python 装饰器(二)
         ......
  • 适配器模式--学习
    适配器模式​ 将一个已有的服务器端应用接口转换成一个客户端程序所期望的接口。模式涉及的角色有目标接口(ITarget):所期待的接口,这里是类适配器模式,因此目标不可以是类......
  • 我学设计模式 之 观察者模式
      观察者(Observer)模式1.观察者模式介绍      观察者模式是对象行为模式,又叫做发布-定义模式、模型-视图模式、源-监听器模式或从属者模式。       观察......
  • Docker网络模式
    一、docker网络概述1、docker网络实现的原理Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP......
  • 当被问到类装饰器,那么是指装饰类的装饰器,还是类本身作为装饰器来用?
    装饰器装饰器:写代码要遵循开放封闭原则,装饰器本质是一个嵌套函数(被套着的函数就是闭包),它可以让被装饰函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是......