Java——Java基础之设计模式篇:装饰者模式

1、需求

制作咖啡
1、咖啡的单品种类:Espresso(意大利浓咖啡)ShortBlackLongBlack(美式
咖啡)Decaf(无因咖啡)
2、可加的调料:MilkSoy(豆浆)Chocolate

2、方案一

枚举所有的咖啡方案,把所有的单品种类咖啡和加各种调料的可能的类都实现一遍。

public abstract class coffee {
    int price;
    public int cost() {
        return this.price;
    }
}
public class coffee_Espresso extends coffee {
}
public class coffee_ShortBlack extends coffee {
}
public class coffee_LongBlack extends coffee {
}
public class coffee_Decaf extends coffee {
}
public class coffee_Decaf_Milk extends coffee {
}
public class coffee_Decaf_Soy extends coffee {
}
public class coffee_Decaf_Chocolate extends coffee {
}
public class coffee_Decaf_Milk_Soy extends coffee {
}
...

3、方案二

上一个方案的复杂点在于如果有很多种调料,就需要把这些调料的所有排列组合都枚举一遍。所以直接在抽象类中设置相应的属性,判断有没有添加这些调料。这时,需要的类就减少到4种。

public abstract class coffee {
    int basicPrice;
    int milkPrice;
    int soyPrice;
    int chocolatePrice;
    int hasMilkSize;
    int hasSoySize;
    int hasChocolateSize;
    public int cost() {
        int totalPrice = this.basicPrice;
        totalPrice += hasMilk * milkPrice;
        totalPrice += hasSoy * soyPrice;
        totalPrice += hasChocolate * chocolatePrice;
        return totalPrice;
    }
}
public class coffee_Espresso extends coffee {
}
public class coffee_ShortBlack extends coffee {
}
public class coffee_LongBlack extends coffee {
}
public class coffee_Decaf extends coffee {
}

3、方案三

上一个方案尽管控制了类的数量,但是如果改变调料种类,还需要重新修改相关代码。所以,使用装饰器模式解决这一问题。

装饰器模式举例:送礼物

  • 主体:礼物本身,比如玩具、衣服、瓷器等
  • 包装:比如包装盒、彩带、贴纸等

将上述示例进一步抽象:

  • Component:主体
  • ConcreteComponent:具体的主体
  • Decorator:装饰(注意这里还包含组合关系
  • ConcreteDecorator:具体的装饰
    在这里插入图片描述

制作咖啡思路:咖啡和调料都算饮料,主体是饮料。饮料到单品咖啡之间增加过渡层咖啡。

在这里插入图片描述
需求:ShortBlack咖啡 + 牛奶 * 2 + 巧克力 * 1,花多少钱?此时只需要递归计算花多少钱。

在这里插入图片描述
代码实现

@Data
public abstract class Drink {
	private String des;//描述
	private float price = 0.0f;
	
	//计算费用的抽象方法
	//子类实现
	public abstract float cost();	
}

咖啡

@Data
public class Coffee extends Drink {
	@Override
	public float cost() {
		return super.getPrice();
	}
}

4种单品咖啡

public class Espresso extends Drink{
	public Espresso() {
		setDes("Espresso");
		this.setPrice(8.0f);
	}	
	@Override
	public float cost() {
		return getPrice();
	}
}
public class ShortBlack extends Drink{
	public ShortBlack() {
		setDes("ShortBlack");
		this.setPrice(10.0f);
	}	
	@Override
	public float cost() {
		return getPrice();
	}
}
public class LongBlack extends Drink{}
public class Decaf extends Drink{}

调料

public class Decorator extends Drink {
	private Drink obj;
	//组合Drink
	public Decorator(Drink obj) {
		this.obj = obj;
	}	
	@Override
	public float cost() {
		//getPrice()自己的价格
        //递归计算cost
		return super.getPrice() + obj.cost();
	}
	@Override
	public String getDes() {
		//输出被装饰者的信息
		return super.des + " " + super.getPrice() + " && " + obj.getDes();
	}
}

3种具体调料

public class Milk extends Decorator {
	public Milk() {
		super(obj);
		setDes("Milk");
		this.setPrice(3.0f);
	}	
	@Override
	public float cost() {
		return getPrice();
	}
}
public class Soy extends Decorator {}
public class Chocolate extends Decorator {}

如何使用呢?

public class CoffeeBar {
	public static void main(String[] args) {
		//点一杯美式咖啡
		Drink order = new LongBlack();
		//点牛奶调料
		order = new Milk(order);
		//点牛奶调料
		order = new Milk(order);
		//计算价格
		System.out.println(order.cost());
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值