装饰者模式
装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。
结构
- 抽象构件角色:使用抽象接口用来规范准备接受附加责任的对象。
- 具体构件角色:即被装饰的对象。
- 抽象装饰角色:继承或实现抽象构件,并包含具体构件的实例,子类扩展具体构件功能。
- 具体装饰角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
代码
package wnan.decorator.component;
/*****UTF-8*****
* Description: 快餐类 抽象构建角色
* Author: wnan
* Create Date: 2024/10/3 9:06
* Proverbs: 吃得苦中苦,方为人上人
*/
public abstract class FastFood {
private double price;
private String desc;
public FastFood(double price, String desc) {
this.price = price;
this.desc = desc;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
// 获得价格
public abstract double cost();
}
package wnan.decorator.component;
/*****UTF-8*****
* Description: 炒面 具体构件
* Author: wnan
* Create Date: 2024/10/3 9:34
* Proverbs: 吃得苦中苦,方为人上人
*/
public class FriedNoodles extends FastFood{
public FriedNoodles(){
super(12, "炒面");
}
@Override
public double cost() {
return getPrice();
}
}
package wnan.decorator.component;
/*****UTF-8*****
* Description: 炒饭类 具体构件角色
* Author: wnan
* Create Date: 2024/10/3 9:14
* Proverbs: 吃得苦中苦,方为人上人
*/
public class FrieRice extends FastFood{
public FrieRice(){
super(10, "炒饭");
}
@Override
public double cost() {
return getPrice();
}
}
package wnan.decorator.decorator_;
import wnan.decorator.component.FastFood;
/*****UTF-8*****
* Description: 抽象装饰角色
* Author: wnan
* Create Date: 2024/10/3 9:38
* Proverbs: 吃得苦中苦,方为人上人
*/
public abstract class Garnish extends FastFood {
private FastFood fastFood;
public Garnish(FastFood fastFood,double price,String desc){
super(price, desc);
this.fastFood=fastFood;
}
public FastFood getFastFood() {
return fastFood;
}
public void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}
}
package wnan.decorator.decorator_;
import wnan.decorator.component.FastFood;
/*****UTF-8*****
* Description: 鸡蛋 具体装饰角色
* Author: wnan
* Create Date: 2024/10/3 9:43
* Proverbs: 吃得苦中苦,方为人上人
*/
public class Egg extends Garnish {
public Egg(FastFood fastFood) {
super(fastFood,1,"鸡蛋");
}
@Override
public double cost() {
// 当前鸡蛋+拿来装饰的快餐=总价格
return getPrice()+getFastFood().cost();
}
@Override
public String getDesc(){
return super.getDesc()+getFastFood().getDesc();
}
}
package wnan.decorator.decorator_;
import wnan.decorator.component.FastFood;
/*****UTF-8*****
* Description: 培根 具体装饰角色
* Author: wnan
* Create Date: 2024/10/3 10:26
* Proverbs: 吃得苦中苦,方为人上人
*/
public class Bacon extends Garnish{
public Bacon(FastFood fastFood){
super(fastFood,2,"培根");
}
@Override
public double cost() {
return getPrice()+getFastFood().cost();
}
@Override
public String getDesc(){
return super.getDesc()+getFastFood().getDesc();
}
}
package wnan.decorator;
import wnan.decorator.component.FastFood;
import wnan.decorator.component.FrieRice;
import wnan.decorator.decorator_.Bacon;
import wnan.decorator.decorator_.Egg;
/*****UTF-8*****
* Description: 装饰者模式
* Author: wnan
* Create Date: 2024/10/2 14:12
* Proverbs: 吃得苦中苦,方为人上人
*/
public class Client {
public static void main(String[] args) {
FastFood rice = new FrieRice();
System.out.println(rice.cost());
System.out.println(rice.getPrice());
System.out.println(rice.getDesc());
FastFood rice_egg=new Egg(rice);
System.out.println(rice_egg.cost());
System.out.println(rice_egg.getPrice());
System.out.println(rice_egg.getDesc());
FastFood rice_egg_bacon = new Bacon(rice_egg);
System.out.println(rice_egg_bacon.cost());
System.out.println(rice_egg_bacon.getPrice());
System.out.println(rice_egg_bacon.getDesc());
}
}
运行结果:
10.0
10.0
炒饭
11.0
1.0
鸡蛋炒饭
13.0
2.0
培根鸡蛋炒饭
优点
- 低耦合:装饰类和被装饰类可以独立变化,互不影响。
- 灵活性:可以动态地添加或撤销功能。
- 替代继承:提供了一种继承之外的扩展对象功能的方式。