Decorator模式(也称为Wrapper )允许将行为静态或动态地添加到单个对象,而不会影响同一类中其他对象的行为。 可以将其视为子类的替代方法。 我们知道子类在编译时会增加行为,并且更改会影响原始类的所有实例。 另一方面,装饰可以在运行时为选择性对象提供新的行为。

装饰器与其装饰的组件的接口一致,从而对组件的客户端透明。 装饰器将请求转发到组件,并且可以在转发之前或之后执行其他操作。 透明度允许装饰器递归嵌套,从而允许无限数量的添加职责。 装饰器模式的主要参与者如下所示:

  • 组件 –指定可以动态添加职责的对象的接口。
  • ConcreteComponent –定义可以添加其他职责的对象
  • 装饰器 –保留对Component对象的引用并符合Component的接口。 它包含要装饰的Component对象。
  • ConcreteDecorator –向组件添加责任。

现在,让我们来看一个装饰器模式的具体示例,并看一下如何使用lambda表达式对其进行转换。 假设我们有不同类型的书籍,而这些书籍的封面或类别可能不同。 我们可以选择任何书籍,并通过继承来指定类别或语言。 可以将书籍抽象为一类。 之后,任何其他类都可以扩展Book类并覆盖cover或category的方法。 但这不是一种有效的方法。 在这种方法下,子类可能具有从超类扩展过来的不必要的方法。 同样,如果我们必须添加更多的属性或特性,则父类也会有所变化。 更改类的实现应该是最后的选择。

让我们通过使用装饰器模式来采取最佳方法。 我们将使用基本方法为Book创建一个接口:

public interface Book {public String describe();}

BasicBook类可以实现此接口以提供最小的抽象:

public class BasicBook implements Book {@Overridepublic String describe() {return "Book";}}

接下来,让我们定义抽象类BookDecorator ,它将充当Decorator:

abstract class BookDecorator implements Book {protected Book book;BookDecorator(Book book) {this.book = book;}@Overridepublic String describe() {return book.describe();}
}

BookDecorator类符合Book接口,并且还存储对Book接口的引用。 如果要将类别作为属性添加到Book接口,则可以使用实现BookDecorator接口的具体类。 对于小说类别,我们可以使用以下装饰器:

public class FictionBookDecorator extends BookDecorator {FictionBookDecorator(Book book) {super(book);}@Overridepublic String describe() {return ("Fiction " + super.describe());}
}

您可以看到FictionBookDecorator在原始操作(即描述)中添加了图书的类别。 同样,如果要指定“科学”类别,则可以具有相应的“ ScienceBookDecorator”

public class ScienceBookDecorator extends BookDecorator {ScienceBookDecorator(Book book) {super(book);}@Overridepublic String describe() {return ("Science " + super.describe());}
}

ScienceBookDecorator还会在原始操作中添加书籍的类别。 也可以有另一套装饰器,指示书籍的封面类型。 我们可以用SoftCoverDecorator来描述这本书有一个软封面。

public class SoftCoverDecorator extends BookDecorator {SoftCoverDecorator(Book book) {super(book);}@Overridepublic String describe() {   return (super.describe() + " with Soft Cover");}
}

我们还可以使用HardCoverDecorator来描述这本书的精装本。

public class HardCoverDecorator extends BookDecorator {HardCoverDecorator(Book book) {super(book);}@Overridepublic String describe() { return (super.describe() + " with Hard Cover");}
}

现在,让我们结合定义的所有类和接口,以利用Decorator模式的强大功能。 仅查看所有这些类的一个示例相互作用:

