我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长。所以我想出了以下DSL语法:

Object msg = //...
whenTypeOf(msg).
    is(Date.class). then(date -> println(date.getTime())).
    is(String.class). then(str -> println(str.length())).
    is(Number.class). then(num -> println(num.intValue())).
                     orElse(obj -> println("Unknown " + obj));

在Java 8中,没有向下转换,简洁的语法,强类型的……完全可以实现的。使用lambda和一些泛型,我创建了一个名为typeof的小型库 ,它比instanceofVisitor模式结合在一起是干净的,易于使用且更健壮的。优势包括:

  • 没有明确的垂头丧气
  • 避免instanceof
  • 清洁且易于使用
  • 强类型
  • 适用于我们无法控制的类,包括JDK

这个小实用程序是出于Akka和Java API的目的而开发的,目的是限制instanceof运算符的使用,但它更通用。同样,您可以根据运行时类型返回一些信息:

int result = whenTypeOf(obj).    is(String.class).thenReturn(String::length).    is(Date.class).thenReturn(d -> (int) d.getTime()).    is(Number.class).thenReturn(Number::intValue).    is(TimeZone.class).thenReturn(tz -> tz.getRawOffset() / 1000).    is(MyType.class).thenReturn(7).    get();

该库从上到下检查每个is()子句,如果找到包括父类在内的第一个匹配类,则停止运行,因此is(Number.class)将同时匹配IntegerFloat。如果没有条件匹配,则调用get将失败,并带有异常。您可以使用orElse()重写此行为orElse()比等效的is(Object.class)更容易阅读):

int result = whenTypeOf(obj).    is(String.class).thenReturn(String::length).//...    orElse(42);

DSL利用Java中的静态类型的优势,几乎不可能错误地使用该库-大多数错误会在编译期间立即捕获。以下所有代码段甚至都不会编译:

//ERROR - two subsequent is()whenTypeOf(obj).is(Foo.class).is(Bar.class)//ERROR - then() without prior is()whenTypeOf(obj).then(x -> println(x))//ERROR - mixing then() and thenReturn()whenTypeOf(obj).is(Foo.class).then(foo -> println(foo)).is(Bar.class).thenReturn(bar -> bar.getB());

基本上,您首先输入whenTypeOf()Ctrl+ space会准确告诉您允许的内容。使用静态类型语言设计类型安全且健壮的DSL的关键是尽可能地限制API,以便在编译时避免无效的状态和调用。您最终将获得大量的小类 ,但这没关系,您的用户将不会看到此内容。例如,签出FirstIs.java –第一次调用is()之后返回的对象:

public class FirstIs<S, T> {final Then parent;private final S object;private final Class expectedType;public Then then(Consumer thenBlock) {if (matchingType()) {            thenBlock.accept(castObject());return new TerminalThen<>();        }return parent;    }public ThenReturn thenReturn(Function result) {if (matchingType()) {return new TerminalThenReturn<>(object, result.apply(castObject()));        }return new ThenReturn<>(object);    }public ThenReturn thenReturn(R result) {if (matchingType()) {return new TerminalThenReturn<>(object, result);        }return new ThenReturn<>(object);    }//...}

编写DSL比使用DSL困难得多,但最终还是很有收获的。注意如何使用不同的返回类型( Then vs. ThenReturn )只是为了确保在每个阶段只能访问有效的方法。另一种方法是实现运行时检查(例如,您不编写is(...).is(...).then(...))–但是为什么还要麻烦编译器为我们做呢?希望您喜欢本文,如果您愿意在项目中尝试使用此实用程序,请告诉我。它可以在GitHub上获得 。参考:来自Java和社区博客的JCG合作伙伴 Tomasz Nurkiewicz提供的Java 8中的instanceof运算符和访客模式替换 。翻译自: https://www.javacodegeeks.com/2013/10/instanceof-operator-and-visitor-pattern-replacement-in-java-8.html

今日福利?

点击阅读原文,一起玩耍

oracle无效的关系运算符_每日一课 | Java 8中的instanceof运算符和访客模式替换相关推荐

  1. java 访客模式,每日一课 | Java 8中的instanceof运算符和访客模式替换

