简单理解设计模式之装饰者模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YQYnsmile/article/details/52673529

闲话不多说,今天来谈谈装饰者模式:

首先,我觉得要学习设计模式,记住它的定义真的挺重要的,或者一开始的时候你不了解,但是后面理解模式的内涵之后,你会发现定义的精辟。

装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。

首先在设计类的时候,我们要明白这样一个观念:我们所设计的类要对扩展开放,对修改关闭。当我们设计的类不能满足我们的需求的时候,我们可能设计一个类去继承它,但是这样就会使对象之间高度的耦合,解耦的时候,或者说需要维护的时候会造成很多不必要的麻烦,这个时候,我们就可以考虑一下使用装饰者模式了,装饰者模式简单来说,就是把对象嵌入我们要扩展功能的类中,调用他的方法,然后跟我们定义的方法一起返回我们需要的类型。这个可能跟适配器模式有点相似,但是他们所针对的点不一样,后面可以继续关注我对适配者模式的讲解。

理论的东西可能理解起来会比较困难,我们还是通过一个例子来说明吧:

我还是喜欢那个咖啡的例子:当我们去咖啡厅的时候。不知道是不是会遇到这种问题呢?本来你点一杯普通的coffe,然后他的价格是10元,但是你尝了之后发现有点苦,想要加点红糖,然后加这个糖的价格是2元;然后过了一会你的朋友过来了,他叫了一杯普通coffee,然后加了点牛奶(假设可以加),这个牛奶的价格是3元,如果叫你设计一个程序负责这部分的内容,你会怎么做呢?

会不会有人这么想,java不是面向对象的语言吗?我们可以通过设计对象来啊,首先创建coffee一个抽象类,然后在列出可能添加调料的可能食品,然后付款的时候,调用方法不就行了吗?确实这样做是可以的,但是前面说了耦合度高,这个时候,就到了我们的装饰者出场了:

首先画出关系图:

我们要做的就是点咖啡1的时候加sugar,点咖啡2的时候加milk

(1)创建coffee的接口

package com.zqu.yqy.scdn.test.test006;

public abstract class Coffee {
	String coffeeInformation = "普通咖啡";
	public String getCoffeeInformation(){
		return coffeeInformation;
	}
	public abstract double cost();

}

实现类coffee1,coffee2:

 

 

package com.zqu.yqy.scdn.test.test006;

public class Coffee1 extends Coffee {
	public Coffee1(){
		coffeeInformation = "coffee1";
	}

	@Override
	public double cost() {
		return 10.0;
	}

}
package com.zqu.yqy.scdn.test.test006;

public class Coffee2 extends Coffee {
	public Coffee2(){
		coffeeInformation = "coffee2";
	}

	@Override
	public double cost() {
		
		return 12.0;
	}

}

(2)调料类

 

 

package com.zqu.yqy.scdn.test.test006;

public abstract class AddThings extends Coffee {
	public abstract String getCoffeeInformation();
}


实现类:

 

 

package com.zqu.yqy.scdn.test.test006;

public class Milk extends AddThings{
	Coffee coff;
	public milk(Coffee c) {
		this.coff = c;
	}

	@Override
	public String getCoffeeInformation() {
		String addThings = coff.getCoffeeInformation()+"添加"+"milk";
		return addThings;
	}

	@Override
	public double cost() {
	
		return 3.0+coff.cost();
	}

}
package com.zqu.yqy.scdn.test.test006;

public class Sugar extends AddThings {
	Coffee coff;
	public Sugar(Coffee c) {
		this.coff = c;
	}
	@Override
	public String getCoffeeInformation() {
		String addThings = coff.getCoffeeInformation()+"添加"+"sugar";
		return addThings;
	}

	@Override
	public double cost() {
		
		return 2.0+coff.cost();
	}
	

}


(3)实现类:

 

 

package com.zqu.yqy.scdn.test.test006;

public class Cost {
	public static void main(String[] args) {
		coffee c1 = new coffee1();
		coffee c2 = new coffee2();
		coffee a1 = new sugar(c1);
		coffee a2 = new milk(c1);
		//coffee a3 = new milk(c2);
		System.out.println(a1.getCoffeeInformation()+" "+a1.cost());
		System.out.println(a2.getCoffeeInformation()+" "+a2.cost());
		//System.out.println(a3.getCoffeeInformation()+" "+a3.cost());
		
	}
	

}

结果截图:

 


你会发现很神奇的实现了,我们要的功能,可能有的人会好奇,为什么我们的调料类也要继承coffee的呢?这个问题问得好,但是我相信你把我注释掉的那部分代码再执行一遍,你会很神奇的发现,我们的coffee1或者是coffee2还能添加牛奶呢。这你实践一下就会明白的,这样的目的怎么,是不是非常棒!!!

好了。关于装饰者模式就介绍到这里,下一篇我会介绍一下,适配器模式,你会发现会有很大的相同之处。


 

 

没有更多推荐了,返回首页