import java.util.List;
import java.util.ArrayList;public class BookDescriptionMain {public static void main(String [] args) {BasicBook book = new BasicBook();//Specify book as Fiction categoryFictionBookDecorator fictionBook = new FictionBookDecorator(book);//Specify that the book has a hard coverHardCoverDecorator hardCoverBook = new HardCoverDecorator(book);//What if we want to specify both the category and cover type togetherHardCoverDecorator hardCoverFictionBook = new HardCoverDecorator(fictionBook);             //Specify book as Science categoryScienceBookDecorator scienceBook = new ScienceBookDecorator(book);//What if we want to specify both the category and cover type togetherHardCoverDecorator hardCoverScienceBook = new HardCoverDecorator(scienceBook);              //Add all the decorated book items in a listList<Book> bookList = new ArrayList<Book>() {{add(book);add(fictionBook);add(hardCoverBook);add(hardCoverFictionBook);add(scienceBook);add(hardCoverScienceBook);}};//Traverse the list to access all the book itemsfor(Book b: bookList) {System.out.println(b.describe());}      }
}

运行此命令可获得以下输出:

Book
Fiction Book
Book with Hard Cover
Fiction Book with Hard Cover
Science Book
Science Book with Hard Cover

它清楚地说明了如何将不同的属性添加到任何预定义的类/对象。 同样,可以组合多个属性。 我试图将所有装饰的书本组合在一个列表中,然后通过遍历该列表来访问它们。

到目前为止,我们所看到的只是标准的装饰器模式,而且已经存在了很长时间。 在这些时候,当函数式编程成为新的流行语时,人们可能会思考Java中对lambda表达式的支持是否会有所不同。 实际上,由于修饰后的接口就像一个函数接口,因此我们可以使用Java中的lambda表达式进行哈希处理。 让我们看一下代码的样子:

import java.util.List;
import java.util.ArrayList;public class BookDescriptionMainWithLambda {public static void main(String [] args) {BasicBook book = new BasicBook();//Specify book as Fiction category using Lambda expressionBook fictionBook = () -> "Fiction " + book.describe();//Specify that the book has a hard cover using Lambda expressionBook hardCoverBook = () -> book.describe() + " with Hard Cover";//What if we want to specify both the category and cover type togetherBook hardCoverFictionBook = () -> fictionBook.describe() + " with Hard Cover";             //Specify book as Science category using Lambda expressionBook scienceBook = () -> "Science " + book.describe();//What if we want to specify both the category and cover type togetherBook hardCoverScienceBook = () -> fictionBook.describe() + " with Hard Cover";              List<Book> bookList = new ArrayList<Book>() {{add(book);add(fictionBook);add(hardCoverBook);add(hardCoverFictionBook);add(scienceBook);add(hardCoverScienceBook);}};bookList.forEach(b -> System.out.println(b.describe()));}
}

运行此命令可获得类似的输出:

Book
Fiction Book
Book with Hard Cover
Fiction Book with Hard Cover
Science Book
Fiction Book with Hard Cover

我们可以看到,使用lambda表达式会使装饰器的其他类变得多余。 您不需要其他课程; 只需使用lambda表达式指定其他行为。 但是,支持再次找到装饰器以供重新使用。 如果您有具体的装饰器类,则下次也可以重用它。

  • 可以从我的github存储库访问所有代码片段

翻译自: https://www.javacodegeeks.com/2015/12/java-8-lambda-expression-design-patterns-decorator-design-pattern.html

设计模式的Java 8 Lambda表达式–装饰器设计模式相关推荐

  1. lambda设计模式_使用lambda的装饰器设计模式

    lambda设计模式 随着Java中lambda的出现,我们现在有了一个新工具,可以更好地设计我们的代码. 当然,第一步是使用流,方法引用和Java 8中引入的其他简洁功能. 展望未来,我认为下一步是 ...

  2. java设计模式之装饰模式_Java中的装饰器设计模式

    java设计模式之装饰模式 装饰器设计模式允许在运行时将附加职责或行为动态附加到对象. 它是一种结构模式,利用聚合来组合这些行为. 在本教程中,我们将学习实现装饰器模式. UML图: 让我们从装饰器模 ...

  3. java 设计模式 示例_Java示例中的装饰器设计模式

    java 设计模式 示例 Decorator design pattern is used to modify the functionality of an object at runtime. A ...

  4. 设计模式的Java 8 Lambda表达式–命令设计模式

    在本博客中,我将说明如何使用Java 8 Lambda表达式以函数式编程方式实现命令模式 . 命令模式的目的是将请求封装为对象,从而为具有不同请求,队列或日志请求的客户端参数化,并支持相应的操作. 命 ...

  5. 设计模式的Java 8 Lambda表达式-策略设计模式

    策略模式定义封装在通常称为Context的驱动程序类中的一系列算法,并使这些算法可互换. 它使算法易于互换,并提供了在特定时间选择适当算法的机制. 算法(策略)在运行时由客户端或上下文选择. 在与客户 ...

  6. 设计模式的Java 8 Lambda表达式–策略设计模式

    策略模式定义封装在通常称为Context的驱动程序类中的一系列算法,并使这些算法可互换. 它使算法易于互换,并提供了在特定时间选择适当算法的机制. 算法(策略)在运行时由客户端或上下文选择. 在与客户 ...

  7. Java中的装饰器设计模式

    装饰器设计模式允许在运行时将附加职责或行为动态附加到对象. 它是一种结构模式,利用聚合来组合这些行为. 在本教程中,我们将学习实现装饰器模式. UML图: 让我们从装饰器模式的UML表示开始: Con ...

  8. 学习笔记:设计模式-装饰器设计模式(JAVA)

    概念 装饰器设计模式,也叫包装设计模式,他是作为现有类的一个包装,允许向一个现有的对象添加新的功能,同时又不改变其结构. 给对象添加功能,一般两种方式,继承或者组合,将一个类的对象嵌入到另一个对象中, ...

  9. java学习--装饰器设计模式

    装饰器设计模式 例一:实现对声音的的放大功能 源码: package me.sgyz.study02;/***实现放大器对声音的的放大功能* @ 洛尘曦**/public class Decorate ...

最新文章

  1. kafka生产者、消费者java示例
  2. Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE
  3. 《非暴力沟通》- 笔记
  4. mac系统学习和快捷键
  5. 第三课--EFM32GG11系列--串口接收不定长度数据的几种方式
  6. Vysor_v1.6.9
  7. 如何让gridview中的checkbox根据数据库情况默认选中?
  8. 数据分析-pands分析美国选民对总统的喜好(python实现)
  9. 阿里云官方网站免费套餐怎么抢
  10. presto联合查询mysql和ES_presto-mysql/elasticsearch6.0.0安装部署测试,异种数据源关联查询入门实践...
  11. 47 Majority Element II
  12. 转:XMPP协议、MQTT协议、HTTP协议、CoAP协议的基本比较
  13. win11文件夹打开延迟怎么办 Windows11文件打开延迟的解决方法
  14. VB语言通用基础语句
  15. 接口文档生成工具ApiPost挺好用
  16. 懂得,是生命中最美的缘
  17. 绘制系列(五)-DrawText()详解
  18. python 题目是idle的文件模式是什么_python的idle如何使用
  19. IT项目管理之第6章 项目成本管理习题选择题汇总
  20. 中国医科大学22春《毛泽东思想和中国特色社会主义理论体系概论(本科)》在线作业【标准答案】

热门文章

  1. Hibernate之映射
  2. C++描述杭电OJ 2008.数值统计 ||
  3. Photoshop中将图片拖不进软件的编辑区的解决方法,超详细
  4. oracle基本笔记整理
  5. Token认证微服务
  6. vue.js 01 模板语法
  7. Tomacat乱码解决
  8. 廖雪峰python教程整理笔记_廖雪峰python教程笔记(一)
  9. 麒麟linux百度云,百度网盘 Linux 版发布,搭配优麒麟运行更完美!
  10. java语言中的访问权限控制符有哪些,18.Java的访问控制符