首页 > 技术文章 > java 装饰者模式与继承的区别

houjiie 2016-12-15 11:32 原文

装饰者模式目标

把许多要实现的功能,加载在子类上,类的继承,显得很臃肿,装饰着模式是在不改变原有类文件和使用继承的情况下,通过创建一个包装对象动态地扩展一个对象的功能,相比生成子类更为灵活

装饰者模式角色

  • 抽象组件角色

给出一个抽象接口

  • 具体组件角色

定义一个将要增加附加功能的类,相当于父类

  • 抽象装饰者角色

持有一个组件对象的实例,并且实现抽象组件接口

  • 具体装饰者角色

负责给组件对象添加附加的功能,相当于子类

 

装饰者模式示例

以一件商品被卖出为例

//抽象组件角色 Commodity.java

public interface Commodity { public void beSoldOut(); } //具体组件角色

public class Book implements Commodity { @Override public void beSoldOut() { System.out.println("书被卖出去了"); } } //抽象装饰者角色
//实现了抽象组件接口
public abstract class Decorator implements Commodity { Commodity commodity; //持有组件对象的实例 Decorator(Commodity commodity){ this.commodity=commodity; } @Override public void beSoldOut() { commodity.beSoldOut(); } } //具体装饰者角色:增加了折扣的功能

public class DiscountDecorator extends Decorator { public DiscountDecorator(Commodity commodity) { super(commodity); } public void discount(){ System.out.println("再送一件相同的商品"); } @Override public void beSoldOut() { // TODO Auto-generated method stub super.beSoldOut(); discount(); } } //具体装饰者角色:再次折扣促销


public class DiscountAgainDecorator extends Decorator { public DiscountAgainDecorator(Commodity commodity){ super(commodity); } public void discountAgain(){ System.out.println("再送一件价格低一点的商品"); } @Override public void beSoldOut() { super.beSoldOut(); discountAgain(); } } //客户端测试类 testDecorator.java
public class testDecorator { public void static main(String[] args) { Commodity book = new Book(); Decorator decorator = new DiscountAgainDecorator(new DiscountDecorator(book)); decorator.beSoldOut(); } }

 

 代码运行结果为:

书被卖出去了
再送一件相同的商品
再送一件价格低一点的商品

 

 

装饰者模式和继承的区别

继承实现的增强类:
  优点:代码结构清晰,而且实现简单
  缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致继承体系过于庞大。


装饰模式实现的增强类:
  优点:内部可以通过多态技术对多个需要增强的类进行增强
  缺点:需要内部通过多态技术维护需要增强的类的实例。进而使得代码稍微复杂。

 

推荐阅读