大话设计模式——装饰者模式

周末又来了啊,锻炼完回来继续研究设计模式,作为一个coder,身体也是很重要的,周末得好好锻炼,昨晚到现在朋友圈出现最多的就是姚贝娜去世的消息,真是英年早逝,深感惋惜。 好了,言归正传,回到正题,首先看下装饰者模式的定义。

装饰者:可以动态地给一个对象增加其他职责。就扩展对象功能来说,装饰者模式比生成子类更为灵活。

看完定义还是一头雾水,莫急,继续往下看。先看一张装饰者模式的通用类图。

 

通过类图,我们可以看出Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象,记住在装饰模式中,必然有一个被提取出来最核心、最原始、最基本的接口或抽象类就是Component。
ConcreteComponent这个是最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是这个东东。
Decorator一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的属性里必然有一个private变量指向Component。
ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,你要把你最核心的、最原始的、最基本的东西装饰成啥东西就在这里面。

好了,下面我通过一款游戏来说明下装饰者模式,天天飞车,相信很多人都玩过,最初只是简单的赛车,也就是最原始的的经典模式,后来几次版本更新,加入了战车模式,接力模式等,这不是主要的,主要的是有了配件,配件干嘛的呢?当然是装饰我们的爱车的,爱车加上配件,速度更快,跑的更远,成绩更高了。

 

package com.lyc.decortor.pattern;

/**
 * 飞车的抽象类
 * @author liyangchao
 *
 */
public abstract class FlyCar {

	 /** 
     * 计算最终总成绩 
     *  
     * @return 
     */  
    public abstract int caculateScore();  
  
    /** 
     * 飞车装备的描述 
     *  
     * @return 
     */  
    public abstract String description();  
}

然后定义我们的普通飞车,最原始版的。

 

 

package com.lyc.decortor.pattern;

/**
 * 没有经过任何装饰的飞车
 * @author liyangchao
 *
 */
public class CommonFlyCar extends FlyCar{

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

	@Override
	public String description() {
		// TODO Auto-generated method stub
		return "普通的车子!";
	}

}

 

现在增加一个装饰类和几个实现类,其中Decorator的作用是封装FlyCar类,看源代码:

 

package com.lyc.decortor.pattern;
/**
 * 装饰类,装饰我们的车子
 * @author liyangchao
 *
 */

public abstract class Decorator extends FlyCar{

    //进入游戏启动爱车
    private FlyCar flyCar;
    
    //构造函数,什么样的车子得传进来
    public Decorator(FlyCar flyCar) {
        this.flyCar = flyCar;
    }
    @Override
    public int caculateScore() {
        // TODO Auto-generated method stub
        return flyCar.caculateScore();
    }
    public String description() {
        // TODO Auto-generated method stub
        return flyCar.description();
    }

}


玩过天天飞车的伙伴们都知道,现在的经典模式里边有4个属性来装饰我们的车子,分别是挂饰,芯片,引擎和邮箱,OK,下面来装饰我们的车子。先上引擎,有了引擎跑的快啊!

 

 

package com.lyc.decortor.pattern;

public class EngineDecorator extends Decorator{

	
	public EngineDecorator(FlyCar flyCar) {
		super(flyCar);
		// TODO Auto-generated constructor stub
	}
	
        //有了引擎跑得快,分数提升50
	public int caculateScore() {
		// TODO Auto-generated method stub
		return 50+super.caculateScore();
	}

	public String description() {
		// TODO Auto-generated method stub
		return super.description()+"+引擎!";
	}
}


在装个油箱,油多跑的更远,分数自然高。

 

 

package com.lyc.decortor.pattern;

public class OilDecorator extends Decorator{

	public OilDecorator(FlyCar flyCar) {
		super(flyCar);
		// TODO Auto-generated constructor stub
	}

	//加了油箱,提升80
	public int caculateScore() {
		// TODO Auto-generated method stub
		return 80+super.caculateScore();
	}

	public String description() {
		// TODO Auto-generated method stub
		return super.description()+"+油箱!";
	}
	
}

 

好了,测试一下

 

 

package com.lyc.decortor.pattern;

public class TestDecorator {

	public static void main(String[] args) {
		FlyCar flyCar;
		int score;
		String string;
		//普通车子先拿过来
		flyCar = new CommonFlyCar();
		
		 //引擎装饰下
		flyCar = new EngineDecorator(flyCar);
		//油箱再装饰下
		flyCar = new OilDecorator(flyCar);
		
		score = flyCar.caculateScore();
		string = flyCar.description();
		
		System.out.println("*******"+string+"******");
		System.out.println("这次比赛的最终成绩是:"+score);
		
	}
}

 

 

 

 

 

还有其他挂饰啊,芯片什么的装饰, 就不在一一描述了,你可以随便加上,也可以任性的减去。

 

发现了吗?装饰模式的一个非常好的优点——扩展性非常好,是对继承的有力补充,你要知道继承不是万能的,继承可以解决实际的问题,但是在项目中你要考虑到诸如易维护、易扩展、易复用等,而且在一些情况下你要是用继承就会增加很多了类,而且灵活性非常的差,那当然维护也不容易了。这正是装饰者的优势,至此又学会一种新技能,喜欢的话点个赞吧~~
 

 

 

你可能感兴趣的:(设计模式)