2011-06-12 16:15:00 zhangweia 阅读数 4957
  • 敏捷开发——SCRUM

    SCRUM是当前较火的一种敏捷开发方法,有用户故事、冲刺、燃尽图等很多很酷的玩法,有牛B的产品负责人、SCRUM Master,有很强的自组织团队。

    13660 人正在学习 去看看 张传波

      需求澄清后,SE把所有的故事卡贴到故事墙上,等待开发人员的开发。故事墙的模板为:

image

分析      : 需求澄清完成后,SE把所有的故事卡都贴到分析阶段

等待开发: 开发人员和SE确认了需求,明确了做什么以及怎么做以后,把故事卡从分析阶段移到等待开发

开发中   : 开发人员一次只开发一张故事卡,把相应开发的那张卡移植到开发中

阻塞      : 如果开发过程中,由于配合的原因,导致故事卡无法继续走下去,则把该卡移动到阻塞阶段

开发完成 :如果开发完成,并向SE  SHOW CASE以后,开发人员吧故事卡移植到等待测试

等待测试 :测试人员看到等待测试中有卡以后,对故事卡进行测试,测试完成以后把卡移到测试完成阶段,如果测试有问题,则移出该卡到开发中阶段

测试完成  : 本张卡的生命周期结束

   故事墙的等待开发、开发中属于开发人员。等待测试,测试完成属于测试人员,开发人员和测试人员必须坚守自己的领地,当卡移动过去时,必须确认了才接受,如果有不清楚以及问题,及时的移除自己的领地。

为什么要有故事墙,故事墙的作用是什么了?

    故事墙描叙了开发过程中的各个阶段,能反应当前团队开发的健康状态。在每天的站立会议中,开发人员依据故事墙,给大家分享其开发状态,问题,需要的帮助。项目领导者也能够及时的通过故事墙,了解当前团队的状态,并及时调整。

2014-07-20 22:41:29 iteye_6080 阅读数 12
  • 敏捷开发——SCRUM

    SCRUM是当前较火的一种敏捷开发方法,有用户故事、冲刺、燃尽图等很多很酷的玩法,有牛B的产品负责人、SCRUM Master,有很强的自组织团队。

    13660 人正在学习 去看看 张传波

        在初步学习完完angular js之后,开始尝试做party_bid的第一张卡片。这个项目用到了敏捷开发的故事卡,用到了angular js,用到了yeoman和rubymine,这些对我来是一个全新的领域,特此总结一下。

        party_bid来源于百老汇,是一个竞价游戏。游戏分为四个部分,创建活动——活动报名——组织竞价——竞价分析,最终从竞价者中选出竞价最低且不重复作为获胜者。

1.首先建立一个新的文件夹。我的文件夹名为party_bid,进入文件夹。在终端输入下面的代码。

 

mkdir party_bid //创建文件夹party_bid
cd party_bid  //进入文件夹

 

2.用yeoman在party_bid文件夹下面生成一个新的工程。接着上面的代码,输入下面的代码。我的工程名字叫party_bid。建议在网速比较好的地方生成,生成速度会比较快,也不容易出现error。

 

yo party_bid  //生成工程文件

提醒 Would you like to use Sass (with Compass)? (Y/n)   n

提醒 Would you like to include Bootstrap? (Y/n)   y

其余按Enter键。

 

3.工程文件生成后,在相应文件夹下用终端输入下面代码,启动服务器。至此,准备活动全部完成,可以正式开始编写程序。

 

grunt serve

 

 4.首先先要把要引用的所有css文件引入index中。

 

<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="css/font-awesome.min.css" rel="stylesheet" media="screen">
<link href="css/android.css" rel="stylesheet" media="screen">

 href是指定的路径,是css文件的位置;rel是relation。

其次还要引入相对应使用的全部js文件。如下:

 

<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="scripts/route.js"></script>
<script src="scripts/controllers/main.js"></script
 

 

5.接下来就是要配置路由器实现页面和控制器之间的联系。部分代码如下:

 

$routeProvider
     .when('/', {
          templateUrl: 'views/main.html',
          controller: 'MainCtrl'
      })
     .when('/create_activity', {
          templateUrl: 'views/create_activity.html',
          controller: 'CreateActivityCtrl'
      })
 我是通过在main.html页面判断是否活动列表中是否存在活动而进行页面的跳转是跳转到activity_list还是create_activity,但是main页面并没有展示内容。

 

