设为首页收藏本站

PHP.La 开源社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 985|回复: 4

设计模式-【装饰模式】 [复制链接]

Rank: 7Rank: 7Rank: 7

守月的人 发表于 2009-11-16 13:51:18 |显示全部楼层
比如在玩“极品飞车”这款游戏,游戏中有对汽车进行喷涂鸦的功能,而且这个喷涂鸦是可以覆盖的
并且覆盖的顺序也影响到最后车身的显示效果
假设现在喷涂鸦具有2种样式:(1)红色火焰 (2)紫色霞光如果使用“继承父类”设计这样的功能
那么类图就像如下的这样:


从图中可以看到使用继承来实现这种功能,并且是2种涂鸦样式,就需要创建4个子类,如果喷涂鸦有3种,4种呢?这种情况就是典型中学课程学习过的“排列与组合”,那简直就是“Head First设计模式”书中讲的“类爆炸”。

显然继承“奥迪汽车类”的这个办法是无效,而且是非常徒劳,繁琐的。
那么如何才能以“灵活”,“顺序敏感”这样的需求来实现这样的功能呢?

【装饰模式解释】
   类型:结构模式
   动态的对一个对象进行功能上的扩展,也可以对其子类进行功能上的扩展。

【装饰模式UML图】


【装饰模式-JAVA代码实现】
  新建一个抽象汽车父类:
  1. package car_package;
  2. public abstract class car_parent {
  3.     // 汽车抽象父类
  4.     private String make_address;
  5.     private int speed;
  6.     public String getMake_address() {
  7.         return make_address;
  8.     }
  9.     public void setMake_address(String make_address) {
  10.         this.make_address = make_address;
  11.     }
  12.     public int getSpeed() {
  13.         return speed;
  14.     }
  15.     public void setSpeed(int speed) {
  16.         this.speed = speed;
  17.     }
  18.     public abstract void print_face();
  19. }
复制代码
然后新建一个奥迪汽车子类
  1. package car_package;
  2. public class audi_sub extends car_parent {
  3.     // 奥迪汽车子类
  4.     @Override
  5.     public void print_face() {
  6.         System.out.println("audi车默认的颜色为 黑色");
  7.     }
  8. }
复制代码
然后再新建一个装饰者父类:
  1. package decorator_package;
  2. import car_package.car_parent;
  3. public abstract class decorator_parent extends car_parent {
  4.     // 装饰者父类
  5.     protected car_parent car_parent_ref;
  6.     public void setCar_parent_ref(car_parent car_parent_ref) {
  7.         this.car_parent_ref = car_parent_ref;
  8.     }
  9.     @Override
  10.     public void print_face() {
  11.         car_parent_ref.print_face();
  12.     }
  13. }
复制代码
然后再新建装饰者子类:红色火焰装饰者类:
  1. package decorator_package;
  2. public class decorator_audi_red extends decorator_parent {
  3.     @Override
  4.     public void print_face() {
  5.         super.print_face();
  6.         System.out.println("给 奥迪 喷涂鸦 - 颜色为 红色火焰");
  7.     }
  8. }
复制代码
然后再新建装饰者子类:紫色霞光装饰者类:
  1. package decorator_package;
  2. public class decorator_audi_purple extends decorator_parent {
  3.     @Override
  4.     public void print_face() {
  5.         super.print_face();
  6.         System.out.println("给 奥迪 喷涂鸦 - 颜色为 紫色霞光");
  7.     }
  8. }
复制代码
新建一个运行类
  1. package main_run;

  2. import car_package.audi_sub;
  3. import decorator_package.decorator_audi_purple;
  4. import decorator_package.decorator_audi_red;

  5. public class main_run {

  6.     public static void main(String[] args) {

  7.         audi_sub audi_sub_ref = new audi_sub();
  8.         audi_sub_ref.setMake_address("北京市朝阳区");
  9.         audi_sub_ref.setSpeed(200);

  10.         decorator_audi_red decorator_audi_red_ref = new decorator_audi_red();
  11.         decorator_audi_red_ref.setCar_parent_ref(audi_sub_ref);

  12.         decorator_audi_purple decorator_audi_purple_ref = new decorator_audi_purple();
  13.         decorator_audi_purple_ref.setCar_parent_ref(decorator_audi_red_ref);

  14.         decorator_audi_purple_ref.print_face();
  15.     }
  16. }
复制代码
程序运行结果如下:
  1. audi车默认的颜色为 黑色
  2. 给 奥迪 喷涂鸦 - 颜色为 红色火焰
  3. 给 奥迪 喷涂鸦 - 颜色为 紫色霞光
复制代码
装饰者模式 
附件: 你需要登录才可以下载或查看附件。没有帐号?立即注册

Rank: 9Rank: 9Rank: 9

admin 发表于 2009-11-16 13:54:18 |显示全部楼层
package, import, void main 好长时间不写JAVA了,有点看不懂了,不过可以学习一下设计模式的思想!

使用道具 举报

Rank: 7Rank: 7Rank: 7

l4yn3 发表于 2009-11-16 14:10:43 |显示全部楼层
还好,我现在上课弄java,学习了。

使用道具 举报

Rank: 7Rank: 7Rank: 7

luke 发表于 2009-11-17 14:09:06 |显示全部楼层
呀 Java好啊  厉害 顶一个  记得多多分享喽 以后跟着混咧
CMS  支持开源  共享万岁

使用道具 举报

版主

小公主

Rank: 7Rank: 7Rank: 7

可可豆 发表于 2009-11-17 22:35:20 |显示全部楼层
呵呵,真的好厉害的啊,我在上学的时候学的是JAVA不过现在已经不写了。
创业者最最重要的是,永远都要有梦想,永远每天去采取行动,去改变,去调整。任何时刻最大的困难,记住,不要失去梦想。

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|PHP.La 开源社区 ( 京ICP备09104811号 )  

GMT+8, 2012-5-20 12:10

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部