装饰者模式

例子:一个可以给人搭配不同服饰的系统,即可以换各种各样的衣服裤子的个人形象系统

最先想到的是,先建一个Person类

package deractor;

public class Person {
	private String name;
	public Person(String name){
		this.name=name;
	}
	public void show(){
		System.out.println("装扮"+name);
	}
}

各种服饰的抽象类

package deractor;

abstract class Finery {
	public abstract void Show();
}

服饰子类

package deractor;

public class TShirts extends Finery{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		System.out.println("大T恤");
	}

}
package deractor;

public class BigTrouser extends Finery{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		System.out.println("垮裤");
	}

}
package deractor;

public class WearSneakers extends Finery{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		System.out.println("破球鞋");
	}

}
package deractor;

public class WearSuit extends Finery{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		System.out.println("西装");
	}
	
}

测试代码

package deractor;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Person test=new Person("Autumn");
		System.out.println("装扮如下");
		Finery ts=new TShirts();
		Finery bt=new BigTrouser();
		Finery ws=new WearSneakers();
		Finery wsuit=new WearSuit();
		ts.Show();
		bt.Show();
		ws.Show();
		wsuit.Show();
	}

}

Test中,把“大T恤”、“垮裤”、“破球鞋”、“西装”一个一个进行显示,好比:你光着身子,当着大家的面,一件一件穿上衣服,so,应该在内部组装完毕

即装饰模式Decorator,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

装饰者模式_第1张图片

其中,Component定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在,至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。基本代码实现如下:

package deractor;

abstract class Component {
	public abstract void Operation();
}
package deractor;

public class ConcreteComponent extends Component{

	@Override
	public void Operation() {
		// TODO Auto-generated method stub
		System.out.println("具体的操作对象");
	}

}
package deractor;

abstract class Decorator extends Component{
	protected Component component;
	public void setComponent(Component component){
		this.component=component;
	}
//	重写Operation,实际执行的是Component的Operation
	public void Operation(){
		if(component!=null){
			component.Operation();
		}
	}
}

package deractor;

public class ConcreteDecoratorA extends Decorator{
	private String addedState;
	public void Operation(){
		super.Operation();//首先运行原Operation,再执行本类的功能,如addedState,相当于对原Component进行了装饰
		addedState="new state";
		System.out.println("具体装饰对象A的操作");
	}
}
package deractor;

public class ConcreteDecoratorB extends Decorator{
	public void Operation(){
		super.Operation();
		AddedBehavior();
		System.out.println("具体装饰对象B的操作");
	}
	private void AddedBehavior(){
		
	}
}

装饰的方法是:先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation

package deractor;

public class DeTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ConcreteComponent c=new ConcreteComponent();
		ConcreteDecoratorA d1=new ConcreteDecoratorA();
		ConcreteDecoratorB d2=new ConcreteDecoratorB();
		
		d1.setComponent(c);
		d2.setComponent(d1);
		d2.Operation();
	}

}

如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而是可以把Decorator和ConcreteDecorator的责任合并成一个类

将上述衣服搭配稍作修改

package deractor;

public class PersonConcreteComponent {
	private String name;
	public PersonConcreteComponent(){}
	public PersonConcreteComponent(String name){
		this.name=name;
	}
	public void Show(){
		System.out.println("装扮的"+name);
	}
}
package deractor;

public class FineryDecorator extends PersonConcreteComponent{
	protected PersonConcreteComponent component;
	
	public void Decorate(PersonConcreteComponent component){
		this.component=component;
	}
	public void Show(){
		if(component!=null){
			component.Show();
		}
	}
}
package deractor;

public class TShirts2 extends FineryDecorator{

	@Override
	public void Show() {
		// TODO Auto-generated method stub	
		super.Show();
		System.out.println("大T恤");
	}

}
package deractor;

public class WearSneakers2 extends FineryDecorator{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		super.Show();
		System.out.println("破球鞋");
	}

}
package deractor;

public class BigTrouser2 extends FineryDecorator{

	@Override
	public void Show() {
		// TODO Auto-generated method stub
		super.Show();
		System.out.println("垮裤");
	}

}
package deractor;

public class DecorateTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PersonConcreteComponent person=new PersonConcreteComponent("Autumn");
		System.out.println("the following装扮");
		
		TShirts2 ts=new TShirts2();
		BigTrouser2 bt=new BigTrouser2();
		WearSneakers2 ws=new WearSneakers2();
		
		ts.Decorate(person);
		bt.Decorate(ts);
		ws.Decorate(bt);
        ws.Show();
	}

}

运行结果:

the following装扮
装扮的Autumn
大T恤
垮裤
破球鞋
由此可以看出,装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它索要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象。

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