设计模式学习(三)——装饰器模式

前言

距离上一次正儿八经地写随笔已经有一段时间了,虽然2月10号有一篇关于泛型的小记,但是其实只是简单地将自己的学习代码贴上来,为了方便后续使用时查阅,并没有多少文字和理解感悟。之所以在今天觉得有必要写点东西,主要是因为对自己这一周的状态不满意。表面上看,周一到周三都是加班到比较晚,周一回到家快10点了,还看了会书到12点半,但是实际上,我知道,自己的精神状态出现了松懈,心态上有点浮躁,态度的问题是不能容忍的。因此决定在今天写点东西,希望让自己能静下来,重新出发。

一、OOP(Object Oriented Programming)中的装饰器模式

在《HeadFirst设计模式》中,作者给出的定义是:装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

其实从字面上,这个定义并不是那么容易理解。我自己总结了下OOP中的装饰器模式特点:

1. 装饰者与被装饰者会继承相同的父类。

2. 装饰者会有一个私有变量持有被装饰者的引用。

3. 装饰者将自己的属性附加到到被装饰者上。

为了学以致用,我想用生活中的例子来描述装饰者模式的使用姿势。

场景:最近我厂由于业务扩展,有大批职位需要招聘,而各个职位对求职者的要求参差不齐,其中有一部分岗位对人才的要求非常相近但是又不完全相同,这边提取出一些出现频率比较高的要求:计算机专业,熟悉Java,熟悉JVM,测试分析能力,自动化测试能力。

下面就是使用装饰者模式实现的代码:

Job(被装饰者)基类:

public abstract class Job {private String title="unknown";public String getTitle(){return title;};public void setTitle(String title){this.title = title;}public abstract String getJobDescription();
}

JobRequirement(装饰者)基类:

public abstract class JobRequirement extends Job {    //重写getDescription方法public abstract String getJobDescription();
}

SoftwareDeveloper(职位1):

public class SoftwareDeveloper extends Job{public SoftwareDeveloper(){this.setTitle("Software Developer");}@Overridepublic String getJobDescription() {return "familiar with Java";}
}

SoftwareTester(职位2)

public class SoftwareTester extends Job{public SoftwareTester() {this.setTitle("Software Tester");}@Overridepublic String getJobDescription() {return "familiar with test-analysis";}
}

AutotestRequirement(自动化测试要求):

public class AutotestRequirement extends JobRequirement{Job job;public AutotestRequirement(Job job){this.job=job;}@Overridepublic String getTitle() {return job.getTitle();}@Overridepublic String getJobDescription() {return job.getJobDescription() + "; " + "familiar with autotest";}
}

JVMRequiremement(JVM要求):

public class JVMRequirement extends JobRequirement {Job job;public JVMRequirement(Job job) {this.job = job;}@Overridepublic String getTitle() {return job.getTitle();}@Overridepublic String getJobDescription() {return job.getJobDescription() + "; " + "familiar with JVM";}    
}

MajorRequirement(专业要求):

public class MajorRequirement extends JobRequirement {Job job;public MajorRequirement(Job job) {this.job = job;}@Overridepublic String getTitle() {return job.getTitle();}@Overridepublic String getJobDescription() {return job.getJobDescription() + "; " + "major in Computer Science";}
}

执行Main类:

 1 public class Main {
 2     public static void main(String[] args) {
 3         //develop 
 4         Job developer = new SoftwareDeveloper();
 5         developer = new MajorRequirement(developer);
 6         developer = new JVMRequirement(developer);
 7         System.out.println("Title: " + developer.getTitle());
 8         System.out.println("JD: " + developer.getJobDescription());
 9         //tester
10         Job tester = new SoftwareTester();
11         tester = new AutotestRequirement(new MajorRequirement(tester));
12         System.out.println("Title: " + tester.getTitle());
13         System.out.println("JD: " + tester.getJobDescription());
14     }
15 }

执行结果:

Title: Software Developer
JD: familiar with Java; major in Computer Science; familiar with JVM
Title: Software Tester
JD: familiar with test-analysis; major in Computer Science; familiar with autotest

可以看到,使用装饰者的代码非常简洁,SoftwareDeveloper本是一个普通的开发岗位,你可以通过加不同的装饰器给这个岗位增加特殊的要求。当有新的职位要求要加入时,只要创建新的requirement类来装饰即可。

二、Python中的装饰器

