当前位置: 首页 > news >正文

1.9(设计模式)装饰器模式

装饰器模式,主要向一个已有对象添加新的功能。

可以看做对原有对象进行装饰,使其功能更加丰富。

 

下面就画图举个例子。

 

Shape接口

public interface Shape {
    public void draw();
}

 

Rectangle 
public class Rectangle implements Shape{

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println("draw rectangle");
    }

}

 

Circle

public class Circle implements Shape{

    @Override
    public void draw() {
        System.out.println("draw circle");
    }

}

 

测试

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        circle.draw();
        rectangle.draw();
    }
}
draw circle
draw rectangle

 

现在我们有了新的要求,画完图形的同时我们需要设置下颜色。

这时我们采用装饰器实现这个功能,在已有对象上添加新功能。

 

那么首先我们需要创建一个抽象的装饰类,用于装饰Shape,在draw后添加setColor的功能。

既然是对原有对象的扩展,所以我们的抽象装饰类也需要实现Shape接口

public abstract class DecoratorShape implements Shape{
    protected Shape decorator;
    
    public DecoratorShape(Shape decorator) {
        super();
        this.decorator = decorator;
    }

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        decorator.draw();
    }
}

其中  Shape decorator;为被装饰对象,也就是说为decorator提供额外的功能。

具体功能的实现是通过 DecoratorShape 的子类中重写draw方法来实现的。

 

 

这里创建了一个 RedDecoratorShape 继承自 DecoratorShape,用于为图像设置红色。

同时draw中通过 decorator调用了Shape接口中图像原有的draw方法,原有的画图方法没有被改变,

只是在画图之后添加了设置颜色的方法 setRed。 

public class RedDecoratorShape extends DecoratorShape{

    public RedDecoratorShape(Shape decorator) {
        super(decorator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void draw() {
        decorator.draw();//decorator的访问级别为protected,子类可以访问。
        setRedShape();
    }
    
    private void setRedShape() {
        System.out.println("color : red");
    }
}

 

测试

public class Main {
    public static void main(String[] args) {
        //图形
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        //红色装饰器,为图像添加设置颜色的功能
        DecoratorShape redCircle = new RedDecoratorShape(circle);
        DecoratorShape redRectangle = new RedDecoratorShape(rectangle);
        //绘图同时设置颜色
        redCircle.draw();
        redRectangle.draw();
    }
}
draw circle
color : red
draw rectangle
color : red

 

 

如果我们现在想图像上既有红色又有蓝色,这时我们只需要在写一个BlueDecoratorShape,同时使用它装饰redCircle即可

BlueDecoratorShape

public class BlueDecoratorShape extends DecoratorShape{
    
        
    public BlueDecoratorShape(Shape decorator) {
        super(decorator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void draw() {
        decorator.draw();
        setRedShape();
    }
    
    private void setRedShape() {
        System.out.println("color : blue");
    }
    
}

 

 

Main

public class Main {
    public static void main(String[] args) {
        
        //图形
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        //红色装饰器,为图像添加设置颜色的功能
        DecoratorShape redCircle = new RedDecoratorShape(circle);
        DecoratorShape redRectangle = new RedDecoratorShape(rectangle);
        //在图像的基础上装饰了红色
        redCircle.draw();
        redRectangle.draw();
        
        System.out.println();
        
        //在红色图像的基础上装饰了蓝色
        DecoratorShape buleRedCircle = new BlueDecoratorShape(redCircle);
        DecoratorShape blueRedRectangle = new BlueDecoratorShape(redRectangle);
        buleRedCircle.draw();
        blueRedRectangle.draw();
        
    }
}
运行结果:
draw circle color : red draw rectangle color : red draw circle color : red color : blue draw rectangle color : red color : blue

 

 

装饰模式注重在对原有功能的扩展增强,后续需要多种颜色还可以继续装饰下去。

 

 

参考资料:

https://www.runoob.com/design-pattern/decorator-pattern.html

转载于:https://www.cnblogs.com/huang-changfan/p/10960015.html

相关文章:

  • TypeScript Visitor设计模式
  • 构造方法、this关键字的另一种用法
  • 模板 计算1的个数
  • 京北机房 怀来云交换数据中心主机托管
  • 排列组合
  • 结巴分词
  • perf4j使用
  • hdfs使用操作命令
  • node.js的npm详解
  • 求一个n!中尾数有多少个零
  • 扫描之家:RFID技术可以应用在哪些方面?
  • 设置myeclipse自动生成的author等注释
  • equals和==的区别
  • go 安装下载
  • web和APP测试区别
  • Date型的使用
  • ECMAScript6(0):ES6简明参考手册
  • ES6语法详解(一)
  • Java应用性能调优
  • Mac转Windows的拯救指南
  • Magento 1.x 中文订单打印乱码
  • Object.assign方法不能实现深复制
  • Ruby 2.x 源代码分析:扩展 概述
  • Selenium实战教程系列(二)---元素定位
  • win10下安装mysql5.7
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 从0实现一个tiny react(三)生命周期
  • 基于HAProxy的高性能缓存服务器nuster
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 入口文件开始,分析Vue源码实现
  • 使用 @font-face
  • 双管齐下,VMware的容器新战略
  • 为什么要用IPython/Jupyter?
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 智能合约开发环境搭建及Hello World合约
  • 白色的风信子
  • Semaphore
  • 阿里云API、SDK和CLI应用实践方案
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #微信小程序(布局、渲染层基础知识)
  • (九)信息融合方式简介
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (一)VirtualBox安装增强功能
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • *p++,*(p++),*++p,(*p)++区别?
  • .gitignore文件_Git:.gitignore
  • .java 9 找不到符号_java找不到符号
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET成年了,然后呢?
  • [2016.7.Test1] T1 三进制异或
  • [Android] Android ActivityManager
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [BZOJ1089][SCOI2003]严格n元树(递推+高精度)