之前买了一本书,叫《架构探险—从零开始写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的开发方法的更多相关文章

  1. 基于微软XAML技术的前端开发方法

    使用XAML技术的平台目前包括WPF,Silverlight,Windows8等平台,未来的Windows10统一Windows App也使用XAML技术. 前端开发指通过可视化集成开发环境进行用户界 ...

  2. 公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享

    公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享 在这个文章里面我将用一个实际的案例来分享如何来构建一个能够接受3000+个连接的GPRS通讯服务器软件,这个软件被我认为是一个艺术品,实现周期为 ...

  3. 基于vue模块化开发后台系统——准备工作

    文章目录如下:项目效果预览地址项目开源代码基于vue模块化开发后台系统--准备工作基于vue模块化开发后台系统--构建项目基于vue模块化开发后台系统--权限控制 前言 本文章是以学习为主,练习一下v ...

  4. 基于Laravel+Swoole开发智能家居后端

    基于Laravel+Swoole开发智能家居后端 在上一篇<Laravel如何优雅的使用Swoole>中我已经大概谈到了Laravel结合Swoole的用法. 今天,我参与的智能家居项目基 ...

  5. Atitit.研发管理--提升效率--软件开发方法DSM总结o99

    Atitit.研发管理--提升效率--软件开发方法DSM总结o99 1. 什么是DSM? 1 2. DSM使用的语言DSL 2 3. 模型的优点 2 4. DSM 跟与MDA区别 2 5. MDA的实 ...

  6. 项目的敏捷开发方法(转自MBAlib)

    项目的敏捷开发方法 敏捷方法很多,包括 Scrum.极限编程.功能驱动开发以及统一过程(RUP)等多种法,这些方法本质实际上是一样的,敏捷开发小组主要的工作方式可以归纳为:作为一个整体工作: 按短迭代 ...

  7. 【翻译】十大要避免的Ext JS开发方法

    原文地址:http://www.sencha.com/blog/top-10-ext-js-development-practices-to-avoid/ 作者:Sean Lanktree Sean ...

  8. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  9. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

随机推荐

  1. CEPH RGW 设置 user default_placement为ssd-placement,优化100KB-200KB小文件性能,使用户创建的bucket对象放置到 SSD设备的Pool上。

    sudo radosgw-admin metadata get user:tuanzi > user.md.json vi user.md.json #to add ssd-placement ...

  2. LVDS/DVI/HDMI Interface

    数字视频信号 以SXGA为例,其时序如下: 垂直:         水平: 图中DSPTMG为使能信号,VSYNC为场同步信号,HSYNC为行同步信号.在行场的消隐期(T1与T7),DSPTMG为低电 ...

  3. Hi3531用SPI FLASH启动 使用Nand做文件系统

    1.编译内核(可选) make ARCH=arm CROSS_COMPILE=arm-hisiv200-linux- menuconfig make ARCH=arm CROSS_COMPILE=ar ...

  4. 【linux】启动apache遇到错误:httpd: Could not reliably determine the server's fully qualified domain name

    1)进入apache的安装目录:(视个人安装情况而不同) [root@server ~]# cd /usr/local/apache/conf 2)编辑httpd.conf文件,搜索"#Se ...

  5. 基于嵌入式操作系统VxWorks的多任务并发程序设计(2) ――任务控制

    4 任务与任务状态 VxWorks实时内核Wind提供了基本的多任务环境.对用户而言,宏观上看起来,多个任务同时在执行.而本质而言,在微观上,系统内核中的任务调度器总是在根据特定的调度策略让它们交替运 ...

  6. Tomcat中的Context.xml的<Loader delegate="true"/>

    Tomcat中的Context.xml的<Loader delegate="true"/> 1.<Loader delegate="true" ...

  7. 用SpeedFan来控制CPU风扇转速

    用SpeedFan来控制CPU风扇转速 浏览:63252 | 更新:2011-04-07 21:14 1 2 3 4 5 6 7 分步阅读 原创文章:看到SpeedFan,很多朋友最想要的是用Spee ...

  8. Django学习-5-模板渲染

    1. {{ 变量名 }}                          def func(request):                     return render(request, ...

  9. eclipse远程调试Tomcat方法(测试成功并且说说遇到的坑)

    转自:http://blog.csdn.net/afgasdg/article/details/9236877 PS:文中容易引起歧义的地方已经做了修改:另外,本人参照以下步骤操作,结果无法调试,后来 ...

  10. 第一节 JDK是什么?JRE是什么?JDK和JRE的区别?以及jdk安装和测试。

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表 ...