装饰者模式

装饰者模式,是在不改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

 

装饰者模式中的角色:

(1) 被装饰者抽象Component,是一个接口或抽象类,就是定义最核心的对象,也是最原始的对象,这个类是需要装饰类的基类。

(2) 被装饰者具体实现ConcreteComponent,是Component类的一个实现类,要装饰的就是这个具体的实现类。

(3) 装饰者Decorator,一般是一个抽象类,实现接口或者抽象方法,它里面有个指向Component的引用,而且它还继承了被装饰者的抽象Component。

(4) 装饰者实现ConcreteDecorator,具体的装饰者类。

 

类图|:

 

代码实现:

被装饰者的抽象:

package com.demo.decorator.component;

/*
 * 甜点类,被装饰者的抽象
 */
public abstract class Dessert {

	protected String description = "Unknown Dessert";
	
	/*
	 * 对甜点的描述,需要被装饰的方法
	 */
	public String getDescription() {
		return description;
	}
	
	public Dessert() {
	}
	
	/*
	 * 甜点的价格,需要被装饰的方法
	 */
	public abstract double cost();
	
}

被装饰者的具体实现:

package com.demo.decorator.component;

/*
 * 蛋糕类,被装饰者的具体实现
 */
public class Cake extends Dessert {

	public Cake() {
		description = "Cake";
	}
	
	@Override
	public double cost() {
		return 9.90;
	}

}
package com.demo.decorator.component;

/*
 * 面包类,被装饰者的具体实现
 */
public class Bread extends Dessert {

	public Bread() {
		description = "Bread";
	}
	
	@Override
	public double cost() {
		return 5.0;
	}
}

装饰者的抽象:

package com.demo.decorator.decorator;

import com.demo.decorator.component.Dessert;

/*
 * 佐料类,装饰者的抽象
 */
public abstract class CondimentDecorator extends Dessert {
	
	/*
	 * 被装饰者的引用
	 */
	protected Dessert dessert;
	
	public CondimentDecorator(Dessert dessert) {
		this.dessert = dessert;
	}
	
	public abstract String getDescription();
	public abstract double cost();
	
}

装饰者的具体实现:

package com.demo.decorator.decorator;

import com.demo.decorator.component.Dessert;

/*
 * 巧克力类,装饰者的具体实现
 */
public class Chocolate extends CondimentDecorator {

	public Chocolate(Dessert dessert) {
		super(dessert);
	}
	
	/*
	 * 通过被装饰者的引用,扩展其方法的功能
	 */
	@Override
	public String getDescription() {
		return dessert.getDescription() + ", Chocolate";
	}
	
	/*
	 * 通过被装饰者的引用,扩展其方法的功能
	 */
	@Override
	public double cost() {
		return dessert.cost() + 1.0;
	}

}
package com.demo.decorator.decorator;

import com.demo.decorator.component.Dessert;

/*
 * 蓝莓类,装饰者的具体实现
 */
public class Blueberry extends CondimentDecorator {

	public Blueberry(Dessert dessert) {
		super(dessert);
	}
	
	/*
	 * 通过被装饰者的引用,扩展其方法的功能
	 */
	@Override
	public String getDescription() {
		return dessert.getDescription() + ", Blueberry";
	}
	
	/*
	 * 通过被装饰者的引用,扩展其方法的功能
	 */
	@Override
	public double cost() {
		return dessert.cost() + 1.5;
	}
	
}

测试代码:

package com.demo.decorator;

import com.demo.decorator.component.Bread;
import com.demo.decorator.component.Cake;
import com.demo.decorator.component.Dessert;
import com.demo.decorator.decorator.Blueberry;
import com.demo.decorator.decorator.Chocolate;

public class MainApp {
	
	public static void main(String[] args) {
		
		/*
		 * 未被装饰的蛋糕
		 */
		Dessert cake = new Cake();
		show(cake);
		
		/*
		 * 被巧克力装饰的蛋糕
		 */
		Dessert chocolateCake = new Cake();
		chocolateCake = new Chocolate(chocolateCake);
		show(chocolateCake);

		/*
		 * 被巧克力和蓝莓装饰的面包
		 * 被装饰者可以被多个装饰者装饰
		 */
		Dessert blueberryChocolateBread = new Bread();
		blueberryChocolateBread = new Chocolate(blueberryChocolateBread);
		blueberryChocolateBread = new Blueberry(blueberryChocolateBread);
		show(blueberryChocolateBread);
		
	}
	
	public static void show(Dessert dessert) {
		System.out.println(dessert.getDescription() +
				"   ¥" + dessert.cost());
	}
}

结果输出:

Cake   ¥9.9
Cake, Chocolate   ¥10.9
Bread, Chocolate, Blueberry   ¥7.5


 

使用装饰者模式的适用场合:

1) 当需要为某个现有的对象动态地增加一个新的功能或职责时,可以考虑使用装饰者模式;

2) 当某个对象的职责经常发生变化或者经常需要动态地增加职责,避免为了适应这样的变化而增加继承子类扩展的方式;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值