设计模式(十一)---装饰模式

英文名称:(Decorator Pattern)

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

装饰模式的一般模式

 
  Component抽象构件
   ---|Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象。
  ConcreteComponent具体构件
   ---|ConcreteComponent是最核心、最原始、最基本的接口或抽象类的实现,要装饰的就是它。
  Decorator装饰角色
   ---|一般是一个抽象类,实现接口或者抽象方法,它的属性里必然有一个private变量指向Component抽象构件
  具体装饰角色

   ---|要把最原始的、最基本的、最核心的东西装饰成其他东西。

public class DecoratorPattern {
	public static void main(String[] args) {
		//拿到原始构件
		Component origin = new ConcreteComponent();
		origin = new ConcreteDecorator1(origin);
		origin = new ConcreteDecorator2(origin);
		origin.doSomething();
	}
}
abstract class Component{
	//抽象的方法,定义一些核心的方法。让子类去实现
	public abstract void doSomething();
}
class ConcreteComponent extends Component{
	
	@Override
	public void doSomething() {
		System.out.println("我是抽象构件的具体实现....");
	}
}
abstract class Decorator extends Component{
	//有一个私有方法,指向Component类
	private Component component;
	
	public Decorator(Component component) {
		this.component = component;
	}
	@Override
	public void doSomething() {
		//让Component的实现类去执行方法。
		this.component.doSomething();
	}
}
/**
 * 1号修饰类
 * @author admin
 *
 */
class ConcreteDecorator1 extends Decorator{
	//指向父类的方法
	public ConcreteDecorator1(Component component) {
		super(component);
	}
	private void decorator1(){
		System.out.println("-----开始之前先修饰-----------");
	}
	@Override
	public void doSomething() {
		System.out.println("-111111111111111111111-");
		//修饰方法
		this.decorator1();
		//执行原始方法
		super.doSomething();
	}
}
/**
 * 2号修饰类
 * @author admin
 *
 */
class ConcreteDecorator2 extends Decorator{
	//指向父类的方法
	public ConcreteDecorator2(Component component) {
		super(component);
	}
	private void decorator2(){
		System.out.println("-----结束之后再修饰-----------");
	}
	@Override
	public void doSomething() {
		System.out.println("-2222222222222222222222-");
		//执行原始方法
		super.doSomething();
		//修饰方法
		this.decorator2();
	}
}

一个例子:

   老师把我的成绩单发下来,让家长签字。因为成绩考的不好,所以不能直接把成绩单拿给爸爸看,
  因此我得在拿出成绩单前加一些修饰语。例如:告诉爸爸班里同学的最高分,我的分数是多少。
  之后再说我在班里的名次。这样就能避免一场海骂了。

public class DecoratorTest {
	public static void main(String[] args) {
		//拿着自己的原始成绩单。
		SchoolScore mScore = new ConcreteStudent();
		//加上一层修饰,最高分的修饰。
		mScore = new HighScoreDecorator(mScore);
		//再加上第二次修饰,我的排名的修饰。
		mScore = new SortDecorator(mScore);
		//做出报告说明
		mScore.report();
		//可以让家长签字了
		mScore.sign("lzl");
	}
}
abstract class SchoolScore{
	//定义一个成绩单的接口,共每个学生去实现
	//每个学生报告给家长,自己的成绩。
	public abstract void report();
	//要求家长签字。
	public abstract void sign(String name);
}
class ConcreteStudent extends SchoolScore{
	@Override
	public void report() {
		System.out.println("我的语文成绩是 89,数学成绩是 78,英语成绩是 77.");
	}

	@Override
	public void sign(String name) {
		System.out.println("家长签字:"+name);
	}
}
/**
 * 因为怕父亲看到成绩被他骂,所以我要来个装饰类。
 * @author admin
 */
abstract class MyDecorator extends SchoolScore{
	//定义学生的成绩
	private SchoolScore score;
	//用构造函数,实例化学生成绩类。
	public MyDecorator(SchoolScore score) {
		this.score = score;
	}
	//抽象方法,为学生提交成绩单时,添加一些修饰方法。
	public void report(){
		this.score.report();
	}
	
	//重写父类的方法。让家长签字
	@Override
	public void sign(String name) {
		this.score.sign(name);
	}
}
/**
 * 首先添加一个全班最高成绩的说明,
 * 让父亲知道我这个成绩还算可以。
 * @author admin
 */
class HighScoreDecorator extends MyDecorator{
	public HighScoreDecorator(SchoolScore score) {
		super(score);
	}
	private void highScoreSchool() {
		System.out.println("语文最高分:99,数学最高分:88,英语最高分:77");
	}
	@Override
	public void report() {
		//先说明最高成绩
		this.highScoreSchool();
		//再报自己的成绩
		super.report();
	}
}
class SortDecorator extends MyDecorator{

	public SortDecorator(SchoolScore score) {
		super(score);
	}
	private void getSort() {
		System.out.println("我在班里的排名是:第十...");
	}
	@Override
	public void report() {
		//先报完成绩
		super.report();
		//再说明名次。
		this.getSort();
	}
}
  装饰模式的优点
  ---|装饰类和被装饰类可以独立的发展,不会相互耦合。
  ---|装饰模式是继承关系的一种替代方案。Decorator不管修饰多少层,返回的对象还是Component,实现的还是is-a的关系。
  ---|装饰模式可以动态的扩展一个实现类的功能。
  装饰模式的缺点:
   ---|多层的装饰模式是比较复杂的。
  装饰模式的使用场景
   ---|扩展一个类的功能,或给一个类增加附加的功能
   ---|动态的给一个对象增加功能,这些功能可以动态的撤销
   ---|为一批的兄弟类进行改装或者加装功能,首选装饰模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值