6.需求要求点击按钮实现页面的跳转。我使用的方式的ng-click,在对应的控制器中实现方法。举个列子:从活动报名的页面点击返回按钮跳转到活动列表中。

 

<button class="btn btn-primary header-left" ng-click="go_list()">返回</button>
 
$scope.go_list = function () {
            $location.path('/activity_list')
        }
 

 

7. 在活动列表页面中要求活动排序按照活动创建的顺序输出。我在存储数据时存成数组的形式,这里只需要将数组reverse之后遍历输出就可以了。这里也使用了ng-repeat方法。在localStorage中的数据传到name中,list对name进行遍历后把结果输出。

 

<li ng-repeat='list in name'>  
            {{list}}    //输出遍历结果
 下面是在控制器中的代码。首先判断localStorage中是否有活动,如果没有就将数据传到name,对name进行reverse。但是这部分代码感觉还不够好,还需要进一步的修改。
if(localStorage.length!=0)
        {
            console.log(localStorage.length);
            var name = JSON.parse(localStorage['activity_name']);
            $scope.name = name.reverse();
        }
        else{
        }
 

 

8.在create_activity页面中要实现存入活动名称,判断活动名称是否重复以及返回按钮在活动列表中没有活动是不显示的三个功能。在存入活动时使用的方法是JSON.stringify方法,因为这个方法可以直接解析对象。在判断活动名称是否重复时使用的循环,在按钮显示的功能使用的是ng-show的方法。这部分的代码感觉也是不够干净利落,还是需要继续修改完善的。

<h3>活动名称</h3>
            <p><input type="text" class="input" ng-model="activity_name"></p>
            <button class="btn btn-default btn-lg btn-block" ng-disabled='!activity_name' ng-click="go_sign_up(activity_name)">创建</button>
            <p>{{tips}}</p>

 

if (localStorage.length != 0) {
                var storedNames = [];
                storedNames = JSON.parse(localStorage['activity_name']);
                var i = 0;
                for (var n = 0; n<storedNames.length; n++) {
                    if (storedNames[n]==temp_act_name) {
                        $scope.tips = "活动名称重复";
                        i = 1;
                        break;
                    }
                    else {
                    }
                }
                if(i==0){
                    storedNames.push(temp_act_name);  //将活动名称存入数组name
                    localStorage['activity_name'] = JSON.stringify(storedNames);
                    //将name数组存入localStorage中,key是activity_name
                    $location.path('/activity_sign_up');
                }
                else{
                }
            } else {
                var name = [];
                name.push(temp_act_name);
                localStorage['activity_name'] = JSON.stringify(name);
                $location.path('/activity_sign_up');
            }
        }

 至此,party_bid的第一张卡片的功能已经大致实现。但是里面还是有很多内容值得我细细思考,认真记录的。其实还是有一个疑问可不可以使用setItem和getItem的方法实现数据的存储和读取的呢?感觉上还是可以的,但是这两种方法哪一种更好呢?希望在下一篇博客中我可以得到结论。

2011-06-12 10:11:00 zhangweia 阅读数 4275
  • 敏捷开发——SCRUM

    SCRUM是当前较火的一种敏捷开发方法,有用户故事、冲刺、燃尽图等很多很酷的玩法,有牛B的产品负责人、SCRUM Master,有很强的自组织团队。

    13660 人正在学习 去看看 张传波

       迭代需求的整理是敏捷开发的第一步,也是敏捷开发很重要的一步,在这一步中我们需要把客户的业务需求按照优先级的顺序,整理成为一个个的迭代。然后把一个个的迭代拆成一个个可验收的故事卡。

       在此需要说说什么是故事卡,故事卡和业务需求之间的关系。故事卡是一个个独立的,可验收的功能,一个业务需求可以拆分为多个故事卡。比如:我们常见的账号管理需求,需要对账号进行增、删,改、查。因为添加、修改、删除、查询都是一个个可单独验收的场景,我们可以把账号管理需求拆分为四个故事卡。因此把需求拆分为故事卡的原则是:

     1.故事卡是可以独立验收的场景

      2.故事卡包含的点数应该尽量小,一般划分为1、3、5个点,如果超过了应该重新拆分该故事卡。给故事卡评点的标准是什么了?我们可以按照一个查询完成的工作量是1个点,然后衡量该故事卡的工作量而适量的评点。

      3. 注意故事卡完成的工作量中包括自我测试和联调的时间。而不是单独的只是开发完成。

        敏捷开发强调成员之间的交互而不强调文档,但这并不意味着不需要文档,需求说明的好坏直接影响着客户价值的交替,我们先来看看下面的一张图:

        image

