java的装饰者模式了解及例子

模式定义:
     在不改变原有对象的基础上,动态地给对象增加一些额外的职责/功能。

     主要就是用来扩展类,对修改关闭,对扩展开放。
装饰者模式必然有一个公共的接口或抽象类,用来作为对象的传递

举个栗子:

     有一杯水,想加点奶,然后再加点珍珠,还想再加点冰块。

     Water接口类:

public interface Water {
	public void addWater();
}

     Water接口具体实现(被装饰的对象):

public class Milk implements Water {

	@Override
	public void addWater() {
		System.out.println("加水冲杯牛奶");
	}
}

     抽象装饰类:

public abstract class Decorate implements Water{
	private Water Water;
	public Decorate(Water water) {
		Water = water;
	}

	@Override
	public void addWater() {
		Water.addWater();
		
	}
}

     抽象装饰类具体实现一:

public class DecorateBubbleTea extends Decorate {
	public DecorateBubbleTea(Water water) {
		super(water);
	}

	@Override
	public void addWater() {
		super.addWater();
		addBubble();//新增功能
	}

	private void addBubble() {
		System.out.println("奶茶加点珍珠");
	}
}

     抽象装饰类具体实现二:

public class DecorateBubbleTeaIce extends Decorate {

	public DecorateBubbleTeaIce(Water water) {
		super(water);
	}

	@Override
	public void addWater() {
		super.addWater();
		addIce();//新增功能
	}

	private void addIce() {
		System.out.println("加点冰");		
	}
}

     测试类:

public class Test {
	public static void main(String[] args) {

		new DecorateBubbleTeaIce(new DecorateBubbleTea(new Milk())).addWater();;//加奶加珍珠加冰
		System.out.println("-------------------------------------------------------");
		new DecorateBubbleTeaIce(new Milk()).addWater();//加奶加冰
		System.out.println("-------------------------------------------------------");
		new DecorateBubbleTea(new Milk()).addWater();//加奶加珍珠
	}

//	加水冲杯牛奶
//	奶茶加点珍珠
//	加点冰
//	-------------------------------------------------------
//	加水冲杯牛奶
//	加点冰
//	-------------------------------------------------------
//	加水冲杯牛奶
//	奶茶加点珍珠

要点:
     抽象装饰类实现公共接口(Water),构造方法传递对象,对象调用接口方法。
     所有的装饰类都是继承自公共的抽象装饰,即对原有的Milk不修改,而能够额外增加功能。
     具体实现类重写抽象装饰类方法,保持父类方法,新增功能具体实现方法。

与类的继承相比较:

     类的继承也能实现扩展行为,但相比子类会繁多;比如要实现加奶要新增一个子类;实现加珍珠也新增一个子类,实现加奶加珍珠还要新增一个子类,加奶加珍珠加冰还要一个子类等等,子类就会相当繁多。
     而采用装饰者模式,功能的实现可以有多种组合实现,比如测试类的例子。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章