Android设计模式之一个例子让你彻底明白装饰者模式(Decorator Pattern)
来源:互联网 发布:热敏打印机编辑软件 编辑:程序博客网 时间:2024/05/01 21:43
导读
这篇文章中我不会使用概念性文字来说明装饰者模式,因为通常概念性的问题都很抽象,很难懂,使得读者很难明白到底为什么要使用这种设计模式,我们设计模式的诞生,肯定是前辈们在设计程序的时候遇到了某种困难,为了避免这种苦难的发生,从而设计出来的这种设计模式,所以这篇文章中我会带领大家遇见这种困难,从而使用设计模式解决这种困难,最后大家就会明白什么是设计者模式,什么时候应该使用设计者模式以及如何使用设计者模式了
首先我们先来看一下装饰者模式的UML图是什么样子的,图中各个类的含义不懂没有关系,下面我会用一个形象的例子来一一介绍他们,相信大家看完后肯定就明白了
如果不用装饰者设计模式会出现什么问题?
这里我不准备用一些概念性的文字来说明什么是装饰者模式,我就要用一个实际的例子来形象的说明什么是装饰者模式!
比如我们玩网络游戏,我们都要先创建一个角色对吧,这些角色每个人创建出来的都不一样,因为角色肯定可以根据用户的审美来个性化打造,但是每个角色最开始的能力都是一样的,不会因为一个玩家给他捏了一张特别帅的脸而变得特别的厉害。那么这个角色肯定是一个接口,这就是UML图中的Conponent接口
/** * 游戏角色 */public interface Avatar { String describe();}
非常简单,只有一个方法,我们只用来演示,真正的游戏角色不可能只有这么简单。describe方法用来描述这个角色。
好,我们玩游戏肯定有职业对吧,假设我们这款游戏只设计了4种职业:战士(Worrior),法师(Mage),猎人(Hunter),术士(Warlock)。我们要创建4个实现类,这就对应ConcreteComponent类
public class Worrior implements Avatar { @Override public String describe() { return "战士"; }}
public class Mage implements Avatar { @Override public String describe() { return "法师"; }}
public class Hunter implements Avatar { @Override public String describe() { return "猎人"; }}
public class WarLock implements Avatar { @Override public String describe() { return "术士"; }}
好了,现在我们已经创建好4种职业的游戏角色了。现在我们的玩家觉得太单调了,所有同样职业的角色都长一个样子,你们应该允许我们在创建角色的时候可以修改角色的外观。比如选择头发颜色。
这可怎么办,我们有4种职业啊,每种职业提供3种颜色的头发,我们得再创建12个子类啊,而且之前设计的4个实现类的作用也就不大了,因为大家肯定都去改变一下头发的颜色。好,先硬着头皮来写吧。
public class WorriorWithRedHair implements Avatar{ @Override public String describe() { return "战士+红颜色头发"; }}public class WorriorWithGreenHair implements Avatar{ @Override public String describe() { return "战士+绿颜色头发"; }}public class WorriorWithBlueHair implements Avatar{ @Override public String describe() { return "战士+蓝颜色头发"; }}public class MageWithRedHair implements Avatar{ @Override public String describe() { return "法师+红颜色头发"; }}public class MageWithGreenHair implements Avatar{ @Override public String describe() { return "法师+绿颜色头发"; }}public class MageWithBlueHair implements Avatar{ @Override public String describe() { return "法师+蓝颜色头发"; }public class HunterWithRedHair implements Avatar{ @Override public String describe() { return "猎人+红颜色头发"; }}public class HunterWithGreenHair implements Avatar{ @Override public String describe() { return "猎人+绿颜色头发"; }}public class HunterWithBlueHair implements Avatar{ @Override public String describe() { return "猎人+蓝颜色头发"; }public class WarLockWithRedHair implements Avatar{ @Override public String describe() { return "术士+红颜色头发"; }}public class WarLockWithGreenHair implements Avatar{ @Override public String describe() { return "术士+绿颜色头发"; }}public class WarLockWithBlueHair implements Avatar{ @Override public String describe() { return "术士+蓝颜色头发"; }
好了,加班到半夜,终于写完了。第二天上班,老板来找你了,现在我们的玩家越来越多了,他们反映说我们的角色还是太单调,我们还要让玩家可以选择上衣的颜色和裤子的颜色,上衣有5种颜色,裤子有5种颜色。听完这个需求,我想你也应该吐血了。比如玩家A会选择战士+红色头发+白色上衣+蓝色裤子,玩家B会选择术士+蓝色头发+白色上衣+黄色裤子。这组合也太多了,这得写多少个实现类。这种方法肯定是行不通的。
使用装饰者模式如何解决问题?
这时公司来了个大牛,他听说了这个情况,接下了这个需求,你心想他一定是疯了,可是第二天他就完成了任务,你吃了一大惊,赶紧去看他的代码是怎么实现的,原来这位大牛使用了你连听都没说过的装饰者设计模式。
首先他设计了一个类,实现了Avatar接口,并且传入了一个Avatar对象,这就对应UML图中的Decorator
public class AvatarDecorator implements Avatar { private Avatar av; public AvatarDecorator(Avatar avatar){ av = avatar; } @Override public String describe() { return av.describe(); }}
我们看到他里面持有一个Avatar类型的对象,在describe方法中实际调用的也是av的describe对象,我们传入的Avatar对象也就是我们需要进行装饰的对象了。
好,现在我们先来设计头发颜色的装饰类
public class RedHair extends AvatarDecorator { public RedHair(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+红色头发"; }}public class GreenHair extends AvatarDecorator { public GreenHair(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+绿色头发"; }}public class BlueHair extends AvatarDecorator { public BlueHair(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+蓝色头发"; }}
我们看到,我们的构造方法是调用的super()的构造方法,也就是调用的AvatarDecorator的构造方法,我们的describe中也先调用了super.describe()然后后面加上了我们的装饰内容,也就是说我们传进来的一个Avatar对象被我们装饰了。这就相当于UML中的ConcreteDecorator。
好了,现在玩家想要创建一个角色的话就可以这样创建出来
//红色头发战士Avatar avatar1 = new RedHair(new Worrior());//绿色头发术士Avatar avatar2 = new GreenHair(new WarLock());
接下来我们再设计上衣和裤子的装饰类
public class WhiteJacket extends AvatarDecorator { public WhiteJacket(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+白色上衣"; }}public class RedJacket extends AvatarDecorator { public RedJacket(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+红色上衣"; }}public class BlackJacket extends AvatarDecorator { public BlackJacket(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+黑色上衣"; }}public class GreenJacket extends AvatarDecorator { public GreenJacket(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+绿色上衣"; }}public class BlueJacket extends AvatarDecorator { public BlueJacket(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+蓝色上衣"; }}
public class WhitePants extends AvatarDecorator { public WhitePants(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+白色裤子"; }}public class BlackPants extends AvatarDecorator { public BlackPants(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+黑色裤子"; }}public class RedPants extends AvatarDecorator { public RedPants(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+红色裤子"; }}public class GreenPants extends AvatarDecorator { public GreenPants(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+绿色裤子"; }}public class BluePants extends AvatarDecorator { public BluePants(Avatar avatar) { super(avatar); } @Override public String describe() { return super.describe()+"+蓝色裤子"; }}
好了,现在我们就可以任意组合我们的角色了
//绿色头发猎人穿着白色上衣和黑色裤子 Avatar avatar3 = new GreenHair(new WhiteJacket(new BlackPants(new Hunter()))); //红色头发法师穿着红色上衣和白色裤子 Avatar avatar4 = new RedHair(new RedJacket(new WhitePants(new Mage())));
有图有真相
- Android设计模式之一个例子让你彻底明白装饰者模式(Decorator Pattern)
- Android设计模式之一个例子让你彻底明白装饰者模式(Decorator Pattern)
- Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)
- Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)
- Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)
- 设计模式-装饰者模式(Decorator Pattern)
- Android设计模式之装饰者模式(Decorator Pattern)
- 装饰者设计模式(Decorator Pattern)
- android设计模式-装饰模式(Decorator Pattern)
- 如何让孩子爱上设计模式 ——8.装饰者模式(Decorator Pattern)
- 设计模式[6] Decorator Pattern 装饰模式
- 设计模式-装饰模式(Decorator Pattern)
- 设计模式之装饰模式(Decorator Pattern)
- 设计模式心得:装饰模式 (decorator pattern)
- 设计模式-装饰模式(Decorator Pattern)
- 设计模式之装饰模式--- Pattern Decorator
- 设计模式_装饰模式(Decorator Pattern)
- 设计模式【装饰模式Decorator Pattern】
- oc考试题
- 指针函数与函数指针的区别
- web.xml中<load-on-startup></load-on-startup>中的作用
- 操作系统: 最佳适配算法和邻近适配算法的模拟实现(内存分配算法)
- ListView的上拉加载以及圆形图片的实现
- Android设计模式之一个例子让你彻底明白装饰者模式(Decorator Pattern)
- Codeforce Round #336--B. Hamming Distance Sum
- ZOJ 3380 Patchouli's Spell Cards(概率DP)
- for循环中i=0与i=arr.length容易被忽视的bug
- Objective-C与JavaScript的简易交互操作
- 从大数据的应用谈如何成为大数据大师的历程
- JAVA集合框架
- 数据结构课程设计-12月27日
- Mac 技巧