设计模式-装饰器模式

  1. 装饰器模式(Decorator Pattern)

动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类较为灵活。

有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。

使用继承可以实现添加功能,但是这样做不够灵活,比较灵活的方式是将组件嵌入另一个对象中,有这个对象添加边框,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此他对使用该组件的客户透明。

这个模式有一点很重要,用户通常感受不到装饰过的组件和未装饰过的组件之间的差异,也不会与装饰产生任何依赖关系。

以下情况适用装饰模式:

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方法进行扩充时,一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类的数量呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

 

744d7779a1858050e1f7ee89282c55c8f2a.jpg

 

 

 3dce3ec76934e40e80ea9358d130170a16a.jpg

 

 35fece3cff521b48dc139f780523eff3e23.jpg

示例:

Window.java

public interface Window {

    void draw(); // Draws the Window

    String getDescription(); // Returns a description of the Window

}

SimipleWindow.java

public class SimpleWindow implements Window {

    @Override

    public void draw() {

        // Draw window

    }

    @Override

    public String getDescription() {

        return "simple window";

    }

}

 

WindowDecorator.java

public class WindowDecorator implements  Window {

    protected Window windowToBeDecorated; // the Window being decorated



    public WindowDecorator (Window windowToBeDecorated) {

        this.windowToBeDecorated = windowToBeDecorated;

    }

    @Override

    public void draw() {

        windowToBeDecorated.draw(); //Delegation

    }

    @Override

    public String getDescription() {

        return windowToBeDecorated.getDescription(); //Delegation

    }

}

 

VerticalScrollBarDecorator.java

public class VerticalScrollBarDecorator extends WindowDecorator {

    public VerticalScrollBarDecorator (Window windowToBeDecorated) {

        super(windowToBeDecorated);

    }



    @Override

    public void draw() {

        super.draw();

        drawVerticalScrollBar();

    }



    private void drawVerticalScrollBar() {

        // Draw the vertical scrollbar

    }



    @Override

    public String getDescription() {

        return super.getDescription() + ", including vertical scrollbars";

    }

}

HorizontalScrollBarDecorator.java

public class HorizontalScrollBarDecorator extends WindowDecorator {

    public HorizontalScrollBarDecorator (Window windowToBeDecorated) {

        super(windowToBeDecorated);

    }



    @Override

    public void draw() {

        super.draw();

        drawHorizontalScrollBar();

    }



    private void drawHorizontalScrollBar() {

        // Draw the horizontal scrollbar

    }



    @Override

    public String getDescription() {

        return super.getDescription() + ", including horizontal scrollbars";

    }

}

DecoratedWindowTest.java

public class DecoratedWindowTest {

    public static void main(String[] args) {

        // Create a decorated Window with horizontal and vertical scrollbars

        Window decoratedWindow = new HorizontalScrollBarDecorator (

                new VerticalScrollBarDecorator (new SimpleWindow()));



        // Print the Window's description

        System.out.println(decoratedWindow.getDescription());

    }

}

 

示例2:

Troll.java

public interface Troll {



  void attack();



  int getAttackPower();



  void fleeBattle();



}

SimpleTroll.java

public class SimpleTroll implements Troll {



  @Override

  public void attack() {

    System.out.println("The troll tries to grab you!");

  }



  @Override

  public int getAttackPower() {

    return 10;

  }



  @Override

  public void fleeBattle() { System.out.println("The troll shrieks in horror and runs away!");

  }

}

ClubbedTroll.java

public class ClubbedTroll implements Troll {



  private Troll decorated;



  public ClubbedTroll(Troll decorated) {

    this.decorated = decorated;

  }



  @Override

  public void attack() {

    decorated.attack();

    System.out.println("The troll swings at you with a club!");

  }



  @Override

  public int getAttackPower() {

    return decorated.getAttackPower() + 10;

  }



  @Override

  public void fleeBattle() {

    decorated.fleeBattle();

  }

}

App.java

public class App {



  /**

   * Program entry point

   * 

   * @param args command line args

   */

  public static void main(String[] args) {



    // simple troll

    System.out.println("A simple looking troll approaches.");

    Troll troll = new SimpleTroll();

    troll.attack();

    troll.fleeBattle();

    System.out.println("Simple troll power " + troll.getAttackPower());



    // change the behavior of the simple troll by adding a decorator

    System.out.println("A troll with huge club surprises you.");

    Troll clubbedTroll = new ClubbedTroll(troll);

    clubbedTroll.attack();

    clubbedTroll.fleeBattle();

    System.out.println("Clubbed troll power " + clubbedTroll.getAttackPower());

  }

}

 

示例3:

Coffee.java

public interface Coffee {

    public double getCost(); // Returns the cost of the coffee

    public String getIngredients(); // Returns the ingredients of the coffee

}

CoffeeDecorator.java

public abstract class CoffeeDecorator implements Coffee{

    protected final Coffee decoratedCoffee;



    public CoffeeDecorator(Coffee c) {

        this.decoratedCoffee = c;

    }



    public double getCost() { // Implementing methods of the interface

        return decoratedCoffee.getCost();

    }



    public String getIngredients() {

        return decoratedCoffee.getIngredients();

    }

}

SimpleCoffee.java

public class SimpleCoffee implements Coffee {

    @Override

    public double getCost() {

        return 1;

    }



    @Override

    public String getIngredients() {

        return "Coffee";

    }

}

WithMilk.java

public class WithMilk extends CoffeeDecorator {

    public WithMilk(Coffee c) {

        super(c);

    }



    public double getCost() { // Overriding methods defined in the abstract superclass

        return super.getCost() + 0.5;

    }



    public String getIngredients() {

        return super.getIngredients() + ", Milk";

    }

}

WithSprinkles.java

public class WithSprinkles extends CoffeeDecorator {

    public WithSprinkles(Coffee c) {

        super(c);

    }



    public double getCost() {

        return super.getCost() + 0.2;

    }



    public String getIngredients() {

        return super.getIngredients() + ", Sprinkles";

    }

}

Main.java

public class Main {

    public static void printInfo(Coffee c) {

        System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());

    }



    public static void main(String[] args) {

        Coffee c = new SimpleCoffee();

        printInfo(c);



        c = new WithMilk(c);

        printInfo(c);



        c = new WithSprinkles(c);

        printInfo(c);

    }

}

 

架构师成长营

转载于:https://my.oschina.net/u/3963977/blog/2985824

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值