喂! 装饰模式(Decoraor) 说你呢! 禁止套娃!!!

了解装饰模式:

我们来看一下“装饰”是什么意思:

(截图来自百度汉语)

就这个词,已经快解释清楚“装饰模式”是什么东西了。

 

装饰模式:动态的将新功能附加到对象上。

怎么去动态添加?

其实是通过套娃实现的。

而且,没有什么附加功能是套娃解决不了的,如果不行,那就套两层。

我就,模拟养成养魔法鱼,做例子来讲一下。

 

装饰模式小案例:

首先咱们建个鱼的父类。

这是类的作用相当于管道,把主体类和各个装饰类链接起来。


package 装饰者模式;

public abstract class AboutFish {
	public AboutFish obj;
	public String des;
	private float price = 0.0f;
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
	/**
	 * 计算费用的抽象方法,子类实现
	 * @return
	 */
	public abstract float cost();
}

然后写魔法鱼类

这个类是主体类,所有的装饰都是给他用的。

package 装饰者模式;

public class Fish extends AboutFish {

	public Fish() {
		setDes("魔法鱼鱼卵");
		setPrice(10.0f);
	}
	@Override
	public float cost() {
		return super.getPrice();
	}
}

到现在,还没有用到装饰。

我们直接开始模拟养成魔法鱼。在过程中使用、讲述装饰模式

package 装饰者模式;

public class Me {

	public static void main(String[] args) {
		// 购买鱼卵
		AboutFish fish = new Fish();
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!");
		System.out.println("-----");
	}
}

运行结果:

已经花了:10.0
魔法鱼鱼卵
已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!
-----

