千家信息网

敏捷开发技术

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,敏捷开发是一种以人为核心、迭代、循序渐进的开发方式。在Spring框架的发展历程中,处处彰显敏捷开发思想的身影。我们可以从Spring中提出的"约定优于配置"的思想,实现业务Bean零配置及按需加载、
千家信息网最后更新 2024年11月18日敏捷开发技术

敏捷开发是一种以人为核心、迭代、循序渐进的开发方式。在Spring框架的发展历程中,处处彰显敏捷开发思想的身影。我们可以从Spring中提出的"约定优于配置"的思想,实现业务Bean零配置及按需加载、敏捷单元测试和模块化管理机制等。学习怎样运用敏捷开发思想,有助于提高应用开发效率和编写易于测试的代码。因此要成为一名出色的软件开发工程师,学习敏捷开发相关思想是非常有必要的。

1、敏捷开发概述

敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切成多个子项目,各个子项目的成果都是经过测试,具备集成和可运行性。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的子项目,并分别完成,在此软件过程中软件一直处于可使用状态。

1.1、敏捷开发原则

  • 主张简单:如果现在不需要这项功能,就不要再设计中增加它。不必要对这个系统进行过分设计,等日后需求有变化时,再来重构这个系统

  • 拥有变化:需求时刻在变,人们对于需求的理解也时刻在变。在项目开发过程中,项目成员可能会变化。项目相关干系人的观点也可能会变化,前期定制的目标、标准也可能会变化。因此开发方法必须能够拥抱变化。

  • 可持续性:即便已经把一个能够运行的系统交付给用户,项目可能也是失败的--实现项目关系人的需求,其中就包括系统应该要有足够的鲁棒性,能够适应日后的发展。可持续性指的是下一个主要的发布版本,捉着正在构建的系统的运转和支持。要做到这一点,不仅仅要构建高质量的软件,还要创建足够的文档,保证下一场软件竞争能有效的进行。

  • 递增的变化:没必要在一开始的时候就设计一个囊括一切的框架模型,只要设计一个小的最基础的核心架构,打下基础,然后慢慢地改进架构,或者在不需要时丢弃这个架构,这就是递增的思想。

  • 快速反馈:从开始采取行动,到获得行动的反馈,二者之间的时间至关重要。和客户紧密工作,了解并分析他们的需求,或是开发满足他们需求的用户界面,这样就提供了快速反馈的机会。

1.2、敏捷开发过程

  • 测试驱动开发(Test-Driven Development,TDD)是一种不同于传统软件开发流程的新型开发方法。它要求在编写某个功能的代码之前要先编写测试代码,然后只编写测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能够快速响应变化,并加速开发过程。测试驱动开发的基本过程:(1)、快速新增一个测试(2)、运行测试,发现新增的测试不能通过(3)、做一些小改动,尽快让测试程序可运行(4)、再次运行测试,并且让测试通过(5)、重构代码,消除重复设计,优化设计结构

  • 持续集成:频繁、持续地在多个团队成员的工作中进行集成,并给与反馈。主要是SVN等版本控制器的使用

  • 结对编程:两个程序员在一台机器上共同工作。一个输入代码,一个审查。主要是与测试相结合

  • 站立会议

  • 小版本发布,一般以周、月为单位,尽可能多的发布产品。

  • 较少的文档。敏捷开发中不是没有文档,而是有大量的文档,即测试代码,这些代码真是的反应了用户的需求以及系统API的用法。

  • 以合作为中心

1.3、敏捷开发方法Scrum

Scrum是一个敏捷开发框架,是一个增量的、迭代的开发过程。在这个框架中,整个开发周期包括若干小的迭代周期,每个小的迭代周期成为Spint,每个Sprint的建议长度为2~4周。

1.4、测试驱动开发TDD实例

//为了便于测试,这里写一个测试基类package com.smart.web;import org.springframework.mock.web.MockHttpServletRequest;import org.springframework.mock.web.MockHttpServletResponse;import org.springframework.mock.web.MockHttpSession;import org.springframework.web.servlet.HandlerMapping;import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;import org.testng.annotations.BeforeClass;import org.unitils.UnitilsTestNG;import org.unitils.spring.annotation.SpringApplicationContext;import org.unitils.spring.annotation.SpringBeanByType;@SpringApplicationContext( { "classpath:applicationContext.xml" })public class BaseWebTest extends UnitilsTestNG {  @SpringBeanByType public AnnotationMethodHandlerAdapter handlerAdapter; //声明Request与Response模拟对象 public MockHttpServletRequest request; public MockHttpServletResponse response; public MockHttpSession session; //执行测试前先初始模拟对象 @BeforeClass public void before() {  request = new MockHttpServletRequest();  response = new MockHttpServletResponse();        request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, true);        request.setCharacterEncoding("UTF-8"); }}package com.smart.web;import org.springframework.web.servlet.ModelAndView;import org.testng.annotations.Test;import org.unitils.spring.annotation.SpringBeanByType;import static org.testng.Assert.assertEquals;import static org.testng.Assert.assertNotNull;public class AddUserViewTest extends BaseWebTest {    //注入用户管理控制器    @SpringBeanByType    private UserManageController controller;    @Test    public void addUserView() throws Exception {        //设置请求URI及方法        request.setRequestURI("/admin/user/add");        request.setMethod("GET");        //验证结果        ModelAndView mav = handlerAdapter.handle(request, response, controller);        assertNotNull(mav);        assertEquals(mav.getViewName(), "/addUser");    }}package com.smart.web;import org.apache.commons.lang.StringUtils;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Controller@RequestMapping("/admin/user")public class UserManageController {    @RequestMapping("/add")    public String  addUser() {        return "/addUser";    }    @RequestMapping("/save")    public String saveUser(HttpServletRequest request) {          String userName = request.getParameter("userName");          String password = request.getParameter("password");        if(StringUtils.isEmpty(userName)||StringUtils.isEmpty(password)){            request.setAttribute("errorMsg", "用户或密码不能为空!");            return "/addUser";        }else{            return "/success";        }    }}

如果assert出现红色的,说明测试驱动开发未成功,继续微调,直到assert全部为绿色的,说明测试驱动开发实例完成。感兴趣的童鞋可以继续测试一下Service和Dao层。

2、版本控制器GIT

2.1、版本控制器的意义

实现开发团队并行并发、提高开发效率的基础。其目的在于对软件开发进程中文件或目录的发展提供有效的追踪手段,保证在需要时课回到旧版本,避免文件的丢失、修改的丢和和相互覆盖,通过对版本库的访问控制避免未授权的访问和修改,达到有效保护企业软件资产和只是产权的目的。

2.2、SVN

2.3、GIT

与常用的CVS、SVN等不同,GIT采用了分布式版本的方式,不必服务器端软件支持,使源码的发布和交流极其方便。每个GIT克隆都是一个完整的文件库,含有全部历史记录和修订追踪能力。最大特色是"分支"及"合并"操作快速、简便。支持离线工作,GIT是整个项目访问的原子提交。

3、代码构建利器Maven

maven是一个强大的构建工具,能够帮助用户建立一套有效的自动化构建体系。从清理、编译、测试到生成报告,再到打包和部署。用户不再需要一遍又一遍得输入命令,只需要利用简单的命令(mvn clean、install等)就可以完成构建任务。

maven的生命周期,基本上包括:项目的清理、初始化、编译、测试、打包、集成测试、验证、部署、站点生成等步骤。maven项目周期是一个抽象概念,这意味着它不做任何实质性的事情,也就是说它的实现细节交给maven的各种强大插件完成。


0