设计模式之装饰模式


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

这次需求是:我对象要坐火车来看我,我需要打扮自己去接她
通过开放-封闭原则(封闭修改,开放扩建)我的代码是这样的:

//人类
public class Person {
	private String name;
	public Person(String name) {
		this.name = name;
	}
	public void show() {
		System.out.print("装扮的" + name);
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//装扮抽象类
public abstract class DressUP {
	public abstract void wear();
}
//装扮抽象子类
public class BigTrouser extends DressUP {

	@Override
	public void wear() {
		System.out.print("垮裤,");
	}
}
....若干个装扮抽象子类
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 执行类
	public static void main(String[] args) {
		// 我
		Person per = new Person("寒小北");

		// 装扮抽象子类
		BigTrouser bt = new BigTrouser();
		Sneakers snk = new Sneakers();
		Tshirts tr = new Tshirts();

		System.out.println("这样装扮:");
		bt.wear();
		snk.wear();
		tr.wear();
		per.show();

		System.out.println();
		System.out.println();
	}
	~~~~~~~~~~~~~~~~~~~~~~执行效果(输出)
	这样装扮:
	垮裤,破球鞋,大T恤,装扮的寒小北

但这样顺序是杂乱的,无序的,说不定是先穿了垮裤再穿的内裤呢,
而且在界面操作,让我有种赤裸着穿衣服的感觉

所以我们要把所需的功能按顺序串联起来
设计模式的具体代码如下,等会儿,再把我的代码套进去,毕竟学习模式是灵活多变的

//对象接口,可以给这些对象动态地添加职责
public abstract class Component {
	public abstract void operation();
}

//定义了一个具体的对象,也可以给这个对象添加一些职责
public class ConcreteComponent extends Component {
	@Override
	public void operation() {
		System.out.println("具体对象的操作");
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//装饰抽象类
public abstract class Decorator extends Component {
	private Component component;
	// 设置Component
	public void setComponent(Component component) {
		this.component = component;
	}
	@Override
	public void operation() {// 重写operation方法,实际执行的是Component的operation()
		if (null != component) {
			component.operation();
		}
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//装饰抽象子类
public class ConcreteDecoratorA extends Decorator {
	// 本类独有功能,用来区别于ConcreteDecoratorB
	private String add;
	public void operation() {
		super.operation();// 首先运行原Componet的operation
		add = "new State";// 再执行本类的功能
		System.out.println("具体装饰对象A的操作:" + add);
	}
}

//装饰抽象子类
public class ConcreteDecoratorB extends Decorator {
	private void add() {
		// 本类独有功能,用来区别于ConcreteDecoratorA
		System.out.println("add");
	}
	public void operation() {
		super.operation();// 首先运行原Componet的operation
		add();// 再执行本类的功能
		System.out.println("具体装饰对象B的操作");
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//客户端代码
public class AAA {
public static void main(String[] args) {
		// 首先实例化对象ConcreteComponent
		ConcreteComponent concreteComponent = new ConcreteComponent();
		ConcreteDecoratorA A = new ConcreteDecoratorA();
		ConcreteDecoratorB B = new ConcreteDecoratorB();
		// 用ConcreteDecoratorA实例化对象A来装饰ConcreteComponent
		A.setComponent(concreteComponent);
		// 用ConcreteDecoratorB实例化对象B来装饰A
		B.setComponent(A);
		// 最后调用B的operation
		B.operation();
	}
}
//控制台输出
具体对象的操作
具体装饰对象A的操作:new State
add
具体装饰对象B的操作

如果只有一个ConcreteComponent 类而没有抽象的Component类,那么Decorator类(装饰抽象类)可以是ConcreteComponent类的一个子类。

同样道理,如果只有一个ConcreteDecorator类,那么没有必要创建一个单独的Decorator类,可以把Decorator类和ConcreteDecorator类的责任合并成一个类。

所以我现在开始用装饰模式更改我一开始的代码

说实话,有点绕

//人类
public class Person {

	public Person() {
	}

	private String name;

	public Person(String name) {
		this.name = name;
	}

	public void show() {
		System.out.print("装扮的" + name);
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//装扮类
public class DressUP extends Person {

	protected Person person;

	public void decorate(Person person) {
		this.person = person;
	}

	public void show() {
		if (null != person) {
			person.show();
		}
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//具体装扮类
public class BigTrouser extends DressUP {
	public void show() {
		System.out.print("垮裤    ");
		super.show();
	}
}
public class Tshirts extends DressUP {
	public void show() {
		System.out.print("大T恤   ");
		super.show();
	}
}
public class Sneakers extends DressUP {
	public void show() {
		System.out.print("破球鞋    ");
		super.show();
	}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//客户端代码
public class AAA {
	public static void main(String[] args) {
		Person person = new Person("寒小北");
		System.out.println("第一种装扮:");
		BigTrouser bt = new BigTrouser();
		Tshirts txu = new Tshirts();
		Sneakers snke = new Sneakers();
		bt.decorate(person);
		txu.decorate(bt);
		snke.decorate(txu);
		snke.show();

		System.out.println();
		System.out.println();
	}
}

装饰模式的优点

1.把类中的装饰功能都搬移去除,这样可以简化原有的类
2.有效的把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

==用处在于:
当系统需要新功能的时候,是向旧的类中添加新代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。
如果在主类中添加新字段,新方法,新逻辑,从而增加了主类的复杂度。
而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。
装饰模式把每个要装饰的功能放在单独的类中,并让这个类去包装它所要装饰的对象
因此,当需要执行特殊行为时,客户代码,就可以在运行时根据需要有选择的、按顺序地使用装饰功能包装对象了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值