我们开始找水吧!(准备好,开始套娃了

 

首先写个装饰抽象类(所有抽象类的父类),接上管道(继承鱼的父类

package 装饰者模式;

public class Decorator extends AboutFish{

	public Decorator(AboutFish obj) {
		this.obj=obj;
	}
	@Override
	public float cost() {
		return super.getPrice()+obj.cost();
	}
	@Override
	public String getDes() {
		return obj.getDes();
	}
}

然后写水类(装饰类

package 装饰者模式;

public class Water extends Decorator{

	public Water(AboutFish obj) {
		super(obj);
		setDes("水");
		setPrice(0.0f);
	}

}

开始孵化吧!

package 装饰者模式;

public class Me {

	public static void main(String[] args) {
		// 购买鱼卵
		AboutFish fish = new Fish();
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!");
		System.out.println("-----");
		// 获得水
		fish = new Water(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“水”,请尽快孵化吧");
		System.out.println("-----");
		System.out.println("开始孵化...");
		fish.obj.des="小鱼苗";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
        System.out.println("孵化成功,赶快给小鱼苗找点吃的吧!");
	}
}

运行结果:

已经花了:10.0
魔法鱼鱼卵
已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!
-----
已经花了:10.0
魔法鱼鱼卵
已获得“水”,请尽快孵化吧
-----
开始孵化...
已经花了:10.0
小鱼苗
孵化成功,赶快给小鱼苗找点吃的吧!

到此我们已经装饰了一次了。

继续给小鱼苗寻找食物吧(装饰类、又套一层娃)。

package 装饰者模式;

public class 脱壳丰年虾卵__小鱼苗食物 extends Decorator{

	public 脱壳丰年虾卵__小鱼苗食物(AboutFish obj) {
		super(obj);
		setDes("脱壳丰年虾卵");
		setPrice(5.0f);
	}

}

开始喂食吧。

package 装饰者模式;

public class Me {

	public static void main(String[] args) {
		// 购买鱼卵
		AboutFish fish = new Fish();
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!");
		System.out.println("-----");
		// 获得水
		fish = new Water(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“水”,请尽快孵化吧");
		System.out.println("-----");
		System.out.println("开始孵化...");
		fish.obj.des="小鱼苗";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("孵化成功,赶快给小鱼苗找点吃的吧!");
		// 获得脱壳丰年虾卵
		fish = new 脱壳丰年虾卵__小鱼苗食物(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“脱壳丰年虾卵”,请喂食小鱼苗,让它快快长大吧");
		System.out.println("-----");
		System.out.println("开始喂食..");
		fish.obj.obj.des="幼鱼";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println(".脱离幼苗期,成为幼鱼,幼鱼得吃水蚤!");
	}
}

运行结果:

已经花了:10.0
魔法鱼鱼卵
已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!
-----
已经花了:10.0
魔法鱼鱼卵
已获得“水”,请尽快孵化吧
-----
开始孵化...
已经花了:10.0
小鱼苗
孵化成功,赶快给小鱼苗找点吃的吧!
已经花了:15.0
小鱼苗
已获得“脱壳丰年虾卵”,请喂食小鱼苗,让它快快长大吧
-----
开始喂食..
已经花了:15.0
幼鱼
.脱离幼苗期,成为幼鱼,幼鱼得吃水蚤!

装饰两次了。

找水蚤吧(装饰类、双套一层娃)。

package 装饰者模式;

public class 水蚤__幼鱼食物 extends Decorator{

	public 水蚤__幼鱼食物(AboutFish obj) {
		super(obj);
		setDes("水蚤");
		setPrice(10.0f);
	}

}

开始喂鱼:

package 装饰者模式;

public class Me {

	public static void main(String[] args) {
		// 购买鱼卵
		AboutFish fish = new Fish();
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!");
		System.out.println("-----");
		// 获得水
		fish = new Water(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“水”,请尽快孵化吧");
		System.out.println("-----");
		System.out.println("开始孵化...");
		fish.obj.des="小鱼苗";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("孵化成功,赶快给小鱼苗找点吃的吧!");
		// 获得脱壳丰年虾卵
		fish = new 脱壳丰年虾卵__小鱼苗食物(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“脱壳丰年虾卵”,请喂食小鱼苗,让它快快长大吧");
		System.out.println("-----");
		System.out.println("开始喂食..");
		fish.obj.obj.des="幼鱼";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println(".脱离幼苗期,成为幼鱼,幼鱼得吃水蚤!");
		// 获得水蚤
		fish = new 水蚤__幼鱼食物(fish);
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
		System.out.println("已获得“水蚤”,请喂食幼鱼,让它快快长大吧");
		System.out.println("-----");
		System.out.println("开始喂食...脱离幼鱼期,成为成鱼");
		fish.obj.obj.obj.des="成鱼";
		System.out.println("已经花了:"+fish.cost());
		System.out.println(fish.getDes());
	}
}

运行结果:

已经花了:10.0
魔法鱼鱼卵
已获得“魔法鱼鱼卵 X1”,有“水”就可以孵化鱼卵了,快去寻找“水”吧!
-----
已经花了:10.0
魔法鱼鱼卵
已获得“水”,请尽快孵化吧
-----
开始孵化...
已经花了:10.0
小鱼苗
孵化成功,赶快给小鱼苗找点吃的吧!
已经花了:15.0
小鱼苗
已获得“脱壳丰年虾卵”,请喂食小鱼苗,让它快快长大吧
-----
开始喂食..
已经花了:15.0
幼鱼
.脱离幼苗期,成为幼鱼,幼鱼得吃水蚤!
已经花了:25.0
幼鱼
已获得“水蚤”,请喂食幼鱼,让它快快长大吧
-----
开始喂食...脱离幼鱼期,成为成鱼
已经花了:25.0
成鱼

接下来还有性成熟、交尾、产卵、衰老、死亡,等等。

你可以接着又、双继续叒、叕的套下去

今天咱们的娃,就先套到这里,啊不对,咱们的鱼,就先养到这里吧。

 

毕竟它是一条工具鱼。养到这里,就够我们理解装饰模式了。

原理解析:

这是原理图:

(关于向上转型,不了解的可以看我的另一篇博客学习:Java知识扫盲——向上转型(类向上转型、接口向上转型)以及向上转型的优势、灵活运用

这是串起来以后的效果图:

 

通过这种无限套娃,让本来的Fish可以经过多次修饰,动态的添加功能。

 

到现在,我想大家已经理解什么是装饰模式了。

 

 

装饰模式的优点:

如大家所见,扩展性非常好,只要套下去就可以了。。。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值