* 24种设计模式——装饰模式

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

继承是静态地为类增加功能,而装饰模式则是动态地增加功能。

一、罪恶的成绩单

成绩分考低了。给老爸说的时候,多点解识,猥琐点

1. 抽象成绩单

public abstract class SchoolReport {
	//成绩单主要展示的就是你的成绩情况
	public abstract void report();
	//成绩单要家长签字,这个是最要命的
	public abstract void sign(String name);
}
2. 四年级成绩单

public class FouthGradeSchoolReport extends SchoolReport{
	//我的成绩单
	public void report() {
		//成绩单的格式是这个样式的
		System.out.println("尊敬的XXX家长:");
		System.out.println("	....");
		System.out.println("	语文62 数学65 体育98 自然63 ");
		System.out.println("	....");
		System.out.println("			家系签名");
	}
	//家长签名
	public void sign(String name) {
		System.out.println("家长签名为:"+name);
	}
}
3. 增加专门的修饰的抽象类

public abstract class Decorator extends SchoolReport{
	//首先我要知道是哪个成绩单
	private SchoolReport sr;
	//构造函数,传递成绩单过来
	public Decorator(SchoolReport sr) {
		this.sr = sr;
	}
	//成绩单还是要被看到的
	public void report() {
		this.sr.report();
	}
	//看完还是要签名的
	public void sign(String name) {
		this.sr.sign(name);
	}
}
4. 最高成绩修饰

public class HighScoreDecorator extends Decorator{
	//构造函数
	public HighScoreDecorator(SchoolReport sr) {
		super(sr);
	}
	//我要汇报最高成绩
	private void reportHighScore() {
		System.out.println("这次考试语言最高是75,数学是78,自然是80");
	}
	//我要在老爸看成绩单前告诉他最高成绩,否则等他一看,就抡起扫帚了。
	public void report() {
		this.reportHighScore();
		super.report();
	}
}
5. 排名情况修饰

public class SortDecorator extends Decorator{
	//构造函数
	public SortDecorator(SchoolReport sr) {
		super(sr);
	}
	//告诉老爸学校的排名情况
	private void reportSort(){
		System.out.println("我是排名第38名...");
	}
	//老爸看完成绩单后再告诉他,加强作用
	public void report() {
		super.report();
		this.reportSort();
	}
}
6. 老爸查看修饰后的成绩单

public class Father {
	public static void main(String[] args) {
		//把成绩单拿过来
		SchoolReport sr;
		//原装的成绩单
		sr = new FouthGradeSchoolReport();
		//加了最高分说明的成绩单
		sr = new HighScoreDecorator(sr);
		//又加了成绩排名的说明
		sr = new SortDecorator(sr);
		//看成绩单
		sr.report();
		//然后老爸一看,很开心,签名了
		sr.sign("老三");
	}
}

二、装饰模式的定义

                                                                

1. 抽象构件

public abstract class Component {
	//抽象的方法
	public abstract void operate();
}
2. 具体构件

public class ConcreteComponent extends Component{
	//具体实现
	@Override
	public void operate() {
		System.out.println("do Something");
	}
}
3. 抽象装饰者

public class Decorator extends Component{
	private Component component = null;
	//通过构造函数传递被修饰者
	public Decorator(Component component) {
		this.component = component;
	}
	//委托给被修饰者执行
	@Override
	public void operate() {
		this.component.operate();
	}
}
4. 具体装饰者

public class ConcreteDecorator1 extends Decorator{
	//定义被修饰者
	public ConcreteDecorator1(Component component) {
		super(component);
	}
	//定义自己的修饰方法
	private void method1(){
		System.out.println("method1 修饰");
	}
	//重写父类的Operation方法
	@Override
	public void operate() {
		this.method1();
		super.operate();
	}
}
&

public class ConcreteDecorator2 extends Decorator{
	//定义被修饰者
	public ConcreteDecorator2(Component component) {
		super(component);
	}
	//定义自己的修饰方法
	private void method2(){
		System.out.println("method2 修饰");
	}
	//重写父类的Operation方法
	public void operate(){
		super.operate();
		this.method2();
	}
}
5. 场景类

public class Client {
	public static void main(String[] args) {
		Component component = new ConcreteComponent();
		//第一次修饰
		component = new ConcreteDecorator1(component);
		//第二次修饰
		component = new ConcreteDecorator2(component);
		//修饰后运行
		component.operate();
	}
}
三、装饰模式应用

1. 装饰模式的优点

1) 装饰类的被装饰类可以独立发展,不会相互耦合,Component类无须知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构件。

2)装饰模式是继承关系的一个替代方案。装饰类Decorator不管装饰多少层,返回的对象还是Component。

3)可以动态地扩展一个实现 类的功能。

2. 装饰模式的缺点

多层的装饰是比较复杂,难以维护,就像剥洋葱,肃到最后才发现最里层的装饰出现了问题,会导致工作量很大。因此,尽量减少装饰类的数量,以便降低系统的复杂度。

3. 使用场景

1)需要扩展一个类的功能,或给一个类增加附加功能

2)需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3)需要为一批兄弟类进行改装或加装功能,当然是首先装饰模式。

四、最佳实践

三个继承关系Father、Son、GrandSon三个类,我要在Son类上增强一些功能怎么办?普通办法会导致GrandSon代码修改很多,其实我们可以通过建立SonDecorator类来修饰Son,相当于创建一个新的类,这个对原有程序没有变更。






















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值