23种设计模式之一— — — —装饰模式详细介绍与讲解

一、定义

装饰模式(别名:包装器)
装饰模式(Decorator Pattern)是结构型的设计模式,它允许在运行时动态地向对象添加新的职责或功能,同时保持对象的原始类不变。通过使用装饰器模式,可以在不修改现有代码的基础上扩展对象的功能,

二、装饰模式结构

核心思想

1.动态扩展:在不改变原类结构和继承关系的情况下,动态地为对象添加功能。
2.包装对象:通过创建一个包装对象(装饰器)来包裹真实对象,增加额外功能。
3.接口一致性:装饰器与真实对象有相同的接口,确保客户端能以相同的方式与两者交互。
4.开闭原则:对扩展开放,对修改关闭。新的功能通过添加装饰器实现,而不是修改原类。
5.灵活组合:允许通过组合多个装饰器来创建功能更为丰富的对象

模式角色

1.抽象组件(Component):定义一个接口,用于规范准备接收附加责任的对象(即被装饰对象)。
2.具体组件(ConcreteComponent):实现抽象组件接口,是装饰器要装饰的真实对象。
3.装饰器(Decorator):持有一个抽象组件的引用,并继承抽象组件的接口。它既可以使用所持有的引用调用被装饰的组件的方法,也可以增加新的功能。
4.具体装饰器(ConcreteDecorator):实现装饰器接口并给具体组件添加职责。它通常包含对具体组件的引用,以及一个或多个用于增加功能的额外方法。
这些角色在装饰模式中的交互方式是:

  • 抽象组件定义了所有装饰器对象和被装饰对象需要实现的接口。
  • 具体组件实现了抽象组件接口,是准备被装饰的对象。
  • 装饰器持有一个对抽象组件的引用,并且实现了抽象组件接口。它可以使用这个引用来调用被装饰对象的方法,并在调用前后添加新的功能。
  • 具体装饰器实现了装饰器接口,并且给具体组件添加新的职责。它通常包含一个指向被装饰对象的引用,以及用于实现附加功能的代码。

模式的UML类图

在这里插入图片描述

应用场景

  • 当需要为单个对象提供多种不同的行为或者表现形式时。
  • 需要向一个已经存在的类中添加功能,但又不希望修改该类的源代码或继承其子类时
  • 组合对象:当需要组合多个对象来创建一个具有更多功能的对象时,装饰模式是一个很好的选择。通过递归组合方式,可以构建出一个具有多种功能的对象。例如,在文件系统中,文件夹可以被视为一个特殊的文件,它可以包含其他文件和文件夹。使用装饰模式,可以将文件夹装饰为一个包含额外功能的对象,如支持加密、压缩等

模式优点

  • 动态地给对象添加功能,相比生成子类更加灵活、透明。
  • 无需修改原有类就可以扩展功能,符合开闭原则。
  • 装饰器可以被组合,以便在运行时动态地、多次地添加多个职责。

模式缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 不易调试:由于装饰器模式涉及到多个对象的交互,调试可能会变得相对困难。特别是当装饰器链很长时,追踪请求和响应的路径可能会变得复杂。

实例演示

图示

鸡腿堡应用:
在这里插入图片描述

代码演示

package ZhuangShiMoShi;

public abstract class Humburger {
	protected String name;

	public String getName() {
		return name;
	}

	public abstract double getPrice();

}

package ZhuangShiMoShi;

public class ChickenBurger extends Humburger {
	public ChickenBurger(){
		name="鸡腿堡";
	}
	public double getPrice(){
		return 10;
	}
	

}

package ZhuangShiMoShi;

public abstract class Condiment extends Humburger {
	protected Humburger humburger;
	public abstract String getName();

}

package ZhuangShiMoShi;

public class Chilli extends Condiment {
	public Humburger hum;

	public Chilli(Humburger hum) {
		this.hum = hum;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return hum.getName() + " 加辣椒";
	}

	@Override
	public double getPrice() {
		// TODO Auto-generated method stub
		return hum.getPrice();
	}

}

package ZhuangShiMoShi;

public class Lettuce extends Condiment {
	public Humburger hum;

	public Lettuce(Humburger hum) {
		this.hum = hum;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return hum.getName()+" 加生菜";
	}

	@Override
	public double getPrice() {
		// TODO Auto-generated method stub
		return hum.getPrice()+1.5;
	}

}


测试类:

package ZhuangShiMoShi;

public class Test {
	public static void main(String[] args) {
		Humburger hum = new ChickenBurger();
		System.out.println(hum.getName() + " 价钱:" + hum.getPrice());
		Lettuce lettuce=new Lettuce(hum);
		System.out.println(lettuce.getName()+" 价钱:"+lettuce.getPrice());
		Chilli chilli1=new Chilli(hum);
		System.out.println(chilli1.getName()+" 价钱:"+chilli1.getPrice());
		Chilli chilli2=new Chilli(lettuce);
		System.out.println(chilli2.getName()+" 价钱:"+chilli2.getPrice());
	}

}

运行结果

在这里插入图片描述

该代码主体是鸡腿堡,可以选择通过添加生菜、酱、辣椒等等许多其他的配料,并根据选择的配料计算相应的价格。
博主用心写,读者点关注;互动传真情,知识不迷路

相关推荐

  1. 23设计模式详细介绍

    2024-06-06 15:08:42       18 阅读
  2. 设计模式——23

    2024-06-06 15:08:42       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 15:08:42       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 15:08:42       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 15:08:42       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 15:08:42       20 阅读

热门阅读

  1. 设计模式之观察者模式

    2024-06-06 15:08:42       8 阅读
  2. Go语言 一些问题了解

    2024-06-06 15:08:42       8 阅读
  3. BMC压力测试脚本

    2024-06-06 15:08:42       9 阅读
  4. 短剧出海的第一桶金

    2024-06-06 15:08:42       8 阅读
  5. Python怎么睡觉:深入探索Python中的暂停执行机制

    2024-06-06 15:08:42       8 阅读
  6. npm如何发布自己的插件包

    2024-06-06 15:08:42       8 阅读
  7. phpword使用TemplateProcessor对模板进行替换

    2024-06-06 15:08:42       10 阅读
  8. 自动化迁移和更新物体检测XML数据集

    2024-06-06 15:08:42       8 阅读
  9. 03-3.1.2 栈的顺序存储的实现

    2024-06-06 15:08:42       10 阅读
  10. AJAX

    AJAX

    2024-06-06 15:08:42      8 阅读
  11. leetcode刷题

    2024-06-06 15:08:42       8 阅读