UDN-企业互联网技术人气社区

板块导航

浏览  : 974
回复  : 0

[讨论交流] Java 设计模式 -- 装饰者模式

[复制链接]
呵呵燕的头像 楼主
发表于 2016-11-27 21:49:05 | 显示全部楼层 |阅读模式
  装饰者模式动态地将责任附加到对象身上。若要拓展功能,装饰者提供了比继承更有弹性的替代方案。

  用过 QQ 的人都知道, 它有很多特权服务,比如说 Vip , SVip 等。我们就以此为例对装饰者模式进行讲解。

  1.   public class User {

  2.   private String des;

  3.   public User() {

  4.   des = "I am common user";

  5.   }

  6.   public String getDes() {

  7.   return des;

  8.   }

  9.   public void function() {

  10.   System.out.println("I can use common function.");

  11.   }

  12.   }
复制代码


  可见,在这里我们只是一个普通用户,而且也只能使用普通用户的功能。那么接下来,我们想要将普通用户升级为会员,可以使用会员功能,怎么办呢?难道这个时候我们还要去修改 function() 中的代码吗?如果真是这样,工作量真是大的难以想象。而且出于让我们得代码遵守开闭原则的目的,我们不能去盲目的修改源代码。下面我们就用装饰者模式将普通用户升级为 Vip 用户。

  首先,我们需要保证装饰者和被装饰对象有相同的超类型,所以我们现在将用户写成一个抽象类。

  1.   public abstract class User {

  2.   public User() {

  3.   }

  4.   public String getDes() {

  5.   return "I am common user";

  6.   }

  7.   public abstract void function();

  8.   }
复制代码


  下面开始书写装饰对象,装饰者可以在被装饰者行为之前或者之后或者覆盖原功能加上自己的行为,以达到特定的目的。下面我们也为装饰者对象写一个抽象类,并让其继承自 User 用以保证装饰者和被装饰者拥有共同的父类。

  1.   public abstract class Decorator extends User {

  2.   public abstract String updateTime();

  3.   }
复制代码


  update() 方法用以记录装饰者添加到被装饰者上的时间。下面我们就去写一个 Vip 装饰者,试一下功能。

  1.   public class VipDecorator extends Decorator {

  2.   private Date mDate;

  3.   private User user;

  4.   public VipDecorator(User user) {

  5.   mDate = new Date();

  6.   this.user = user;

  7.   }

  8.   @Override

  9.   public String updateTime() {

  10.   return mDate.toString();

  11.   }

  12.   @Override

  13.   public void function() {

  14.   user.function();

  15.   System.out.println("Vip function. ");

  16.   }

  17.   @Override

  18.   public String getDes() {

  19.   return "I am vip user.";

  20.   }

  21.   }
复制代码


  其实,我们应该在Decorator 抽象类里将 getDes() 和 function() 方法继续声明为抽象方法,强制子类实现这两个方法,否则很可能会遗漏。比如我一开始就漏写了 getDes() 方法。

  1.   public class Client {

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

  3.   User user = new CommonUser();

  4.   System.out.println(user.getDes());

  5.   user.function();

  6.   System.out.println("-------------------------");

  7.   user = new VipDecorator(user);

  8.   System.out.println(user.getDes());

  9.   user.function();

  10.   }

  11.   }
复制代码


  输出结果为

  1.   I am common user

  2.   Common function.

  3.   -------------------------

  4.   I am vip user.

  5.   Common function.

  6.   Vip function.
复制代码


  可见,这个时候我们想要的功能就实现了。而且,如果以后我们想增加其它的功能也不需要修改源代码。比如说,现在我想添加 SVip.

  1.   public class SVipDecorator extends Decorator {

  2.   private Date mDate;

  3.   private User user;

  4.   public SVipDecorator(User user) {

  5.   mDate = new Date();

  6.   this.user = user;

  7.   }

  8.   @Override

  9.   public String updateTime() {

  10.   return mDate.toString();

  11.   }

  12.   @Override

  13.   public void function() {

  14.   user.function();

  15.   System.out.println("SVip function. ");

  16.   }

  17.   @Override

  18.   public String getDes() {

  19.   return "I am SVip user";

  20.   }

  21.   }
复制代码


  在原来的基础上进项测试。

  1.   public class Client {

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

  3.   User user = new CommonUser();

  4.   System.out.println(user.getDes());

  5.   user.function();

  6.   System.out.println("-------------------------");

  7.   user = new VipDecorator(user);

  8.   System.out.println(user.getDes());

  9.   user.function();

  10.   System.out.println("-------------------------");

  11.   user = new SVipDecorator(user);

  12.   System.out.println(user.getDes());

  13.   user.function();

  14.   }

  15.   }
复制代码


  打印结果为

  1.   I am common user

  2.   Common function.

  3.   -------------------------

  4.   I am vip user.

  5.   Common function.

  6.   Vip function.

  7.   -------------------------

  8.   I am SVip user

  9.   Common function.

  10.   Vip function.

  11.   SVip function.
复制代码


原文作者:高华峰 来源:开发者头条

相关帖子

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

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部