结构型模式-装饰者模式
- 7.3装饰者模式:arrow_up::arrow_up::arrow_up:
- 7.3.1概念
- 7.3.2场景
- 7.3.3优势 / 劣势
- 7.3.4装饰者模式可分为
- 7.3.5装饰者模式
- 7.3.6实战
- 7.3.6.1题目描述
- 7.3.6.2输入描述
- 7.3.6.3输出描述
- 7.3.6.4代码
- 7.3.7总结
- 装饰者模式
7.3装饰者模式⬆️⬆️⬆️
7.3.1概念
装饰者模式通过在一个现有对象中,能动态的给该对象添加新的功能,同时不改变对象本身的结构,是继承的一种替代方案,可以实现在不定义子类的情况下,运行时动态地扩展对象的行为(给对象添加一些额外的功能),而无需修改原有代码。
7.3.2场景
当我们去一家咖啡店时,点了一杯咖啡。这时,你觉得咖啡有点苦,或者说咖啡的味道不够丰富,就可以给店员 / 咖啡师说,希望可以在我们的咖啡中添加糖、牛奶等不同的食材以此来丰富我们咖啡。这些食物都可以看作是装饰者,然后我们可以根据自己的具体口味,添加不同程度的以及不同风味的食材。
7.3.3优势 / 劣势
- 可扩展性:根据多个不同的装饰类来组合出不同功能,以此来装饰同一对象
- 灵活性:在不改变原有对象的基础上,动态的给对象添加新的功能
- 易于维护:由于装饰者模式的动态性,可以随时添加或删除装饰者,无需修改原有的代码
- 系统复杂度:因为装饰者模式需要创建更多的类和对象,会增加系统的复杂度
- 执行效率降低:装饰者模式是动态添加 / 删除的,可能会引入一些性能问题,最后导致执行效率降低
7.3.4装饰者模式可分为
- 组件Component:通常是抽象类或者接口,是具体组件和装饰者的父类,定义了具体组件需要实现的方法
- 具体组件ConcreteComponent:实现类Component接口的具体类,是被装饰的对象
- 装饰类:一个抽象类,给具体组件添加功能,但是具体的功能由其子类具体装饰者完成,持有一个指向Component对象的引用
- 具体装饰类ConcreteDecorator:扩展Decorator类,负责向Component对象添加新的行为,加牛奶的咖啡是一个具体装饰类,加糖的咖啡也是一个具体装饰类
7.3.5装饰者模式
package com.technologystatck.designpattern.mode.decoration;public class Decoration {public static void main(String[] args) {//创建具体组件ConcreteComponent concreteComponent = new ConcreteComponent();//使用具体装饰者装饰具体组件Decorator decorator = new ConcreteDecorator(concreteComponent);//调用方法decorator.operation();}
}//1.定义Component组件接口
interface Component{void operation();
}//2.实现ConcreteComponent具体组件
class ConcreteComponent implements Component{@Overridepublic void operation() {System.out.println("ConcreteComponent operation");}
}//3.定义抽象Decorator装饰类,继承自Component
abstract class Decorator implements Component{protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}//4.定义具体的装饰者实现,给具体组件对象添加功能
class ConcreteDecorator extends Decorator{public ConcreteDecorator(Component component) {super(component);}@Overridepublic void operation() {System.out.println("Before operation in ConcreteDecorator");super.operation();System.out.println("After operation in ConcreteDecorator");}
}
7.3.6实战
7.3.6.1题目描述
小明喜欢品尝不同口味的咖啡,他发现每种咖啡都可以加入不同的调料,比如牛奶、糖和巧克力。他决定使用装饰者模式制作自己喜欢的咖啡。
请设计一个简单的咖啡制作系统,使用装饰者模式为咖啡添加不同的调料。系统支持两种咖啡类型:黑咖啡(Black Coffee)和拿铁(Latte)。
7.3.6.2输入描述
多行输入,每行包含两个数字。第一个数字表示咖啡的选择(1 表示黑咖啡,2 表示拿铁),第二个数字表示要添加的调料类型(1 表示牛奶,2 表示糖)。
7.3.6.3输出描述
根据每行输入,输出制作咖啡的过程,包括咖啡类型和添加的调料。
7.3.6.4代码
package com.technologystatck.designpattern.mode.decoration;import java.util.Scanner;public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while(scanner.hasNext()){//咖啡类型int coffeeType = scanner.nextInt();//咖啡装饰类型int condimentType = scanner.nextInt();//根据选择制作不同的咖啡Coffee coffee=null;if(coffeeType ==1){coffee=new BlackCoffee();}else if(coffeeType ==2){coffee=new Latte();}else{System.out.println("Invald coffee type");continue;}//添加不同的食材if(condimentType == 1){coffee=new MilkDecorator(coffee);}else if(condimentType ==2){coffee=new SugarDecorator(coffee);}else{System.out.println("Invald condiment type");continue;}//输出制作过程coffee.brew();}}
}//抽象咖啡组件
interface Coffee{//制作咖啡的方法void brew();
}//具体的黑咖啡类
class BlackCoffee implements Coffee{@Overridepublic void brew() {System.out.println("Brewing Black Coffee");}
}//具体的拿铁咖啡类
class Latte implements Coffee{@Overridepublic void brew() {System.out.println("Brewing Latte Coffee");}
}//装饰者抽象类
abstract class AbstractDecorator implements Coffee{protected Coffee coffee;public AbstractDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic void brew() {coffee.brew();}
}//具体的牛奶装饰者类实现
class MilkDecorator extends AbstractDecorator{public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic void brew() {super.brew();System.out.println("Adding Milk");}
}class SugarDecorator extends AbstractDecorator{public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic void brew() {super.brew();System.out.println("Adding Sugar");}
}