设计模式总结(Java)—— 装饰模式

参考文章:https://blog.csdn.net/android_zyf/article/details/68343953

一,什么时候使用装饰者模式?

比如有一家店卖饮品,饮品就有不少种,每一种还可以加项,比如给可乐加冰,加糖,兑水什么的,每次加项的价格还不同,就会将代码弄的很繁琐,这种情况下就可以使用装饰者模式来实现. 

何时使用

二,什么是装饰者模式?

上述的例子中,可以以饮品为主体,用不用的各种需求来装饰它,比如有一个可乐对象,那我用一个加冰对象装饰一下,再用加糖对象装饰一下,最后能得到一个加冰加糖可乐,这时候就将原可乐对象扩展,得到了加冰和加糖两种装饰. 
装饰者模式: 动态地将责任附加到对象上,对扩展功能来说,装饰者比继承更有弹性更灵活(因为子类继承父类扩展功能的前提,是已知要扩展的功能是什么样的,而这是在编译时就要确定的,但是装饰者模式可以实现动态(在运行时)去扩展功能).

三,装饰者模式结构

装饰者模式结构 

Decorator:是装饰者的父类,每个装饰者都需要继承这个抽象类(或实现这个接口). 
ConcreteDecoratorA/B:具体的装饰者,就对应上述例子中的加冰,加糖等. 
ConcreteComponent:具体的对象,就是上述例子中的可乐. 
Component:装饰者模式中最顶级的父类,装饰者与被装饰者都是它的子类或实现类才行.

四,代码走起

代码目录结构: 

建立最顶级的父类

饮品类:所有的被装饰的类都需要继承它.

/**
 * 装饰者模式最顶级的父类
 * (饮料类)
 * @author ygzx
 *
 */
public abstract class Drinks {
	
	public String name;
	
	public abstract float price();

	
	public String getName() {
		return name;
	}
}

被装饰的可乐类

/**
 * 被装饰的可乐类
 * @author ygzx
 *
 */
public class Cola extends Drinks {

	public Cola() {
		name = "可乐";
	}
	
	@Override
	public float price() {
		return 15;
	}

}

被装饰的啤酒类

/**
 * 被装饰的啤酒类
 * @author ygzx
 *
 */
public class Beer extends Drinks {

	public Beer() {
		name = "啤酒";
	}
	
	@Override
	public float price() {
		return 10;
	}

}

Decorator类,所有装饰类的父类

/**
 * 所有装饰者的父类
 * @author ygzx
 *
 */
public class Decorator extends Drinks {

	protected Drinks drinks;
	
	public Decorator(Drinks drinks) {
		this.drinks = drinks;
	}
	
	@Override
	public float price() {
		
		return 5;
		
	}

}

装饰类:加醋类

/**
 * 装饰类(加醋)
 * @author ygzx
 *
 */
public class Vinegar extends Decorator {
	
	public Vinegar(Drinks drinks) {
	     super(drinks);
	}
	
	public void addVinegar(){
		System.out.println("加醋!!!!!");
	}
	
	@Override
	public float price() {
		
		return 1+drinks.price();
	}
	
	@Override
	public String getName() {
		
		addVinegar();
		return "加醋的"+drinks.getName();
	}
	

}

装饰类:加水类

/**
 * 装饰类(加水)
 * @author ygzx
 *
 */
public class Water extends Decorator {
	
	public Water(Drinks drinks) {
		super(drinks);
	}
	
	public void addWater(){
		System.out.println("加水!!!!");
	}
	
	@Override
	public float price() {
		return 1+drinks.price();
	}
	
	@Override
	public String getName() {
		addWater();
		return "加水"+drinks.getName();
	}
	

}

五、测试类

public class Test {
	
	public static void main(String[] args) {
		
		
		Drinks drinks = new Cola();
		drinks = new Vinegar(drinks);
		drinks = new Water(drinks);
		
		System.out.println("饮品:"+drinks.getName()+",价格:"+drinks.price());
	}

}

六、总结

  • 装饰者模式可以非常的贴合六大原则之一的开闭原则.
  • 继承虽然也可以实现扩展,但是继承的扩展需要已经扩展需求,在编译期扩展,而装饰者模式可以实现在运行期扩展.
  • 装饰者可以在被装饰者的行为上扩展行为,也可以完全替代被装饰者的行为.
  • 一般情况下的引用使用的都是父类的引用,如果使用了装饰者的引用,那么也就使用该装饰者独有的方法了.
  • 使用装饰者模式,类的数量会增长很多,不能过度使用,主要是看别人代码的时候如果遇到装饰者模式而自己不懂的话,看懵逼是很正常的.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值