客户      : 客户高兴的把具有5个价值点的需求交代给需求人员

需求人员: 需求人员由于理解的不同,只从顾客那里接受了3个价值点

程序员   : 由于需求人员表述的不清晰,最终程序员只理解了1个价值点,并交互给客户

客户      : 当客户拿到只有1个价值点的产品后,客户哭了!!

因此作为需求人员,当在向程序员解析需求的时候,需要做到以下几点,防止价值点的丢失。

a.  功能点:需求包含了那些功能点

b.  约束条件: 每个功能点有什么约束条件

c.  流程图 :功能点的业务流程是怎样的

d. 如果有界面的话,需要有页面元素图以及说明。

e. 验收:验收不同于测试用例,主要用来模拟用户的行为以及期望的响应

现在我们就以一个简单的登录界面,来讲讲应该怎样去描叙需求:

功能点:

         1. 用户可输入用户名、密码。可选择自动自动登录、记住密码。响应登录按钮

         2. 当点击登录时: a. 判断用户名、密码是否有为null,有则提示用户。

                                   b. 记录用户名、密码以及记住密码、自动登录的状态

                                   c.  发起登录请求,并响应登录状态。成功则调转到下一个界面,失败则提示用户

         3. 启动登录界面的时候,读取配置文件,访问记住密码和自动登录状态。如果记住密码为true,自动登录为false,则启动登录界面的时候,用户名和密码为上次登录退出时的用户名和密码。如果自动登录为true,则直接执行点击登录的事件。

约束条件:

         1. 用户名必须以字母开头,并且包含字母、数字,长度不小于6位,当焦点切换到密码的时候,自动验证输入的用户名的合法性

         2. 密码以*号隐藏

流程图:

         image

界面(低保真--界面元素草图):

      image

验收

image
2015-04-19 15:46:06 chenleixing 阅读数 3455
  • 敏捷开发——SCRUM

    SCRUM是当前较火的一种敏捷开发方法,有用户故事、冲刺、燃尽图等很多很酷的玩法,有牛B的产品负责人、SCRUM Master,有很强的自组织团队。

    13660 人正在学习 去看看 张传波

需求澄清后,SE把所有的故事卡贴到故事墙上,等待开发人员的开发。故事墙的模板为:

image

分析      : 需求澄清完成后,SE把所有的故事卡都贴到分析阶段

等待开发: 开发人员和SE确认了需求,明确了做什么以及怎么做以后,把故事卡从分析阶段移到等待开发

开发中   : 开发人员一次只开发一张故事卡,把相应开发的那张卡移植到开发中

阻塞      : 如果开发过程中,由于配合的原因,导致故事卡无法继续走下去,则把该卡移动到阻塞阶段

开发完成 :如果开发完成,并向SE  SHOW CASE以后,开发人员吧故事卡移植到等待测试

等待测试 :测试人员看到等待测试中有卡以后,对故事卡进行测试,测试完成以后把卡移到测试完成阶段,如果测试有问题,则移出该卡到开发中阶段

测试完成  : 本张卡的生命周期结束

   故事墙的等待开发、开发中属于开发人员。等待测试,测试完成属于测试人员,开发人员和测试人员必须坚守自己的领地,当卡移动过去时,必须确认了才接受,如果有不清楚以及问题,及时的移除自己的领地。

为什么要有故事墙,故事墙的作用是什么了?

    故事墙描叙了开发过程中的各个阶段,能反应当前团队开发的健康状态。在每天的站立会议中,开发人员依据故事墙,给大家分享其开发状态,问题,需要的帮助。项目领导者也能够及时的通过故事墙,了解当前团队的状态,并及时调整。

2014-06-09 16:53:46 u014419512 阅读数 2305
  • 敏捷开发——SCRUM

    SCRUM是当前较火的一种敏捷开发方法,有用户故事、冲刺、燃尽图等很多很酷的玩法,有牛B的产品负责人、SCRUM Master,有很强的自组织团队。

    13660 人正在学习 去看看 张传波

           敏捷开发目前已成为互联网公司的首选方案,为应对市场的快速变化,我们公司也在大力推广敏捷,最近在读《用户故事与敏捷方法》一书,我想边读边做一些分享,传播知识的同时加强记忆。

