摘要:靜態構造方法靜態構造方法的語義和簡化程度真的高于直接去一個對象。當然,看過很多源碼以后,我想相信將靜態構造方法換成會先的更加簡潔測試代碼當然他仍然是支持鏈式調用的這樣來寫代碼,真的很簡潔,并且可讀性很強。
擁抱 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 的程序員吧。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/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...
閱讀 3114·2023-04-26 01:58
閱讀 958·2021-11-24 09:38
閱讀 3291·2021-09-03 10:29
閱讀 721·2021-08-21 14:10
閱讀 1494·2019-08-30 15:44
閱讀 3094·2019-08-30 14:10
閱讀 3218·2019-08-29 16:32
閱讀 1484·2019-08-29 12:48