zoukankan      html  css  js  c++  java
  • 装饰模式(decorator)

    意图:

      动态地给一个对象添加一些额外的职责,就增加功能而言,Decorator模式相比生成子类模式更为灵活

    动机:

      有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。一种较为灵活的方式是将组件嵌入另一个对象中,由这个对象添加边框。我们称这个嵌入的对象为装饰 。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。

            例如,假定有一个对象 Te x t Vi e w,它可以在窗口中显示正文。缺省的 Te x t Vi e w没有滚动
    条,因为我们可能有时并不需要滚动条。当需要滚动条时,我们可以用 S c r o l l D e c o r a t o r添加滚
    动条。如果我们还想在 Te x t Vi e w周围添加一个粗黑边框,可以使用 B o r d e r D e c o r a t o r添加。因
    此只要简单地将这些装饰和 Te x t Vi e w进行组合,就可以达到预期的效果。

    结构:

    例子:

    以往画布上画一个圆为例来说明装饰模式的使用

     1 package designpatterns.strucural;
     2 //抽象构件角色--Component
     3 interface Shape {
     4     void draw();
     5 }
     6 //具体构件角色--Concrete Component
     7 class Circle implements Shape {
     8 
     9     @Override
    10     public void draw() {
    11         System.out.println("Shape: Circle");
    12     }
    13 }
    14 
    15 //装饰角色--Decorator
    16 abstract class ShapeDecorator implements Shape{
    17     protected Shape decoratedShape;
    18 
    19     public ShapeDecorator(Shape decoratedShape) {
    20         this.decoratedShape = decoratedShape;
    21     }
    22 
    23     public void draw() {
    24         decoratedShape.draw();
    25     }
    26 }
    27 
    28 //具体装饰角色--Concrete Decorator1
    29 class RedShapeDecorator extends ShapeDecorator {
    30 
    31     public RedShapeDecorator(Shape decoratedShape) {
    32         super(decoratedShape);
    33     }
    34 
    35     @Override
    36     public void draw() {
    37         decoratedShape.draw();
    38         setRedBorder(decoratedShape);
    39     }
    40 
    41     private void setRedBorder(Shape decoratedShape) {
    42         System.out.println("Border Color: Red");
    43     }
    44 
    45 }
    46 
    47 //具体装饰角色--Concrete Decorator2
    48 class  DottedLineShapeDecorator extends ShapeDecorator {
    49 
    50     public DottedLineShapeDecorator(Shape decoratedShape) {
    51         super(decoratedShape);
    52     }
    53 
    54     @Override
    55     public void draw() {
    56         decoratedShape.draw();
    57         setLineType(decoratedShape);
    58     }
    59 
    60     private void setLineType(Shape decoratedShape) {
    61         System.out.println("Line   type:  dotted");
    62     }
    63 
    64 }
    65 
    66 //画布
    67 class Canvas{
    68       void addshape(Shape shape){
    69           shape.draw();
    70       }
    71 }
    72 
    73 //客户端
    74 public class Decorator {
    75 
    76     public static void main(String[] args) {
    77 
    78         Canvas canvas = new Canvas();
    79         Circle circle = new Circle();
    80 
    81         canvas.addshape(circle);
    82         System.out.println();
    83 
    84         canvas.addshape(new RedShapeDecorator(circle));
    85         System.out.println();
    86 
    87         canvas.addshape(new DottedLineShapeDecorator(new RedShapeDecorator(circle)));
    88         System.out.println();
    89     }
    90 
    91 }

    验证输出:

    Shape: Circle
    
    Shape: Circle
    Border Color: Red
    
    Shape: Circle
    Border Color: Red
    Line   type:  dotted

    代码说明:

    最终使用该组件的客户为Canvas,由于装饰和它装饰的组件接口一致,客户就可以随意组合调用

    1、绘制圆

    2、绘制红色的圆

    3、用虚线绘制红色的圆

    你还可以添加更多的装饰,使用时只需要将这些装饰和组件Circul进行组合,就可以达到想要的效果

    参考:

    设计模式:桥接模式(Bridge)

    Java与模式

    设计模式:可复用面向对象软件的基础

  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/hixin/p/7449767.html
Copyright © 2011-2022 走看看