设计模式学习笔记---装饰模式decorator(Java版)

一、场景

增加车的功能

二、实质

动态的为一个对象增加新的功能,是一种用于代替继承的技术,无须通过继承增加新的子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。


三、实现细节

Component抽象构件角色

真实对象与装饰对象有相同的接口,这样客户端对象就能够以与真实对象相同的方式同装饰对象交互。

ConcreteComponent具体构件角色(真实对象

Decorator装饰角色

持有一个抽象构件的引用,装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样就能在真实对象调用前后增加新的功能。

ConcreteDecorator具体装饰角色

负责给构件对象增加新的责任。

四、示例

实例1


package IOOthers;

public class Voice {
	private int voice = 10;
	public Voice() {
	}
	public Voice(int voice) {
		super();
		this.voice = voice;
	}
	public int getVoice() {
		return voice;
	}
	public void setVoice(int voice) {
		this.voice = voice;
	}
	public void say()
	{
		System.out.println(voice);
	}
}


class Amplifier {
	private Voice voice;
	public Amplifier() {
	}	
	public Amplifier(Voice voice) {
		super();
		this.voice = voice;
	}
	public void say()
	{
		System.out.println(voice.getVoice()*1000);
	}
}


package IOOthers;

/**
 * 扩音器
 * 类与类之间的关系
 * 1、依赖:形参|局部变量
 * 2、关联:属性
 * 			聚合:属性  整体与部分 不一致的生命周期 人与手
 * 			组合:属性 整体与部分 一致的生命周期 人与大脑
 * 3、继承:父子类关系
 * 4、实现:接口与实现类关系
 */

public class Demo09 {
	public static void main(String[] args) {
		Voice v = new Voice(20);
		v.say();
		Amplifier am = new Amplifier(v);
		am.say();
	}
}


运行结果:

20
20000


实例2

设计模式学习笔记---装饰模式decorator(Java版)_第1张图片

package com.lgd.decorator;
/**
 * 抽象组件
 * @author liguodong
 *
 */
public interface ICar {
	void move();
}

//具体构建对象(真实对象)
class Car implements ICar{

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("陆地上跑");
	}
	
}

//装饰器角色
class SuperCar implements ICar{
	private ICar car;
	
	public SuperCar(ICar car) {
		super();
		this.car = car;
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		car.move();
	}
	
}

//具体装饰角色
class FlyCar extends SuperCar{

	public FlyCar(ICar car) {
		super(car);
		// TODO Auto-generated constructor stub
	}
	
	public void fly(){
		System.out.println("天上飞");
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		super.move();
		fly();
	}
}


//具体装饰角色
class WaterCar extends SuperCar{

	public WaterCar(ICar car) {
		super(car);
		// TODO Auto-generated constructor stub
	}
	
	public void Water(){
		System.out.println("水上游");
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		super.move();
		Water();
	}
}

//具体装饰角色
class AICar extends SuperCar{

	public AICar(ICar car) {
		super(car);
		// TODO Auto-generated constructor stub
	}
	
	public void AI(){
		System.out.println("自动跑");
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		super.move();
		AI();
	}
}


package com.lgd.decorator;

import java.awt.CardLayout;


public class Client {
	public static void main(String[] args) {
		Car car = new Car();
		car.move();
		
		System.out.println("增加新的功能,飞行-----");
		FlyCar flyCar = new FlyCar(car);
		flyCar.move();
		
		System.out.println("增加新的功能,水里游-----");
		WaterCar waterCar = new WaterCar(car);
		waterCar.move();
		
		System.out.println("增加新的功能,水里游天上飞-----");
		WaterCar waterflyCar = new WaterCar(new FlyCar(new Car()));
		waterflyCar.move();
	}
}


运行结果:

陆地上跑
增加新的功能,飞行-----
陆地上跑
天上飞
增加新的功能,水里游-----
陆地上跑
水上游
增加新的功能,水里游天上飞-----
陆地上跑
天上飞
水上游



五、应用场景

IO中的输入流和输出流的设计

Swing包中图形界面构建功能

Servlet API中提供了一个request对象的Decoratot设计模式的默认实现类HttpServletRequestWrapper,增强了request的功能。

Struct2中,request,response,session对象的处理

六、总结

装饰模式(Decorator)也叫包装器模式(Wrapper)

装饰模式降低了系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,一边增加新的具体构建类和具体装饰类。

优点:

扩展对象功能,比继承灵活,不会导致类个数的急剧增加。

可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更强大的对象。

具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。


缺点:

产生很多小的对象,大量小对象占据内存,一定程度上影响性能。

装饰模式易于出错,调试排查比较麻烦。


七、装饰模式和桥接模式的区别

都是为了解决多子类对象问题,但他们的诱因不一样。

桥接模式是对象自身现有机制沿着多个维度变化,是有部分不稳定。

装饰模式是为了增加新的功能。


你可能感兴趣的:(设计模式)