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

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

  • 相关阅读:
    Android使用百度地图定位并显示手机位置后使用前置摄像头“偷拍”
    JS传递参数时对中文进行编码和解码
    点击<a>标签,禁止页面自动跳到顶部的解决办法
    百度地图API用法(传地址)
    asp.net页面按Enter键IE不提交表单
    asp.net同时调用JS和后台的无效的解决
    QQ浏览器不支持JS问题
    html中opacity的使用
    c#中传递参数前加out
    IE下使用jquery ajax失效
  • 原文地址:https://www.cnblogs.com/hixin/p/7449767.html
Copyright © 2011-2022 走看看