【Java】装饰器模式

本文主要是介绍《【C++】装饰器模式》(点击打开链接)的Java版。关于什么是装饰器模式就不再赘述了,这次主要说明从UML类图是如何与代码联系起来的。

还是从2012年上半年软件设计师的软考题来说明这个例子。

题目是这样的:某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如下表所示。

咖啡有两种:蒸馏咖啡Espresso 25元/杯,深度烘焙咖啡DarkRoast 20元/杯

可以在咖啡里面加配料:摩卡Mocha 10元/份,奶泡Whip 8元/份

现采用装饰器模式Decorator模式来实现计算费用的功能,得到如图5-1所示的类图。


1、UML中,白色箭头代表继承关系,例如上图Espresso就继承了Beverage,从上述的UML可以看到,Beverage是所有类的父类,然而题目在Beverage类中定义了类成员,也出先有代码体的getDescription(),因此注定Beverage只可能是抽象类abstract而不是接口。而int cost()方法不想在此类给出相应的实现,因此必须定义为抽象方法。

2、CondimentDecorator的分析从下面已经给出的Mocha与Whip入手,因为其子类Mocha与Whip的构造方法出现了CondimentDecorator的父类——Beverage中没有的Beverage beverage,因此其CondimentDecorator必须有一个Beverage beverage;定义,而Beverage中存在的方法与声明,就无须再写了。

3、最后,本题询问主函数的构造函数是如何的。没什么好说的,就是根据类中定义的方法,传入正确的参数。

就可以达到了最终的层层叠加的装饰器模式目的。

具体实现代码如下所示:

abstract class Beverage { // 饮料
	String description = "Unknown Beverage";

	public String getDescription() {
		return description;
	}

	public abstract int cost();
}

abstract class CondimentDecorator extends Beverage { // 配料
	Beverage beverage;
}

class Espresso extends Beverage { // 蒸馏咖啡
	private final int ESPRESSO_PRICE = 25;

	public Espresso() {
		description = "Espresso";
	}

	public int cost() {
		return ESPRESSO_PRICE;
	}
}

class DarkRoast extends Beverage { // 深度烘焙咖啡
	private final int DARKROAST_PRICE = 20;

	public DarkRoast() {
		description = "DarkRoast";
	}

	public int cost() {
		return DARKROAST_PRICE;
	}
}

class Mocha extends CondimentDecorator { // 摩卡
	private final int MOCHA_PRICE = 10;

	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Mocha";
	}

	public int cost() {
		return MOCHA_PRICE + beverage.cost();
	}
}

class Whip extends CondimentDecorator { // 奶泡
	private final int WHIP_PRICE = 8;

	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Whip";
	}

	public int cost() {
		return WHIP_PRICE + beverage.cost();
	}
}

public class Coffee {
	public static void main(String args[]) {
		Beverage beverage = new DarkRoast();
		beverage = new Mocha(beverage);
		beverage = new Whip(beverage);
		System.out.println(beverage.getDescription() + "¥" + beverage.cost());
	}
}

运行的结果为:


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,根据您的需求,以下是一个简单的装饰器模式的实现,用于计算咖啡店销售咖啡的费用: 首先,我们需要定义一个基础的咖啡接口,用于表示咖啡的基本属性和价格: ```java public interface Coffee { double getCost(); // 获取咖啡的价格 String getDescription(); // 获取咖啡的描述 } ``` 然后,我们需要实现一个具体的咖啡类,用于表示咖啡的种类和基本价格: ```java public class Espresso implements Coffee { @Override public double getCost() { return 1.99; } @Override public String getDescription() { return "Espresso"; } } ``` 接下来,我们需要定义一个装饰器抽象类,用于表示各种配料的基本属性和价格: ```java public abstract class CoffeeDecorator implements Coffee { protected Coffee coffee; public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; } public double getCost() { return coffee.getCost(); } public String getDescription() { return coffee.getDescription(); } } ``` 最后,我们可以实现各种具体的装饰器类,用于表示各种不同的配料和对应的价格: ```java public class Milk extends CoffeeDecorator { public Milk(Coffee coffee) { super(coffee); } public double getCost() { return coffee.getCost() + 0.5; } public String getDescription() { return coffee.getDescription() + ", Milk"; } } public class Sugar extends CoffeeDecorator { public Sugar(Coffee coffee) { super(coffee); } public double getCost() { return coffee.getCost() + 0.3; } public String getDescription() { return coffee.getDescription() + ", Sugar"; } } public class Cream extends CoffeeDecorator { public Cream(Coffee coffee) { super(coffee); } public double getCost() { return coffee.getCost() + 0.7; } public String getDescription() { return coffee.getDescription() + ", Cream"; } } ``` 使用时,我们可以通过组合各种装饰器类,来实现不同种类咖啡的价格计算: ```java Coffee coffee = new Espresso(); coffee = new Milk(coffee); coffee = new Sugar(coffee); System.out.println(coffee.getDescription() + ": $" + coffee.getCost()); ``` 输出结果为: ``` Espresso, Milk, Sugar: $2.29 ``` 这样,我们就使用装饰器模式实现了咖啡店计算咖啡价格的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值