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与模式

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

  • 相关阅读:
    ArcGIS10.1的安装问题
    谁是农业信息化的第一推动力
    名片
    【旺铺2012分享】导航CSS代码使用修改技巧!
    新旺铺教程之导航12
    新旺铺教程之导航
    Photoshop制作通透的紫色宝石字
    用PS怎么画虚线圆?
    一张彩色图片,如何用Photoshop处理成一张轮廓图(就是变成刚用铅笔画出来时的那样)_...
    php从入门到放弃系列-01.php环境的搭建
  • 原文地址:https://www.cnblogs.com/hixin/p/7449767.html
Copyright © 2011-2022 走看看