基于TODO的开发方法
之前买了一本书,叫《架构探险—从零开始写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
基于TODO的开发方法的更多相关文章
- 基于微软XAML技术的前端开发方法
使用XAML技术的平台目前包括WPF,Silverlight,Windows8等平台,未来的Windows10统一Windows App也使用XAML技术. 前端开发指通过可视化集成开发环境进行用户界 ...
- 公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享
公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享 在这个文章里面我将用一个实际的案例来分享如何来构建一个能够接受3000+个连接的GPRS通讯服务器软件,这个软件被我认为是一个艺术品,实现周期为 ...
- 基于vue模块化开发后台系统——准备工作
文章目录如下:项目效果预览地址项目开源代码基于vue模块化开发后台系统--准备工作基于vue模块化开发后台系统--构建项目基于vue模块化开发后台系统--权限控制 前言 本文章是以学习为主,练习一下v ...
- 基于Laravel+Swoole开发智能家居后端
基于Laravel+Swoole开发智能家居后端 在上一篇<Laravel如何优雅的使用Swoole>中我已经大概谈到了Laravel结合Swoole的用法. 今天,我参与的智能家居项目基 ...
- Atitit.研发管理--提升效率--软件开发方法DSM总结o99
Atitit.研发管理--提升效率--软件开发方法DSM总结o99 1. 什么是DSM? 1 2. DSM使用的语言DSL 2 3. 模型的优点 2 4. DSM 跟与MDA区别 2 5. MDA的实 ...
- 项目的敏捷开发方法(转自MBAlib)
项目的敏捷开发方法 敏捷方法很多,包括 Scrum.极限编程.功能驱动开发以及统一过程(RUP)等多种法,这些方法本质实际上是一样的,敏捷开发小组主要的工作方式可以归纳为:作为一个整体工作: 按短迭代 ...
- 【翻译】十大要避免的Ext JS开发方法
原文地址:http://www.sencha.com/blog/top-10-ext-js-development-practices-to-avoid/ 作者:Sean Lanktree Sean ...
- 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
随机推荐
- android判断网络是否可用
private boolean isNetworkConnected(Context context) { ConnectivityMannger cManager = (ConnectivityMa ...
- 为你的APK进行数字签名
摘要: 我们需要为 APK进行数字签名,这样才能发布到 Google Play商店.解决方法很简单,使用 Java的keytool命令创建证书并在 Gradle构建文件的 signingConfigs ...
- R语言︱LDA主题模型——最优主题数选取(topicmodels)+LDAvis可视化(lda+LDAvis)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:在自己学LDA主题模型时候,发现该模 ...
- Hybrid APP 架构设计思路
关于Hybrid模式开发app的好处,网络上已有很多文章阐述了,这里不展开. 本文将从以下几个方面阐述Hybrid app架构设计的一些经验和思考. 原文及讨论请到 github issue 通讯 作 ...
- servlet上传文件报错(三)
1.具体报错如下 null null Exception in thread "http-apr-8686-exec-5" java.lang.OutOfMemoryError: ...
- class-提升方法Boosting
1 AdaBoost算法2 AdaBoost训练误差分析3 AdaBoost algorithm 另外的解释3.1 前向分步算法3.2 前向分步算法与AdaBoost4 提升树4.1 提升树模型4.2 ...
- java的几种引用之二
import java.lang.ref.PhantomReference;import java.lang.ref.ReferenceQueue;import java.lang.ref.SoftR ...
- 浅谈MySQL的优化
平时在开发中大多在写业务逻辑,很少关注于底层sql的执行效率,大多能交给batis的mapper做的就交给它去做. 然而这些天越来越发现,大家还是很愿意手写sql的,往往一段业务逻辑,可以用稍微复杂一 ...
- java实现中文分词
IK Analyzer是基于lucene实现的分词开源框架 下载路径:http://so.csdn.net/so/search/s.do?q=IKAnalyzer2012.jar&t=doc& ...
- 【BZOJ1899】午餐(动态规划)
[BZOJ1899]午餐(动态规划) 题面 BZOJ 题解 我太弱了 这种\(dp\)完全做不动.. 首先,感性理解一些 如果所有人都要早点走, 那么,吃饭时间长的就先吃 吃饭时间短的就晚点吃 所以, ...