常用设计模式之装饰者模式(Decorator Pattern)+java小示例

概念:装饰者模式动态的将责任附加到对象身上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案

正文

问题:
我们需要了解一个人今天的穿着,并且计算他今天的穿着一共花了多少钱。

继承解决方案:
我们定一个父类,再定义一些穿着,比如帽子,球鞋等等,这些要定义成布尔值变量。然后提供一个计算一身穿着的方法,判断帽子,球鞋等等是否穿了,如果布尔值是true就相加。
对于子类,他有可能是一个学生,本身的校服也算钱,然后重写父类计算方法,把校服加进去,如果今天带帽子了,我就把帽子布尔值设为true。
很明显的问题在于,如果运动员,白领,工人,司机等等职业加进来,继承体系非常臃肿,如果我们要再加一个装饰,比如墨镜,就需要修改父类方法,这些就造成我们必须要随时修改代码。
装饰者模式解决方案:
我们先定一个抽象的被装饰父类,让装饰者和被装饰者都继承它

public abstract class Man {

	protected String name;

	protected double price;

	//名称
	public String getName() {
		return name;
	}
	//价格
	public double getPrice() {
		return price;
	}
	//穿着
	public abstract  String getDecorate();


}

我们定义装饰者父类,让它继承基类

public abstract class Decorate extends Man{

	public abstract double getPrice();

	public abstract String getName();
}

这里可能不太理解,为什么装饰者父类要继承基类,我的理解是,装饰者需要装饰对象,把被装饰者父类的name和price重新再装饰一下,所以需要继承你的方法,我给你装饰一下。
装饰者具体实现类

public class Hat extends Decorate{

	Man man;

	public Hat(Man man) {
		this.man = man;
	}

	@Override
	public double getPrice() {
		return man.getPrice()+30.00;
	}

	@Override
	public String getDecorate() {
		return man.getDecorate()+"阿迪的帽子";
	}

	@Override
	public String getName() {
		return man.getName();
	}
}
public class Shoes extends Decorate{

	Man man;

	public Shoes(Man man) {
		this.man = man;
	}

	@Override
	public double getPrice() {
		return man.getPrice()+10.00;
	}

	@Override
	public String getName() {
		return man.getName();
	}

	@Override
	public String getDecorate() {

		return man.getDecorate()+"耐克的球鞋";
	}
}

装饰者类是具体实现装饰者父类,每个装饰者类都直接引用被装饰者父类,然后进项装饰。
被装饰者具体实现类

public class Player extends Man{

	public Player() {
		this.name = "运动员";
		this.price = 100.00;
	}

	@Override
	public String getDecorate() {

		return "运动服";
	}
}
public class Student extends Man{

	public Student() {
		this.name = "学生";
		this.price = 0.00;
	}

	@Override
	public String getDecorate() {

		return "校服";
	}
}

客户端代码:

public class Client {


	public static void main(String[] args) {
		//这里引入被装饰者,然后一层一层进行装饰,很神奇
		Man student = new Student();
		student = new Shoes(student);
		student =new Hat(student);
		System.out.println(student.getName()+"穿着是:"+student.getDecorate()+"一共花了"+student.getPrice());

		Man player = new Player();
		player = new Shoes(player);
		System.out.println(player.getName()+"穿着是:"+player.getDecorate()+"一共花了"+player.getPrice());
	}

}

输出:

学生穿着是:校服耐克的球鞋阿迪的帽子一共花了40.0
运动员穿着是:运动服耐克的球鞋一共花了110.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农业路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值