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

x33g5p2x  于2021-03-13 发布在 Java  
字(3.6k)|赞(0)|评价(0)|浏览(554)

英文名称:(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的关系。
---|装饰模式可以动态的扩展一个实现类的功能。
装饰模式的缺点:
---|多层的装饰模式是比较复杂的。
装饰模式的使用场景
---|扩展一个类的功能,或给一个类增加附加的功能
---|动态的给一个对象增加功能,这些功能可以动态的撤销
---|为一批的兄弟类进行改装或者加装功能,首选装饰模式。

相关文章