装饰者模式生动实现,带源代码(豆浆,糖,鸡蛋,黑豆)

本文介绍装饰者模式的概念及其应用场景,对比继承方式,装饰者模式能够更灵活地为对象添加职责,通过具体实例演示如何实现饮料装饰的过程。

    1、继承带来的问题

源代码地址:http://download.youkuaiyun.com/detail/kai46385076/7870073





会产生类爆炸

2、装饰着模式概述

在不影响对象的情况下,以动态、透明的方式给单个对象添加职责。

比如上图,如果添加一个种类,可能需要增加很多类,产生类暴躁,类似网络游戏,打游戏的时候,可以给角色增加很多装备,比如盔甲,头盔,宝石,装饰品,武器,都是增强了功能,但是不改变本身。




第一个Component是一个组件,concretecompnent是一个具体的组件,豆浆是一个饮料的一种,也可以是酸梅汤等等,Decorator有两个子类继承,也可能有很多子类,这样分开可以有很多组合,比如鸡蛋,糖,比如喝豆浆的时候需要添加配料的时候添加实体装饰类就可以了。



涉及角色

抽象构建组件:定义一个抽象接口,来规范准备附加功能的类。

具体构建组件:将要被附加功能的类,实现抽象构件角色功能。

抽象装饰着角色:持有对具体构件角色的引用并定义域抽象构件组件一致的接口、

具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能。




抽象构建组件

   package com.zkq.decorator;

/**
 * 被装饰者对象的接口
 * @author Administrator
 *
 */
public interface Drink {
//饮料的描述信息
public String description();
//计算价格
public float cost();

}

具体构建组件

package com.zkq.decorator;


/**
 * 具体的被装饰者:纯豆浆
 * @author Administrator
 *
 */
public class SoyaBeanMilk implements Drink {


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


@Override
public float cost() {
// TODO Auto-generated method stub
return 5f;
}


}


抽象装饰着角色

package com.zkq.decorator;
/**
 * 装饰着父类
 * @author Administrator
 *
 */
public abstract class Decorator implements Drink{

private Drink drink;//要装饰的对象

public Decorator(Drink drink)
{
this.drink=drink;
}


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


@Override
public float cost() {
// TODO Auto-generated method stub
return drink.cost();
}



}


具体装饰角色

package com.zkq.decorator;
/**
 *具体的装饰者对象,糖 
 * @author Administrator
 *
 */
public class SugarDecorator extends Decorator{


public SugarDecorator(Drink drink) {
super(drink);
// TODO Auto-generated constructor stub
}
@Override
public String description() {
// TODO Auto-generated method stub
return super.description()+"糖";
}
@Override
public float cost() {
// TODO Auto-generated method stub
return super.cost()+0.5f;
}
}


具体装饰角色


package com.zkq.decorator;
/**
 * 具体的装饰着对象:鸡蛋
 * @author Administrator
 *
 */
public class EggDecorator extends Decorator{


public EggDecorator(Drink drink) {
super(drink);
// TODO Auto-generated constructor stub
}
@Override
public String description() {
// TODO Auto-generated method stub
return super.description()+"鸡蛋";
}
@Override
public float cost() {
// TODO Auto-generated method stub
return super.cost()+2.0f;
}
}


具体装饰角色


package com.zkq.decorator;
/**
 * 具体的装饰者:黑豆
 * @author Administrator
 *
 */
public class BlackBeanDecorator extends Decorator{


public BlackBeanDecorator(Drink drink) {
super(drink);
// TODO Auto-generated constructor stub
}
@Override
public String description() {
// TODO Auto-generated method stub
return super.description()+"黑豆";
}
@Override
public float cost() {
// TODO Auto-generated method stub
return super.cost()+3.0f;
}


}


测试

package com.zkq.decorator;


public class Test {


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//生产一个豆浆
Drink soya=new SoyaBeanMilk();
//在豆浆中加鸡蛋
EggDecorator eggSoya=new EggDecorator(soya);
//在加了鸡蛋中的豆浆中加糖
SugarDecorator sugarEggSoya=new SugarDecorator(eggSoya);
//加了糖了豆浆中加黑豆
BlackBeanDecorator blackbeansugarEggSoya=new BlackBeanDecorator(sugarEggSoya);
System.out.println("你点了"+blackbeansugarEggSoya.description());
System.out.println("一共"+blackbeansugarEggSoya.cost());
}


}

实现结果为:

你点了纯豆浆鸡蛋糖黑豆
一共10.5



下面可以举个生动的例子,大家应该见过打印咧PrintStream,这个就算是装饰着模式。

OutputStream out=new FileutputStream("d:\\1.txt");

BufferedOutputStream bos=new BufferedOutputStream(out);

PrintStream ps=new PrintStream(bos);

等于豆浆加上鸡蛋,加上糖。相当于具备了很好输出功能的输出流。实现了装饰着模式

OO原则:动态地将责任附加到对象上。想要扩张功能,装饰者提供有别于继承的另一种选择。

注意要点:

1、继承属于扩展形式之一,但不见得是弹性设计的最佳方案。

2、在我们的设计中,应该允许行为可以被扩展,而不须修改现有的代码。

3、组合和委托可用于在运行时动态地加上新的行为。

4、除了继承,装饰着模式也可以让我们扩展行为。

5、装饰着模式意味着一群装饰着类,这些类用来包装具体组件。

6、装饰着类反映出被装饰的组件类型(实际上,他们具有相同的类型,都通过接口和继承实现)。

7、装饰着可以在在被装饰者的行为前面与或后面加上自己的行为,甚至将装饰者行为整个取代掉,而达到特定的目的。

8、你可以有无数个装饰者包装一个组件。

9、装饰着一般对组件的客户是透明的。

除非客户程序依赖于组件的具体类型。

源代码地址:http://download.youkuaiyun.com/detail/kai46385076/7870073

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值