装饰器模式

定义

在不改变原有对象的基础上,将功能附加到对象上(提供了比继承更有弹性的替代方案,属于结构型模式)

先来看结构图:

 装饰器四个角色:

  • Component(被装饰对象基类):定义对象的接口,可以给这些对象动态增加职责。
  • ConcreteComponent(具体被装饰对象):定义具体的对象,Decorator可以给它增加额外的职责。
  • Decorator(装饰器抽象类):维护指向Component实例的引用,定义与Component一致的接口(也就是要继承或实现的被装饰对象基类),具体装饰由其子类实现。
  • ConcreteDecorator(具体装饰者):具体的装饰对象,Decorator的子类,给内部持有的具体被装饰对象增加具体职责。

 其实代码逻辑十分简单,直接来情景模拟比较好理解:

现在酒店有服务员,服务员只会机械的在服务,为了提升业绩,要求每个服务员要微笑地服务。使用装饰器模式来实现此情景。

服务员的父接口Service,里面有service()方法

package com.zlfan.decorator;
/*
 * 相当于Component接口
 */
public interface Service {
	void service();
}

服务员

package com.zlfan.decorator;
/*
 * 相当于ConcreteComponent
 */
public class Waiter implements Service {

	@Override
	public void service() {
		System.out.println("在服务...");
	}

}

接下来是装饰器模式的核心,内部维护了服务员,要被装饰的方法

package com.zlfan.decorator;
/*
 * 装饰抽象类,实现了Component,从外类来扩展Component类的功能,
 * 但对于Component来说,是无需知道Decorator存在的。
 */
public abstract class WaiterDecorator implements Service {

	Service service;
	
	public WaiterDecorator(Service service){
		this.service = service;
	}
	
	@Override
	public void service() {		
		service.service();
	}

}

接下来我们就可以通过继承上面的WaiterDecorator类来装饰service()方法了

package com.zlfan.decorator;
/*
 * 额外给服务员添加微笑   相当于ConcreteDecorator
 */
public class SmileWaiter extends WaiterDecorator{

	public SmileWaiter(Service service) {
		super(service);		
	}
	@Override
	public void service() {
		System.out.println("装饰:微笑");
		super.service();
	}
}

注意上面的service()方法中,我给他增加了  微笑  ,然后才调用了内部维护的服务员的service()。也就是给他增加了额外的功能

测试类

package com.zlfan.decorator;

public class Test {

	public static void main(String[] args) {
		Service sv = new Waiter();
		sv.service();
		System.out.println("-----装饰后------");
		Service svm = new SmileWaiter(new Waiter());
		svm.service();
	}
}

运行结果

在服务...
-----装饰后------
装饰:微笑
在服务...

装饰器模式的使用场景

在不影响其他对象的情况下,以动态的、透明的方式给单个对象添加职责。

  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量子类,使子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。

优缺点

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,可以动态扩展一个实现类的功能。符合开闭原则。

缺点:多层装饰比较复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值