java链式编程_Java链式编程学习
Java链式编程
在使用jquery时肯定对它的链式编程惊艳到,慢慢的其它语言这种编程模式也逐渐增多。其本身并不复杂,在调用方法时,方法最后返回对象本身,以达到链式编程的效果。
链式编程比较简单,只要return this即可具有相应的编程模式,但是需要根据业务需求使用不同的方法方式进行实现。
简单的链式编程
既然使用return this可以实现链式模式,那就依次为方案,实现一个简单的例子。
public class Book {
private String bookId;
private String title;
private String cover;
public String getBookId() {
return bookId;
}
public Book setBookId(String bookId) {
this.bookId = bookId;
// 返回当前对象
return this;
}
public String getTitle() {
return title;
}
public Book setTitle(String title) {
this.title = title;
// 返回当前对象
return this;
}
public String getCover() {
return cover;
}
public Book setCover(String cover) {
this.cover = cover;
// 返回当前对象
return this;
}
@Override
public String toString() {
return "Book{" +
"bookId='" + bookId + '\'' +
", title='" + title + '\'' +
", cover='" + cover + '\'' +
'}';
}
}
代码比较简单,就是一个图书的模型,将三个字段的Set方法都返回了对象本身。看一下调用
public static void main(String[] args) {
Book book = new Book().setBookId("b.001").setTitle("庆余年").setCover("http://localhost/qyn.jpg");
System.out.println(book);
}
// Book{bookId='b.001', title='庆余年', cover='http://localhost/qyn.jpg'}
编码过程中,完成一个Set方法后按下.就会继续提醒其他方法,实现了链式编程的效果。并且最终结果也符合预期。
静态初始化方法of
目前Spring中有很多方法提供了静态of方法,可以更方便的创建对象,结合return this将更为实用的实现链式编程,算是一种比较不错得扩展措施。在这种模式中,大量的使用了of替代了构造函数。
public class Pageable {
// 页码,从1开始
private long page;
// 页大小
private int size;
// 结果命中数量
private long count;
private Pageable(long page, int size) {
this.page = page;
this.size = size;
}
private Pageable(long page, int size, long count) {
this(page, size);
this.count = count;
}
// PageRequest时使用
public static Pageable of(long page, int size) {
return of(page, size, 0);
}
// 返回结果时,具有命中数量及返回总页码计算使用
public static Pageable of(long page, int size, long count) {
return new Pageable(page, size, count);
}
// 分页时,获取偏移量
public long getOffset() {
return (page - 1) * size;
}
// 返回总页码
public long getPageCount() {
return (long) Math.ceil((double) count / size);
}
public long getPage() {
return this.page;
}
public int getSize() {
return this.size;
}
public long getCount() {
return this.count;
}
}
上面示例中的分页工具类,只实现了三个成员变量页码、页大小、条目数,并且未实现成员变量的Set方法;构造方法全部为私有,实现了静态的of方法来创建分页对象。在该对象中同时提供了获取分页偏移量的getOffset方法,以及计算出总页码的getPageCount方法。
该工具一般有两种使用场景:
数据库查询后,返回数据列表以及分页信息,此时需要页码、页大小、条目数三个信息,使用及实现都比较方便
内存分页时,可以提供一个分页偏移量的计算方法
public static void main(String[] args) {
Pageable pageable = Pageable.of(10, 10, 123);
System.out.println(pageable.getOffset());
System.out.println(pageable.getPageCount());
}
// 90
// 13
如果采用FastJson进行序列化,上述设计方式也能够满足返回JSON的需求,FastJson按照Get方法进行生成属性列表。
public static void main(String[] args) {
System.out.println(JSON.toJSONString(Pageable.of(10, 10, 123)));
}
// {"count":123,"offset":90,"page":10,"pageCount":13,"size":10}
Builder模式链式编程
Builder模式也是目前较为常用的一种链式编程方法,目前Spring中有大量的依据此模式进行的编码。以最为常见的ResponseEntity(或者Swagger模块也大量采用了此类方法)类来看,其内部定义了Builder接口,并默认实现了一个DefaultBuild内部类,内部方法采用return this实现链式模式,同时在ResponseEntity中提供了类似的Builder方法,如ok、status等静态方法。
从这些类的实现原理看,实现Builder模式也比较简单,一方面创建一个内部Builder类,实现相应信息的创建;同时在目标类中,实现一个静态的builder方法,用于创建Builder对象,并启动链式模式;最后再由内部类提供一个终止方法,该终止方法将完成目标类的创建。
public class ApiInfo {
private String name;
private String description;
private String url;
private Map params;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map getParams() {
return params;
}
public void setParams(Map params) {
this.params = params;
}
@Override
public String toString() {
return "ApiInfo{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", url='" + url + '\'' +
", params=" + params +
'}';
}
public static ApiBuilder builder() {
return new ApiBuilder();
}
// 内部Builder类
public static class ApiBuilder {
private String name;
private String description;
private String url;
private Map params;
// name信息设置,链式
public ApiBuilder name(String name) {
this.name = name;
return this;
}
// 注释信息设置
public ApiBuilder description(String description) {
this.description = description;
return this;
}
public ApiBuilder url(String url) {
this.url = url;
return this;
}
// 参数信息设置
public ApiBuilder params(String name, String description) {
this.params = Optional.ofNullable(params).orElseGet(() -> Maps.newHashMap());
this.params.put(name, description);
return this;
}
// 创建ApiInfo对象
public ApiInfo build() {
ApiInfo apiInfo = new ApiInfo();
apiInfo.setName(this.name);
apiInfo.setDescription(this.description);
apiInfo.setUrl(this.url);
apiInfo.setParams(this.params);
return apiInfo;
}
}
}
上述示例采用Builder模式实现了一个Api接口信息的对象设计,主要是能够设置接口名、地址以及相应的参数。内部设计了一个ApiBuilder,可以实现链式属性设置,并最终提供一个build方法用于终止时创建目标实例。
public static void main(String[] args) {
ApiInfo apiInfo = ApiInfo.builder().name("获取资源信息")
.description("根据资源ID获取资源信息")
.url("/resource/:id")
.params("id", "资源唯一ID")
.params("token", "令牌")
.build();
System.out.println(apiInfo);
}
// ApiInfo{name='获取资源信息', description='根据资源ID获取资源信息', url='/resource/:id', params={id=资源唯一ID, token=令牌}}
lombok链式编程
链式编程比较简单,一般也就是return、静态of、Builder几种模式,可以直接编码实现,Spring以及一些开源项目Swagger等等都是这么做的。如果我们不是为了做一个通用的开源产品,只是业务性的编码,此时不需要通过大量的编码去实现链式编程,可以采用lombok进行实现,使用也比较简单。
使用lombok时,可以通过maven引入,也可以通过idea安装插件的方式引入。
return链式
仍然使用此前的例子Book类,进行改造,采用lombok注解进行编码。
lombok实现return this链式,只需要在类添加注释@Accessors(chain = true)即可实现
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class Book {
private String bookId;
private String title;
private String cover;
public static void main(String[] args) {
Book book = new Book().setBookId("b.001").setTitle("庆余年").setCover("http://localhost/qyn.jpg");
System.out.println(book);
}
}
如果在IDE中,查看类接口(ctrl+o),可以发现属性的Set方法,返回类型为Book,和自己编码的方案一致。
public static void main(String[] args) {
Book book = new Book().setBookId("b.001").setTitle("庆余年").setCover("http://localhost/qyn.jpg");
System.out.println(book);
}
// Book{bookId='b.001', title='庆余年', cover='http://localhost/qyn.jpg'}
静态初始化方法
对Pageable类进行改造,使用lombok实现of方法。
静态of方法的添加,需要通过lombok的构造函数注解进行添加,RequiredArgsConstructor可以实现必备参数列表的构造,并通过staticname指定静态方法为of;针对上例中的Pageable对象提供了两种静态构造方法,一种是只需要指定页码和页大小即可,还有一种是全部参数的构造函数,可以计算总页码;RequiredArgsConstructor可以实现必备参数的构造;AllArgsConstructor实现全部参数的构造函数,并指定staticName为of,通过lombok的注解组合,实现Pageable与上例自己编码同等效果。
@Getter
@ToString
@Accessors(chain = true)
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(staticName = "of")
public class Pageable {
/**
* 页码,从1开始
*/
@NonNull
private long page;
/**
* 页大小
*/
@NonNull
private int size;
/**
* 结果命中数量
*/
private long count;
/**
* 分页时,获取偏移量
*
* @return
*/
public long getOffset() {
return (page - 1) * size;
}
/**
* 返回总页码
*
* @return
*/
public long getPageCount() {
return (long) Math.ceil((double) count / size);
}
}
通过组合注释实现了同样的效果,使用也和原有编码效果等同。
public static void main(String[] args) {
Pageable pageable = Pageable.of(10, 10);
System.out.println(pageable.getOffset());
// 全部构造
System.out.println(JSON.toJSONString(Pageable.of(10, 10, 123)));
}
// 90
// {"count":123,"offset":90,"page":10,"pageCount":13,"size":10}
Builder模式
对ApiInfo进行改造,使用lombok实现builder模式。
lombok实现Builder模式,只要添加@Builder注解即可
@Getter
@Setter
@Builder
@ToString
public class ApiInfo {
private String name;
private String description;
private String url;
private Map params;
}
使用上和之前的例子差不多,不过对于params默认只能是Set的形式。
public static void main(String[] args) {
ApiInfo apiInfo = ApiInfo.builder().name("获取资源信息")
.description("根据资源ID获取资源信息")
.url("/resource/:id")
.params(new HashMap() {
{
put("id", "资源唯一ID");
put("token", "令牌");
}
})
.build();
System.out.println(apiInfo);
}
// ApiInfo(name=获取资源信息, description=根据资源ID获取资源信息, url=/resource/:id, params={id=资源唯一ID, token=令牌})
java链式编程_Java链式编程学习相关推荐
- java链式编程_Java 链式编程 和 lombok 实现链式编程
一.链式编程定义 链式编程的原理就是返回一个this对象,就是返回本身,达到链式效果. 二.jdk中 StringBuffer 源码 我们经常用的 StringBuffer 就是 实现了链式的写法. ...
- 用java编写图形用户界面_Java图形用户界面编程
GUI代表图形用户界面(Graphical User Interface),Java API中提供了两套组件用户支持编写图形用户界面,包括AWT和Swing. AWT使用本地操作系统的代码资源,被称为 ...
- Java面向事件编程_Java面向事件编程
基于Java的基础课程给教师和学生都提出了新的挑战.虽然Java要比C++简单,但Java作为一种具有大量标准库的面向对象语言这一事实既带来了新的复杂性,同时也带来了新的机会.. 本书作为计算机科学基 ...
- Java8链式调用_java链式调用(转载http://www.cnblogs.com/quiet-snowy-day/p/6091233.html)
记录最近在项目设计中遇到的一个小问题. 前提:有这样两个POJO类,它们都可以通过链式调用的方式来设置其属性值,其中一个类继承了另一个类. 问题:通过链式调用,子类对象访问父类方法后,如何使返回对象仍 ...
- java 图形化编程_java图形化编程
转载 学习Java Swing图形化编程,我们首先要了解三个最基本的概念:顶层容器,控件,布局. 下面就来介绍一下这三个基本概念 1.顶层容器 什么是顶层容器?当我们使用Java进行图形编程的时候,图 ...
- java 接口编程_JAVA面向接口编程
一.什么是面向接口编程 要正确地使用Java语言进行面向对象的编程,从而提高程序的复用性,增加程序的可维护性.可扩展性,就必须是面向接口的编程.面向接口的编程就意味着:开发系统时,主体构架使用接口,接 ...
- java校招面试题_java校招面试编程题及答案.docx
java校招面试编程题及答案 java校招面试编程题及答案 Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 集合框 ...
- java网络编程_Java基础 网络编程
主要内容 软件架构CS/BS 网络通信三要素 TCP通信 Socket套接字 ServerSocket 教学目标 能够辨别UDP和TCP协议特点 能够说出TCP协议下两个常用类名称 能够编写TCP协议 ...
- Java ME游戏编程_Java ME游戏编程(第2版)
Java ME游戏编程(第2版) 作者:(美)帕特里克(Patrick,J.J.)著 出版日期:2009年03月 文件大小:25.45M 支持设备: ¥25.00在线试读 适用客户端: 言商书局 iP ...
最新文章
- java网络编程udp_java网络编程 UDP网络编程问题
- Composer 本地路径加载 laravel-admin 扩展包
- Kubernetes系列之Helm介绍篇
- 34观察者模式(Observer Pattern)
- NoSQL那些事--Redis
- 作者:牛怡晗,女,就职于上海浦东发展银行昆明分行。
- 信息学奥赛一本通C++语言——1057:简单计算器
- [原]CentOS 6.5 上安装 MySQL 5.6
- 华三中各种路由协议的缺省优先级
- css3 animation 位置移动了怎么不占位置_手把手整理CSS3知识汇总【思维导图】
- 常见 MIME 类型列表
- 利用Python生成钢琴音色
- ELK-logstash 的 grok与dissect 测试应用
- bzoj 1127 [POI2008]KUP——思路(悬线法)
- Mac系统验证文件的MD5/SHA1/SHA256
- 显示器是个人计算机上的一个重要输出设备,东大17秋学期《计算机应用基础》在线作业123满分答案...
- 运输层----ARQ 协议 ---- 连续 ARQ 协议
- 【t042】炮击坦克
- 【Vue】Vue中mixins的使用方法及实际项目应用详解
- 16S 物种丰度热图学习
热门文章
- MySQL冷备份过程
- 数据库中ISNULL,IFNULL,NULLIF 函数的区别是什么?
- LeetCode-【动态规划】-完全平方数
- python鼻祖_科技日历| 61年前,ALGOL语言创立!它是C语言等高级语言的直接“鼻祖”...
- 如何管理银行多网点监控?用这方法就够了!
- NAT和PAT的原理及配置
- Visual C++使用入门级教程
- 运行截图之SpringCloud企业分布式微服务云架构快速开发平台源码
- Linux系统终止httpd服务,【转】Linux下apache/httpd服务启动与停止
- iOS 16发热耗电严重怎么办?iOS 16发热耗电解决办法分享