上一节介绍了OOP中的装饰器设计模式的思想和用法,下面简单谈谈Python中的装饰器。关于Python中的装饰器使用,这里不细讲,有兴趣可以直接查询廖雪峰的Python教程:《装饰器-廖雪峰的官方网站》。这里主要谈谈两者的区别:

1. Python中的装饰器实际上是基于函数的装饰,而面向对象的装饰器思想是基于类的装饰。

Python中的装饰器,实际上是通过语法实现基于函数的装饰,增强原有函数的功能。它通过将一些公有操作(比如:日志打印,校验网站session中是否已存在登录信息等)抽取出来,在各个需要这些公有操作的函数上方通过增加“@装饰器名”的方式来增强函数的功能。缺点是:当一个方法加上装饰器后,不能再调用原来的方法。

面向对象中的装饰器,是基于类的装饰。装饰者与被装饰者继承相同的父类,准确地应该说是有相同的“祖先”。它通过一系列的封装,使得更多的类的方法可以被复用。缺点:可能会有大量的类,造成API调用时的困扰。

2. 装饰器模式是一种设计思想,Python也是一种面向对象的语言,当然也可以使用面向对象的方式来实现装饰器模式。

三、Java I/O中的装饰者模式应用

 

上图是简单的InputStream类图(有些类没有完全列出),可以看到InputSream是一个父类,下面有4个子类,其中FileInputStream、StringBufferInputStream、ByteArrayInputStream都是被装饰者,是可以被装饰者包装起来的具体组件;FilterInputSream是一个抽象装饰者,下面有4个具体的装饰者类:PushbackInputStream、BufferedInputStream、DataInputStream、LineNumberInputStream。

这样一看,Java I/O的结构关系似乎就明了了许多,但是其中具体的细节,还是必须要抽时间系统地学习一番。

四、写在最后

其实对我来说,第一季度已经过去了70%,后续还有非常繁忙地迭代测试任务,没有多少时间可以用来完成自己第一季度的计划。在这个时间点,我更应该做的是去学习自己计划中的任务(YARN)。只是发现最近这周自己的思想状态不是很好,心态上似乎也有点浮躁,所以抽时间来写点东西,让自己的心静一静。另一方面也想将自己看过的东西实践并记录下来,可以方便后续使用时查阅。希望通过这篇随笔提醒自己,珍惜时间,不忘初心,方得始终。

转载于:https://www.cnblogs.com/znicy/p/6445359.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCL学习八叉树

建立空间索引在点云数据处理中有着广泛的应用,常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构,比较有代表性的包括BSP树,KD树,KDB树,R树,四叉树,八叉树等索引结构,而…

Android实现自定义带文字和图片的Button

在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法。 一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最小。在Button的属性中有一个是drawableLeft,这个 属性可以…

mysql语句中的注释方法_MySQL语句注释方式简介

MySQL支持三种注释方式:1.从‘#字符从行尾。2.从‘-- 序列到行尾。请注意‘-- (双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符等等)。3.从/*序列到后面的*/序列。结束序列不一定在同一行中,因此该语法允许注释跨越多行。…

android框架----下沉文字Titanic的使用

Titanic is a simple illusion obtained by applying an animated translation on the TextView TextPaint Shaders matrix. Titanic的使用 Titanic的使用,项目结构如下: 一、下载Titanic并且部署到项目中 Titanic的项目地址: https://github…

linux 自动安装mysql_Linux安装mysql

一、下载这里我创建了一目录software用于存放我们待会要下载的mysql包,先去到该目录命令:cd /software命令:wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar下载完成后,你会在software这个…

Animation用法

测试代码及说明&#xff1a; <!DOCTYPE html> <html lang"en-US"> <head><meta charset"UTF-8"><title>Simple CSS3 Animation</title><style type"text/css">#demo {position: absolute;left: 30%;t…

mysql备份 where_MySQL备份与还原

1.mysqldumpmysqlbinlog介绍mysqldump备份结合binlog日志恢复。MySQL备份一般采取全库备份加日志备份的方式&#xff0c;例如每天执行一次全备份&#xff0c;每小时执行一次二进制日志备份&#xff0c;这样在MySQL故障后可以使用全备份和日志备份将数据恢复到最后一个二进制日志…

JMeter:负载测试关系数据库

Apache JMeter是完全使用Java编写的性能测试工具。 可以在请求/响应模型上运行的任何应用程序都可以使用JMeter进行负载测试。 关系数据库也不例外&#xff1a;接收sql查询&#xff0c;执行它们并返回执行结果。 我将向您展示使用JMeter的图形用户界面设置测试方案有多么容易。…