1.       基于用户建模是一个比较好的起点。

产品团队可以采用头脑风暴等形式,挖掘出产品实际存在或者潜在的用户或客户,给他们一些角色。

多种角色出现重叠时,再将重叠部分成立一个独立角色。

比如“运维角色”和“部署角色”都需要做一件事情:做数据修改,那么我们就考虑一个“数据修改角色”专门做这个事情,然后“运维角色”和“部署角色”就都不包含这个职能了。

 

再然后呢,给每个角色找一个生动的虚拟人物来代替,让团队熟悉这个人,就像身边的一个朋友一样了解。

例子:“借款人角色”,代表人物叫“张穷”,30岁,小餐馆经营者,这两年生意做得不错,想扩大店面,但是手头吃紧,正绞尽脑汁想找一笔贷款。

 

用户建模时,可以考虑一些特殊的人群,他们有助于发现一些细致的需求。比如老太太需要屏幕字体够大。

 

2.       寻找用户。

最理想的方式是能够找到软件真实的使用者,了解他们的需求。

条件不成熟的情况下就只有寻找用户代理,不同的人群都可以担任用户代理,但是要注意不同的用户代理看待问题大多是从个人需要出发的,要摸清他们的一些小脾气。

实际用户的经理:他们对于产品细节的关注度可能不高,因为他很可能平时不做实际操作,对于群众疾苦了解得不够;他们可能会过分关注一些管理功能,比如任务调度、查看每个手下现在的任务完成情况等,而这些功能很可能不是产品核心的东西。

开发经理:他们通常缺少对软件的实际体验,其内心驱动因素很可能是业务压力或者成就感,这样的动机很容易背离产品核心业务价值。

销售人员:他们的核心价值观通常是尽量多的订单,为了不丢单,他们总会承诺“没问题”,各种稀奇古怪的东西都想丢进产品里面,使得产品没有规划、随遇而安。

领域专家:他们通常能够在产品设计上提供很大的帮助,但要小心他们弄出一个太“高大上”的东西,不接地气,让小白的用户觉得软件极其难用。

系统分析师:他们是很有想法的文艺青年,既懂技术又懂业务,是很好的用户代理。但要小心他们的空想症,他们有可能花上两天去精心设计一个业务流程,但根本没有做过任何调研。最坏的结果是最后不得不推翻一个精心雕琢的楼阁,浪费、肉疼。。

 

3.       切割故事。

传统的切割方式大多是按实现层面或者技术栈来切割,比如一个功能别切割为前台、后台、数据库几个任务,或者按照技术栈切割为java相关、C#相关、移动端几个任务。

这样的切割方式最大的问题是:单个任务不能产生业务价值、相互依赖导致无法快速交付并得到反馈。

推荐做纵向的切割,每个故事尽量是一个功能闭包,一个故事完成意味着一个功能可交付。

以京东提交订单功能为例,其业务流程为:基于预先选好的商品信息,先选择支付方式、再选择配送方式,然后提交保存。

传统的切割方式可能为:

T1: 前台交互实现(选择支付方式、配送方式),形成可提交的订单数据后提交给servlet

T2:后台接收订单数据,保存到数据库,给成功提示。

 

考虑换一种切割方式:

S1:基于预先选好的商品信息,使用默认支付方式和配送方式,提交订单并保存。

S2:支持用户选择支付方式并保存订单。

S3:支持用户选择配送方式并保存订单。

 

我们不要写哪种大而全的故事,一个故事只为一种客户编写,只满足其一个小小的业务价值。

编写故事时尽量避免涉及界面的描述,这会诱导开发人员按照某人脑海中印象来实现功能,这实际是把设计意图强加到故事之中,更致命的是会隐含的扩大故事范围。

比如这样一个故事:

           在首页的右上方,用户可以看到“注册”按钮并点击它,之后弹出一个对话框,用户录入注册信息后,点击提交按钮,若注册成功就回到首页,并发送激活邮件。

它的问题:

           涉及太多的界面信息,它阻止了开发人员或者分析师跟客户做进一步沟通的欲望,也许这样的交互设计是蹩脚的呢?

考虑写成这样也许更好:

           在首页醒目位置可以进行用户注册,注册成功需要发送激活邮件,注册失败需要失败提醒。

 

下期分享:故事估算和制定计划,谢谢围观~~

没有更多推荐了,返回首页