之前買了一本書,叫《架構探險—從零開始寫Java Web框架 》(不推薦購買~),一本標題黨書籍!但是我很推崇作者寫程式碼的方式,就是基於TODO的方式進行開發!
個人認為以基於TODO的方式進行開發,至少有如下幾點優勢:
- 有助於理解需求
- 有助於梳理業務流程
- 有助於任務拆解和程式碼封裝
- TODO即註釋
- 更易於進入心流體驗
同時還能避免如下兩種情況:
下面我以Blog的建立流程為例,來演示基於TODO的開發方式,並說明為何基於TODO的開發方式有如上優勢!
後端的開發框架請見Web開發框架推導!
流程演示
後端開發流程
基於上面的開發框架,整體流程就是Controller->Service->Mapper->Database! 就Blog建立流程來說,我們會有BlogController->BlogService->BlogMapper->Database的流程! 那我們的開發流程如下:
Step1:
@RestController
public class BlogController{
//todo 建立blog流程
//todo 接收引數
//todo 驗證欄位
//todo 構建Model
//todo 委託BlogService
//todo 返回blog主鍵
//todo 處理可能異常
}
@Service
public class BlogService{
//todo 建立blog
//todo 設定建立資訊
//todo 委託blogMapper執行
//todo 返回主鍵
}
複製程式碼
Step2:
@RestController
public class BlogController{
//建立blog流程
@PostMapping("/blog")
public Long create(BlogDto blog){
//todo 接收引數
//todo 驗證欄位
//todo 構建Model
//todo 委託BlogService
//todo 返回blog主鍵
//todo 處理可能異常
return null;
}
}
複製程式碼
Step3:
@RestController
public class BlogController{
//建立blog流程
//接收引數
@PostMapping("/blog")
public Long create(@RequestBody @Validated BlogDto blog, BindingResult result){
//驗證欄位
if (bindResult.hasErrors()) {
throw new BindingException(bindResult.getFieldError().getDefaultMessage());
}
//todo 構建Model
//todo 委託BlogService
//todo 返回blog主鍵
//todo 處理可能異常
return null;
}
}
複製程式碼
Step4:
@RestController
public class BlogController{
//建立blog流程
//接收引數
@PostMapping("/blog")
public ResponseEntity create(@RequestBody @Validated BlogDto blogDto, BindingResult result){
//驗證欄位
if (bindResult.hasErrors()) {
throw new BindingException(bindResult.getFieldError().getDefaultMessage());
}
//構建Model
Blog blog = BeanUtils.copyProperties(blogDto,Blog.class);
//todo 委託BlogService
//todo 返回blog主鍵
//todo 處理可能異常
return ResponseEntity.ok("");
}
}
複製程式碼
Step5:
@RestController
public class BlogController{
@Autowired
private BlogService blogService;
//建立blog流程
//接收引數
@PostMapping("/blog")
public ResponseEntity create(@RequestBody @Validated BlogDto blogDto, BindingResult result){
//驗證欄位
if (bindResult.hasErrors()) {
throw new BindingException(bindResult.getFieldError().getDefaultMessage());
}
//構建Model
Blog blog = BeanUtils.copyProperties(blogDto,Blog.class);
//委託BlogService
Long recId = blogService.create(blog);
//todo 返回blog主鍵
//todo 處理可能異常
return ResponseEntity.ok("");
}
}
@Service
public class BlogService{
//建立blog
public Long create(Blog blog){
//todo 設定建立資訊
//todo 委託blogMapper執行
//todo 返回主鍵
return null;
}
}
複製程式碼
Step6:
@RestController
public class BlogController{
@Autowired
private BlogService blogService;
//建立blog流程
//接收引數
@PostMapping("/blog")
public ResponseEntity create(@RequestBody @Validated BlogDto blogDto, BindingResult result){
//驗證欄位
if (bindResult.hasErrors()) {
throw new BindingException(bindResult.getFieldError().getDefaultMessage());
}
//構建Model
Blog blog = BeanUtils.copyProperties(blogDto,Blog.class);
//委託BlogService
Long recId = blogService.create(blog);
//返回blog主鍵
return ResponseEntity.ok(recId);
//todo 處理可能異常
}
}
複製程式碼
Step7:
@RestController
public class BlogController{
@Autowired
private BlogService blogService;
//建立blog流程
//接收引數
@PostMapping("/blog")
public ResponseEntity create(@RequestBody @Validated BlogDto blogDto, BindingResult result){
try{
//驗證欄位
if (bindResult.hasErrors()) {
throw new BindingException(bindResult.getFieldError().getDefaultMessage());
}
//構建Model
Blog blog = BeanUtils.copyProperties(blogDto,Blog.class);
//委託BlogService
Long recId = blogService.create(blog);
//返回blog主鍵
return ResponseEntity.ok(recId);
}catch (BusinessException e) {
//處理可能異常
logger.error("Create Blog Error!", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Create Blog Error!" + e.getMessage());
} catch (Exception e) {
logger.error("Create Blog Error!", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Create Blog Error!" + e.getMessage());
}
}
}
複製程式碼
Step8:
@Service
public class BlogService{
//建立blog
public Long create(Blog blog){
//設定建立資訊
Long userId = UserContext.getUser().getUserId();
blog.setCreateId(userId);
blog.setUpdateId(userId);
blog.setCreateTime(new Date());
blog.setUpdateTime(new Date());
//todo 委託blogMapper執行
//todo 返回主鍵
return null;
}
}
複製程式碼
Step9:
@Service
public class BlogService{
@Autowired
private BlogMapper blogMapper;
//建立blog
public Long create(Blog blog){
//設定建立資訊
Long userId = UserContext.getUser().getUserId();
blog.setCreateId(userId);
blog.setUpdateId(userId);
blog.setCreateTime(new Date());
blog.setUpdateTime(new Date());
//委託blogMapper執行
blogMapper.insert(blog);
//todo 返回主鍵
return null;
}
}
複製程式碼
Step10:
@Service
public class BlogService{
@Autowired
private BlogMapper blogMapper;
//建立blog
public Long create(Blog blog){
//設定建立資訊
Long userId = UserContext.getUser().getUserId();
blog.setCreateId(userId);
blog.setUpdateId(userId);
blog.setCreateTime(new Date());
blog.setUpdateTime(new Date());
//委託blogMapper執行
blogMapper.insert(blog)
//返回主鍵
return blog.getRecId();
}
}
複製程式碼
前端開發流程
前端的開發除了需要處理程式碼邏輯,還需要處理頁面流程!依然可以以TODO的方式來處理,藉助於a標籤和按鈕,可以把頁面流給串起來! 接著上面的Blog的CRUD邏輯,這裡僅列出示例,不再演示流程,開發流程和上面的流程一致!
list.html:
<!-- todo 新增Blog-->
<a href="new.html">新增</a>
<!--TODO 搜尋-->
<!--TODO 列表顯示,操作-->
<table>
<tr>
<td>
<a href="view.html">檢視</a>
<a href="edit.html">編輯</a>
<a href="delete.html">刪除</a>
</td>
</tr>
</table>
<!--TODO 翻頁-->
複製程式碼
new.html:
<!--todo 表單欄位-->
<!--todo 驗證規則-->
<!--todo 儲存邏輯-->
<a href="list.html">儲存按鈕</a>
<!--todo 取消邏輯-->
<a href="list.html">取消按鈕</a>
複製程式碼
view.html:
<!--todo 展示欄位-->
<!--todo 返回邏輯,按場景返回?-->
<a href="list.html">返回按鈕</a>
複製程式碼
edit.html:
<!--todo 表單欄位-->
<!--todo 欄位賦值-->
<!--todo 驗證規則-->
<!--todo 儲存邏輯-->
<a href="list.html">儲存按鈕</a>
<!--todo 取消邏輯-->
<a href="list.html">取消按鈕</a>
複製程式碼
優勢
首先問一個問題,對於你接收到的資訊,你是以什麼樣的標準來評判你理解了或學會了?就是__用你自己的話再說一遍__! 基於TODO的開發方法就是以此為基礎:
- 首先基於需求,以TODO文字的形式將業務流程寫下來。寫下來以後,可以和需求去確認,修正偏差,既__有助於理解需求__也__有助於梳理業務流程__
- 同時,可以看出,每個TODO的工作量都比較小,實際上也起到了__任務拆解和程式碼封裝__的作用。既然任務拆解了,編寫的程式碼也就相應的被拆解為一個個的功能程式碼了。當然對於邏輯較複雜的程式碼,還是需要使用重構手段,來進一步的對程式碼進行封裝
- 程式碼編寫完後,不需要將TODO完全刪除,只需要把TODO字樣去除,__TODO就變成了註釋__了!
- 由於每個TODO的實現時間都較短(主要看拆解得如何),你開發的每個小功能,實際上都是在解決一個TODO,就像遊戲裡的打怪一樣,能得到__準即時反饋__,心理得到滿足!這是__進入心流體驗__的一個必要條件!
關於心流體驗:
- 心流英文叫"flow",我第一次見到這個詞是在《人件》這本書上!這是兩年前寫的讀書筆記《我的管理實踐---《人件》讀後感》!
- 心流的解釋有很多,有興趣的可以去搜尋一下
- 相信很多人都經歷過,比如你做某件事時很專注(寫程式碼、玩遊戲等等),當做完後,你以為沒多長時間,但是回過神來一看,好幾個小時已經過去了!
寫在最後
本文只是演示了一種個人比較推崇的寫程式碼的方式,並解釋了為什麼推崇這種方式!當然,僅供參考!畢竟 適合自己的才是最好的!
公眾號:ivaneye