new: Set up a window

Nehe的教程确实太老了&#xff0c;不过我认为它也能够让我了解OpenGL3.2以前的管线渲染模式&#xff0c;即使它在现在已经不常见了。因为想要了解&#xff0c;所以我还是会看完Nehe的教程。 现在这是一个新的教程 - JoeyDeVries的教程&#xff0c;可以说是网上最好的OpenGL教程…

Python全栈开发:socket

Socket socket通常也称作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一个通信链的句柄&#xff0c;应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 socket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&…

NetBeans 7.1:创建自定义提示

我已经在帖子中介绍了一些我最喜欢的NetBeans提示 &#xff0c;这些信息是用于使Java代码现代化的七个NetBeans提示和七个不可或缺的NetBeans Java提示 。 这两个帖子中涉及的十四个提示仅占NetBeans支持的“即开即用”提示总数的一小部分。 但是&#xff0c;由于NetBeans 7.1使…

qregexp括号匹配_转:Qt的正则表达式和QRegExp

考虑一下我们经常遇到的问题&#xff0c;比如gemfield想从青岛之光读书(www.civilnet.cn/book)中找一个关键的电话号码&#xff0c;通常第一步就是将书中所有的电话号码查找出来放在手边。那么怎么拟定查询条件呢&#xff1f;电话的格式有如下几种&#xff1a;01088888888010 8…

具有Tron效果的JavaFX 2 Form

这是一个具有TRON效果的简单JavaFX登录表单。 在此示例中&#xff0c;我使用CSS设置TextField和Button的样式。 这是CSS和Effect代码的片段&#xff1a; .text-field{-fx-background-color: transparent;-fx-border-color: #00CCFF;-fx-text-fill: white; }.password-field{-fx…

Akka的字数统计MapReduce

在我与Akka的日常工作中&#xff0c;我最近写了一个字数映射表简化示例。 本示例实现了Map Reduce模型&#xff0c;该模型非常适合横向扩展设计方法。 流 客户端系统&#xff08;FileReadActor&#xff09;读取文本文件&#xff0c;并将每一行文本作为消息发送给ClientActor。…

Struts2之环境配置

在学习struts2之前&#xff0c;首先我们要明白使用struts2的目的是什么&#xff1f;它能给我们带来什么样的好处&#xff1f; 设计目标 Struts设计的第一目标就是使MVC模式应用于web程序设计。在这儿MVC模式的好处就不在提了。 技术优势 Struts2有两方面的技术优势&#xff0c;…

基于JavaFX的SimpleDateFormat演示程序

对于使用Java Date进行格式化的新手甚至对于使用Java Date进行格式化的有经验的Java开发人员而言&#xff0c;可能有些棘手的事情是使用SimpleDateFormat规范日期/时间格式。 SimpleDateFormat的基于类级别的Javadoc的文档非常详尽&#xff0c;涵盖了表示日期/时间的各个组成部…

iOS与H5交互

前提&#xff1a;在iOS控制器中加载UIWebView&#xff0c;设置代理&#xff0c;遵守UIWebViewDelegate协议。 一、iOS调用JS方法 通过iOS调用JS代码实现起来比较方便直接调用UIWebView的方法- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script…

markdownTest

MARKDOWNTEST 11111111111111有一种神奇的语言&#xff0c;它比html还简单&#xff0c;它巧妙地将内容与格式整合在一起——它就是Markdown有一种神奇的语言&#xff0c;它比html还简单&#xff0c;它巧妙地将内容与格式整合在一起——它就是Markdown 111111111111111222222222…

Aleri –复杂事件处理

Sybase的Aleri流媒体平台是CEP市场中最受欢迎的产品之一。 它在Sybase的交易平台RAP版本中使用&#xff0c;该版本在资本市场中广泛用于管理投资组合中的头寸。 今天&#xff0c;在这个由多个部分组成的系列文章的第一个部分中&#xff0c;我希望提供Aleri平台的概述&#xff0…

python版本回退_Python爬虫之BeautifulSoup解析之路

上一篇分享了正则表达式的使用&#xff0c;相信大家对正则也已经有了一定的了解。它可以针对任意字符串做任何的匹配并提取所需信息。但是我们爬虫基本上解析的都是html或者xml结构的内容&#xff0c;而非任意字符串。正则表达式虽然很强大灵活&#xff0c;但是对于html这样结构…