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

lambda设计模式

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

展望未来,我认为下一步是重新访问完善的设计模式,并通过功能性编程视角进行了解。 为此,我将采用Decorator模式,并使用lambdas实现它。

我们将以装饰器模式的简单且美味的示例为例:在披萨中添加浇头。 这是GoF建议的标准实现:

首先,我们具有定义组件的接口:

public interface Pizza {String bakePizza();
}

我们有一个具体的组成部分:

public class BasicPizza implements Pizza {@Overridepublic String bakePizza() {return "Basic Pizza";}
}

我们决定必须以不同的方式装饰组件。 我们选择装饰器模式。 这是抽象装饰器:

public abstract class PizzaDecorator implements Pizza {private final Pizza pizza;protected PizzaDecorator(Pizza pizza) {this.pizza = pizza;}@Overridepublic String bakePizza() {return pizza.bakePizza();}
}

我们为组件提供一些具体的装饰器:

public class ChickenTikkaPizza extends PizzaDecorator {protected ChickenTikkaPizza(Pizza pizza) {super(pizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with chicken topping";}
}public class ProsciuttoPizza extends PizzaDecorator {protected ProsciuttoPizza(Pizza pizza) {super(pizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with prosciutto";}
}

这是使用新结构的方式:

Pizza pizza = new ChickenTikkaPizza(new BasicPizza());
String finishedPizza = pizza.bakePizza();   //Basic Pizza with chicken toppingpizza = new ChickenTikkaPizza(new ProsciuttoPizza(new BasicPizza()));
finishedPizza  = pizza.bakePizza();  //Basic Pizza with prosciutto with chicken topping

我们可以看到这会变得非常混乱,如果考虑如何处理Java中的缓冲读取器,它的确会变得非常混乱:

new DataInputStream(new BufferedInputStream(new FileInputStream(new File("myfile.txt"))))

当然,您可以将其拆分为多行,但这不会解决混乱情况,只会分散它。 现在让我们看看如何使用lambda来做同样的事情。 我们从相同的基本组件对象开始:

public interface Pizza {String bakePizza();
}public class BasicPizza implements Pizza {@Overridepublic String bakePizza() {return "Basic Pizza";}
}

但是现在,我们不再声明将提供装饰模板的抽象类,而是创建装饰器,该装饰器向用户询问将装饰组件的功能。

public class PizzaDecorator {private final Function<Pizza, Pizza> toppings;private PizzaDecorator(Function<Pizza, Pizza>... desiredToppings) {this.toppings = Stream.of(desiredToppings).reduce(Function.identity(), Function::andThen);}public static String bakePizza(Pizza pizza, Function<Pizza, Pizza>... desiredToppings) {return new PizzaDecorator(desiredToppings).bakePizza(pizza);}private String bakePizza(Pizza pizza) {return this.toppings.apply(pizza).bakePizza();
}}

这条线构成了要应用的装饰链:

Stream.of(desiredToppings).reduce(identity(), Function::andThen);

这行代码将获取您的装饰(属于Function类型),并使用andThen链接它们。 这和

(currentToppings, nextTopping) -> currentToppings.andThen(nextTopping)

并确保随后按您提供的顺序调用这些函数。 还将Function.identity()转换为elem-> elem lambda表达式。 好吧,现在我们要在哪里定义装饰? 您可以在PizzaDecorator甚至在界面中将它们添加为静态方法:

public interface Pizza {String bakePizza();static Pizza withChickenTikka(Pizza pizza) {return new Pizza() {@Overridepublic String bakePizza() {return pizza.bakePizza() + " with chicken";}};}static Pizza withProsciutto(Pizza pizza) {return new Pizza() {@Overridepublic String bakePizza() {return pizza.bakePizza() + " with prosciutto";}};}
}

现在,这就是这种模式的使用方式:

String finishedPizza = PizzaDecorator.bakePizza(new BasicPizza(),Pizza::withChickenTikka, Pizza::withProsciutto);//And if you static import PizzaDecorator.bakePizza:String finishedPizza  = bakePizza(new BasicPizza(),Pizza::withChickenTikka, Pizza::withProsciutto);

如您所见,代码变得更加清晰和简洁,我们没有使用继承来构建装饰器。

这只是可以使用lambda改进的众多设计模式之一。 还有更多功能可用来改善其余功能,例如使用部分应用程序(循环)来实现适配器模式。

希望我能引起您考虑对您的开发风格采用功能更强大的编程方法的想法。

参考书目

装饰器示例的灵感来自“ 四人帮” –“用装饰器设计模式进行装饰”一文。

重构方法是受以下Devoxx 2015演讲的启发(我建议在观看这些演讲时将其视为主题): Remi Forax重新加载的 设计模式,Venkat Subramaniam的Lambda表达式设计模式

翻译自: https://www.javacodegeeks.com/2015/12/decorator-design-pattern-using-lambdas.html

lambda设计模式

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

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

相关文章

linux监控nginx占用,使用zabbix 2.4 监控nginx

1、获取 Nginx 状态( HTTP Stub Status )/usr/local/nginx/sbin/nginx -V2、配置 nginx.confvim /usr/local/nginx/conf/nginx.conflocation ~ /nginx_status {stub_status on;access_log off;allow 127.0.0.1;allow 192.168.1.14;deny all;}3、编写脚本获取上面的 key 值vim /…

如何使用java代码生成_使用Java成功生成代码的7个技巧

如何使用java代码生成作为介绍&#xff0c;最近我有点安静&#xff0c;部分原因是我一直在忙于Chronicle-FIX的工作 。 这是Chronicle-Enterprise套件中的一个新的超低延迟库&#xff0c;我们证明了该库可以在低个位数微秒内解析和存储消息。 当然&#xff0c;它利用了我们的开…

多核 linux 绑定,Linux 操作系统下CPU多核心的绑定

现在多CPU的趋势越来越大了. 有时候为了更好地操作机器, 需要将某个进程绑定到具体的CPU上去. 下面给出了一个进程绑定到具体的CPU上去的一个例子.cpu.c[CODE]#include#include#include#include#include#define __USE_GNU#include#include#includeint main(int argc, char* arg…

java键盘事件键值表_Java的20年:重大事件的时间表

java键盘事件键值表翻译自: https://www.javacodegeeks.com/2015/12/2-decades-java-timeline-notable-events.htmljava键盘事件键值表

c语言printf到指定文件,急求如何将下列C语言程序数据存储到文件中?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼求如何改动才能将下列程序的存储输入或输出数据(或两者一起)到指定的文件(或运行时直接创立一个文件)如Arrangement中。#include int n0;int rest[7][7]; //全局声明,以供全局调用int main(){void perm(int list[],int ,int );int …

spring一站式开发_Spring开发人员知道的一件事

spring一站式开发在最近的&#xff08;核心&#xff09;Spring框架培训课程中&#xff0c;有人问我&#xff1a;“&#xff08;Java&#xff09;Spring开发人员应该知道的一件事是什么&#xff1f;” 这个问题使我措手不及。 是的&#xff0c;&#xff08;核心&#xff09;Spri…

c语言十六进制转换加H,c语言十六进制和十进制间的转换.docx

集团文件版本号&#xff1a;(M928-T898-M248-WU2669-I2896-DQ586-M1988)集团文件版本号&#xff1a;(M928-T898-M248-WU2669-I2896-DQ586-M1988)c语言十六进制和十进制间的转换1.将十六进制转换为十进制.#include#includeint main(void){int convert(int,char *);int i,j;char …

jax-ws和jax-rs_带有JAX-WS和Spring的Web服务应用程序

jax-ws和jax-rs1.简介 这是一个漫长的等待&#xff0c;但是我最终要发布有关使用Spring创建第一个基于SOAP的Web服务应用程序的教程。 JAX-WS &#xff08;用于XML Web服务的Java API&#xff09;是用于以XML格式创建Web服务的一组API&#xff0c;我们最常将其称为基于SOAP的We…

c command语言学例子,语言学第四章

《语言学第四章》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《语言学第四章(3页珍藏版)》请在人人文库网上搜索。1、Chapter 4:SyntaxI. Decide whether each of the following statements is True or False:1. Syntax is a subfield of linguistics that studies …

eclipse开发jsf_在Eclipse上创建JSF / CDI Maven项目

eclipse开发jsf当我在研究JSF和CDI示例时&#xff0c;我认为提到创建JSF和CDI Maven项目所需的步骤会很有用。 您可以找到以下步骤。 工具类 默认情况下&#xff0c;M2E插件随附的Eclipse Luna。 因此&#xff0c;无需自己安装插件。 WildFlye8.x。 从主菜单中选择文件->…

apache camel_Apache Camel的性能调整思路

apache camel时不时地&#xff0c;我会以Camel速度较慢的观点来询问有关优化Camel应用程序的问题。 骆驼只是连接不同系统的粘合剂&#xff0c;路由引擎全部在内存中&#xff0c;并且不需要任何持久状态。 因此&#xff0c;在99&#xff05;的情况下&#xff0c;性能问题是由于…

为什么写C语言弹不出窗口,居然还有SB说C写不出窗口的..

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼decebx.endwassumeesi:nothinginvokeGetStockObject,WHITE_BRUSHinvokeSelectObject,hDcBack,eaxinvokeDeleteObject,eaxinvokeDeleteObject,hBmpBackpopadret_CreateBackGroundendp;>>>>>>>>>>>…

java写入单个字符_将2个字符写入单个Java char

java写入单个字符这是创建超低延迟的Chronicle FIX-Engine时使用的另一个好技巧。 在从字节流中读取数据时&#xff0c;如果可能的话&#xff0c;将数据存储在char而不是将其读取到String效率更高。 &#xff08;至少您要避免创建String对象&#xff0c;尽管可以通过使用缓存或…

xmanager linux,教您用xmanager启动Linux上的图形界面程序-Go语言中文社区

对于习惯实体化的开发人员来说&#xff0c;还是界面化用着比较习惯&#xff0c;所以这就涉及到掌握使用Xmanager启动Linux上的图形界面程序&#xff0c;为了方便大家的使用&#xff0c;本集小编就详细的为大家讲解具体操作。具体步骤如下&#xff1a;1、首先下载Xmanager并安装…

android开发 文件分享到应用,Android 实现文件分享功能(共享多个文件)

效果如图&#xff1a;神一样的代码&#xff1a;针对image代码如下&#xff1a;IntentsharenewIntent(Intent.ACTION_SEND);share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));//此处一定要用Uri.fromFile(file),其中file为File类型&#xff0c;否则附件无法发送成功。s…

python kotlin_用Java和Python模仿Kotlin构建器

python kotlin介绍 Kotlin可能现在是我最喜欢的语言&#xff0c;可能它提供的最酷的功能之一是基于几个功能构建的类型安全的生成器&#xff08;稍后解释&#xff09;。 我发现自己真的很想在其他两种主要语言&#xff08;Java和Python&#xff09;中使用此功能。 本文解释了我…

android 4.4.2截屏方法,android4.4.2 使用 uiautoviewer 截屏报错

1、正常启动后&#xff0c;使用 uiautomatorviewer 没有问题2、由于要使用 uiautomator&#xff0c;每次启动 uiautomator 服务后再使用 uiautomatorviewer 就会图片错误&#xff0c;启动 uiautomator 服务的步骤如下&#xff1a;1、Download jar files from uiautomator jsonr…

java fastutil_具有FastUtil的精简Java集合

java fastutil针对我最近在GNU Trove库上发表的《 发现Java原始资源集合的处理 》一书 &#xff0c; TheAlchemist指出了fastutil优于trove的一些优点&#xff1a;“我更喜欢fastutil&#xff08; http://fastutil.di.unimi.it/ &#xff09;&#xff0c;因为它仍在积极开发中&…

android 圆角按钮渐变,Android实现圆形渐变加载进度条

最近设计要求要一个圆形进度条渐变的需求&#xff1a;1.画圆形进度条2.解决渐变最终实现效果代码package com.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.grap…

javaone_JavaOne 2015:为JDK 9做准备– blog @ CodeFX

javaoneJavaOne 2015看到了Project Jigsaw团队关于Java 9中的模块化的一系列讨论 。它们都是非常有趣的&#xff0c;并且充满了宝贵的信息&#xff0c;我敦促每个Java开发人员都注意它们。 除此之外&#xff0c;我想给社区一种搜索和引用它们的方法&#xff0c;因此我在这里总…