    每日一课 | Java 8中的instanceof运算符和访客模式替换 每日一课 | Java 8中的instanceof运算符和访客模式替换 我有一个梦想,不再需要操作员和垂头丧气的instance ...

  2. instanceof运算符_Java 8中的instanceof运算符和访客模式替换

    instanceof运算符 我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTy ...

  3. Java 8中的instanceof运算符和访客模式替换

    我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTypeOf(msg).is(D ...

  4. java lt t gt 是什么意思_关于泛型:Java 7中的菱形运算符(&lt;&gt;)有什么意义?...

    Java 7中的菱形操作符允许如下代码: List list = new LinkedList<>(); 然而,在Java 5/6中,我可以简单地写: List list = new Li ...

  5. 循环斐波那契数列_每日一课 | 斐波那契数列的第n个项

    Python程序借助两种方法来计算斐波那契数列的第n个项 (有许多方法可以计算第n个项). 描述: 第一种方法:动态编程 在这种方法中,我们计算出斐波那契数列直到n的所有项,如果我们需要计算小于n的任 ...

  6. JavaScript中的instanceof运算符是什么?

    本文翻译自:What is the instanceof operator in JavaScript? The instanceof keyword in JavaScript can be qui ...

  7. java instanceof运算符_Java 中的instanceof 运算符

    Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法: res ...

  8. 每日一课 | 在Python中获取列表的长度和大小

    Python是一种非常具有表现力的语言,它提供了不同的结构来简化开发人员的工作.该列表是python提供的最受欢迎的数据结构之一.在常规工作流程中,我们在列表中添加元素或从列表中删除元素.但是在这种浮 ...

  9. 访客模式 无痕模式 区别_访客设计模式示例

    访客模式 无痕模式 区别 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如 ...

最新文章

  1. 源码资本深耕“三横九纵”科技助力网聚优秀企业
  2. Hibernate n+1问题
  3. Linux(一) 概述 、 系统安装与分区
  4. 【meitong】Windows系统受损切莫将就使用 如何快速修复
  5. 微信小程序开发工作流程
  6. 跟上!本周业界动态来了!Java周报,2019/8/10,黑客日教程
  7. EasyUI项目驱动学习
  8. pdf转json_如何显著缩小PDF文件大小?
  9. 聊天群组营销-把小米磨成粉,再做成团
  10. 别让生气毁了你的生活(深度好文)
  11. 阿里云对象存储OSS文件上传
  12. Aspose.3D使用教程:使用 Java 将 FBX 转换为 RVM 或 RVM 转换为 FBX 文件
  13. 笔记本用一段时间tapc耳机之后再用圆孔没反应。
  14. Selenium测试报错 Other element would receive the click 问题
  15. 【蓝桥杯单片机备赛】3.【SMG】共阳共阴数码管模板整理及真题实战心得
  16. 输入无线网密码后显示无法连接服务器,无线网连接失败
  17. 2022年全球与中国偏光成像相机市场现状及未来发展趋势
  18. 什么是3D角色设计?以及角色设计师的工作是什么?
  19. 支付宝服务窗关注 html,支付宝服务窗/生活号/小程序二次开发
  20. 基于Java Swing 亲属关系计算器

热门文章

  1. 华为将发布鲲鹏 920 芯片数据;三星 S10 自燃;Mageia 7 正式发布 | 极客头条
  2. 这本 Python 入门畅销书《“笨办法”学 Python 3》,不仅仅是一本书!
  3. 史上最强春节档来袭!Python 解读哪部影片值得一看?
  4. 赶超 Python 与 Java,JavaScript 问鼎最受欢迎的编程语言
  5. Java 10 正式发布!时隔 6 月带来 109 项新特性
  6. 邪恶的编码魔咒,你中招没?
  7. javaweb实训第一天作业练习
  8. power bulider 9.0 如何将sql语句查询的值返回给变量_SQL—你应该知道的子查询
  9. mysql递归查询树,帮你突破瓶颈
  10. go back go fullscreen_四款高端便携音箱TUFTON、B17、MUSIC3和GO+PLAY音质排行榜