摘要:静态构造方法静态构造方法的语义和简化程度真的高于直接去一个对象。当然,看过很多源码以后,我想相信将静态构造方法换成会先的更加简洁测试代码当然他仍然是支持链式调用的这样来写代码,真的很简洁,并且可读性很强。
拥抱 lombok,它会帮助我们解决一些让我们很烦躁的问题
去掉 Setter 和 Getter@Setter @Getter public class UserDTO { @NotNull private String username; @NotNull private int age; public User convertToUser(){ UserDTOConvert userDTOConvert = new UserDTOConvert(); User convert = userDTOConvert.convert(this); return convert; } public UserDTO convertFor(User user){ UserDTOConvert userDTOConvert = new UserDTOConvert(); UserDTO convert = userDTOConvert.reverse().convert(user); return convert; } private static class UserDTOConvert extends Converter{ @Override protected User doForward(UserDTO userDTO) { User user = new User(); BeanUtils.copyProperties(userDTO,user); return user; } @Override protected UserDTO doBackward(User user) { throw new AssertionError("不支持逆向转化方法!"); } } }
看到了吧,烦人的 Getter 和 Setter 方法已经去掉了。
bean 中的链式风格改造前
public class Student { private String name; private int age; public String getName() { return name; } public Student setName(String name) { this.name = name; return this; } public int getAge() { return age; } public Student setAge(int age) { return this; } }
相信合理使用这样的链式代码,会更多的程序带来很好的可读性,那看一下如果使用 lombok 进行改善呢,请使用 @Accessors(chain = true),看如下代码:
@Accessors(chain = true) @Setter @Getter public class Student { private String name; private int age; }
这样就完成了一个对于 bean 来讲很友好的链式操作。
静态构造方法静态构造方法的语义和简化程度真的高于直接去 new 一个对象。比如 new 一个 List 对象,过去的使用是这样的:
Listlist = new ArrayList<>();
看一下 guava 中的创建方式:
Listlist = Lists.newArrayList();
Lists 命名是一种约定(俗话说:约定优于配置),它是指 Lists 是 List 这个类的一个工具类,那么使用 List 的工具类去产生 List,这样的语义是不是要比直接 new 一个子类来的更直接一些呢,答案是肯定的,再比如如果有一个工具类叫做 Maps,那你是否想到了创建 Map 的方法呢:
HashMapobjectObjectHashMap = Maps.newHashMap();
接上上边的静态构造方法和必传参数的构造方法,使用 lombok 将更改成如下写法(@RequiredArgsConstructor 和 @NonNull):
@Accessors(chain = true) @Setter @Getter @RequiredArgsConstructor(staticName = "ofName") public class Student { @NonNull private String name; private int age; }
测试代码:
Student student = Student.ofName("zs");
这样构建出的 bean 语义是否要比直接 new 一个含参的构造方法(包含 name 的构造方法)要好很多。
当然,看过很多源码以后,我想相信将静态构造方法 ofName 换成 of 会先的更加简洁:
@Accessors(chain = true) @Setter @Getter @RequiredArgsConstructor(staticName = "of") public class Student { @NonNull private String name; private int age; }
测试代码:
Student student = Student.of("zs");
当然他仍然是支持链式调用的:
Student student = Student.of("zs").setAge(24);
这样来写代码,真的很简洁,并且可读性很强。
使用 builder@Builder public class Student { private String name; private int age; }
调用方式:
Student student = Student.builder().name("zs").age(24).build();代理模式
正如我们所知的,在程序中调用 rest 接口是一个常见的行为动作,如果你和我一样使用过 spring 的 RestTemplate,我相信你会我和一样,对他抛出的非 http 状态码异常深恶痛绝。
所以我们考虑将 RestTemplate 最为底层包装器进行包装器模式的设计:
public abstract class FilterRestTemplate implements RestOperations { protected volatile RestTemplate restTemplate; protected FilterRestTemplate(RestTemplate restTemplate){ this.restTemplate = restTemplate; } //实现RestOperations所有的接口 }
然后再由扩展类对 FilterRestTemplate 进行包装扩展:
public class ExtractRestTemplate extends FilterRestTemplate { private RestTemplate restTemplate; public ExtractRestTemplate(RestTemplate restTemplate) { super(restTemplate); this.restTemplate = restTemplate; } publicRestResponseDTO postForEntityWithNoException(String url, Object request, Class responseType, Object... uriVariables) throws RestClientException { RestResponseDTO restResponseDTO = new RestResponseDTO (); ResponseEntity tResponseEntity; try { tResponseEntity = restTemplate.postForEntity(url, request, responseType, uriVariables); restResponseDTO.setData(tResponseEntity.getBody()); restResponseDTO.setMessage(tResponseEntity.getStatusCode().name()); restResponseDTO.setStatusCode(tResponseEntity.getStatusCodeValue()); }catch (Exception e){ restResponseDTO.setStatusCode(RestResponseDTO.UNKNOWN_ERROR); restResponseDTO.setMessage(e.getMessage()); restResponseDTO.setData(null); } return restResponseDTO; } }
包装器 ExtractRestTemplate 很完美的更改了异常抛出的行为,让程序更具有容错性。在这里我们不考虑 ExtractRestTemplate 完成的功能,让我们把焦点放在 FilterRestTemplate 上,“实现 RestOperations 所有的接口”,这个操作绝对不是一时半会可以写完的,当时在重构之前我几乎写了半个小时,如下:
public abstract class FilterRestTemplate implements RestOperations { protected volatile RestTemplate restTemplate; protected FilterRestTemplate(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Override publicT getForObject(String url, Class responseType, Object... uriVariables) throws RestClientException { return restTemplate.getForObject(url,responseType,uriVariables); } @Override public T getForObject(String url, Class responseType, Map uriVariables) throws RestClientException { return restTemplate.getForObject(url,responseType,uriVariables); } @Override public T getForObject(URI url, Class responseType) throws RestClientException { return restTemplate.getForObject(url,responseType); } @Override public ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables) throws RestClientException { return restTemplate.getForEntity(url,responseType,uriVariables); } //其他实现代码略。。。 }
我相信你看了以上代码,你会和我一样觉得恶心反胃,后来我用 lombok 提供的代理注解优化了我的代码(@Delegate):
@AllArgsConstructor public abstract class FilterRestTemplate implements RestOperations { @Delegate protected volatile RestTemplate restTemplate; }
这几行代码完全替代上述那些冗长的代码。
是不是很简洁,做一个拥抱 lombok 的程序员吧。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/74214.html
摘要:总是看到类似的九宫格抽奖效果后来想自己手撸一个试一试吧。多多尝试万一成功了呢先来总结一下效果类似与跑马灯效果,闪动效果先快后慢。 总是看到类似的九宫格抽奖效果,后来想自己手撸一个试一试吧。(多多尝试,万一成功了呢 github L6zt) 先来总结一下效果,类似与跑马灯效果,闪动效果先快后慢。代码解析如下所示:代码 0 ...
摘要:总是看到类似的九宫格抽奖效果后来想自己手撸一个试一试吧。多多尝试万一成功了呢先来总结一下效果类似与跑马灯效果,闪动效果先快后慢。 总是看到类似的九宫格抽奖效果,后来想自己手撸一个试一试吧。(多多尝试,万一成功了呢 github L6zt) 先来总结一下效果,类似与跑马灯效果,闪动效果先快后慢。代码解析如下所示:代码 0 ...
摘要:深拷贝概念并不新鲜,但是真正要真正理解原理还是有点难度的。这也是语言精粹之一吧。 JS深拷贝概念并不新鲜,但是真正要真正理解原理还是有点难度的。这也是JS语言精粹之一吧。 例子 let a = { name: demo, age: 18 }; let b = a; b.name = demo1; console.log(a); // 输出 {name: demo1,...
摘要:滚动插件设计原理获取滚动元素的视口高度和滚动高度得出滚动轴最大滚动距离根据滚动时计算滚动时滚动轴的滚动高度与比较做差,判断是否触发动作。 // github L6zt滚动插件设计原理 获取滚动元素的视口高度viewH和滚动高度scrollH,得出 滚动轴最大滚动距离 scrollMaxTop = viewH - scrollH; 根据滚动时计算滚动时滚动轴的滚动高度 scrollTo...
摘要:滚动插件设计原理获取滚动元素的视口高度和滚动高度得出滚动轴最大滚动距离根据滚动时计算滚动时滚动轴的滚动高度与比较做差,判断是否触发动作。 // github L6zt滚动插件设计原理 获取滚动元素的视口高度viewH和滚动高度scrollH,得出 滚动轴最大滚动距离 scrollMaxTop = viewH - scrollH; 根据滚动时计算滚动时滚动轴的滚动高度 scrollTo...
阅读 3050·2023-04-26 01:58
阅读 927·2021-11-24 09:38
阅读 3255·2021-09-03 10:29
阅读 690·2021-08-21 14:10
阅读 1469·2019-08-30 15:44
阅读 3049·2019-08-30 14:10
阅读 3161·2019-08-29 16:32
阅读 1444·2019-08-29 12:48