java设计模式之Decorator(装饰)模式

 java的设计模式数不胜数,本人在学习sprint mvc时偶然间看到了Decorator(装饰)模式。下面就此模式进行简单的分析和讲述。

在工作和项目的编程中,通常会碰见一些需要临时加功能的需求,对于这些需求,如果数量少,功能单一,则可以通过继承父类,扩展子类的方法实现。但试想一下,如果工作量变大,需求变大,那到底要继承多少子类才能实现呢,如果子类过多,又会不会造成项目的混乱不堪。因此为了解决这种困扰,Decorator设计模式因运而生。

此模式大致可分为两大模块,也就是装饰类和被装饰类,那么下面便是此模式的uml图例:


1、Component抽象组件,是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象。(注:在装饰模式中,必然有一个最基本、最核心、最原始的接口或者抽象类充当Component抽象组件)
2、ConcreteComponent具体组件,是最核心、最原始、最基本的接口或抽象类的实现,我们需要装饰的就是它。
3、Decorator装饰角色, 一般是一个抽象类,实现接口或者抽象方法,它的属性里必然有一个private变量引用指向Component抽象组件。(功能多的话可以独立出个抽象类来,也可以直接ConcreteDecorator)
4、ConcreteDecorator具体装饰角色,,我们要把我们最核心的、最原始的、最基本的东西装饰成其它东西。

(以上内容为复制粘贴)


重点看如下代码:

一:原始的抽象类或接口IEquip.java

package Model;

//顶层抽象类
public abstract  class IEquip
{
	//计算攻击力
	public abstract  int caculateAttack();
	
	//装备的描述
	public abstract String description();

}

二:左侧被修饰类ArmEquip.java

package Model;

//左侧抽象类
public class ArmEquip extends IEquip {

	@Override
	public int caculateAttack() {
		// TODO Auto-generated method stub
		return 20;
	}

	@Override
	public String description() {
		// TODO Auto-generated method stub
		return "刀";
	}

}
三: 右侧修饰类IEquipDecorator.java

package Model;

public abstract class IEquipDecorator extends IEquip {

	@Override
	public int caculateAttack() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String description() {
		// TODO Auto-generated method stub
		return null;
	}

}
四:装饰组件BlueGemDecorator.java \ RedGemDecorator.java

package Model;

/**
 * @author wangye
 *
 */
public class BlueGemDecorator extends IEquipDecorator {
	private IEquip equip;
	public BlueGemDecorator(IEquip equip)
	{
		this.equip=equip;
	}
	
	@Override
	public int caculateAttack() {
		
		return 5+equip.caculateAttack();
	}

	@Override
	public String description() {
		
		return equip.description()+"+蓝宝石";
	}

}

 
package Model;

public class RedGemDecorator extends IEquipDecorator {

	private IEquip equip;
	public RedGemDecorator(IEquip equip)
	{
		this.equip=equip;
	}
	@Override
	public int caculateAttack() {
		
		return 5+equip.caculateAttack();
	}

	@Override
	public String description() {
		
		return equip.description()+"+红宝石";
	}

}

五:测试类

package Model;
public class MainTest {
	public static void main(String[] args) {
		System.out.println("修饰后的武器实力:");
		ArmEquip arm=new ArmEquip();
		IEquip equip= new RedGemDecorator(new BlueGemDecorator(arm));
		System.out.println(equip.caculateAttack());
		System.out.println(equip.description());
	}
}

需要注意的是:

每一个装饰类都需要有一个总类的private对象,并在各自的类方法中传入对象参数,以便控制原有方法,并作出新方法的改变。

再装入修饰时,要将被装饰的类一次装入修饰类中,这样便可实现此模式。


猜你喜欢

转载自blog.csdn.net/qq_36251958/article/details/77926749