欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

记一次业余项目的敏捷开发实践

程序员文章站 2022-05-29 08:42:23
本次是在原有ApiTemplate项目之上,增加一个用户登录权限控制模块,用于验证ApiTemplate项目在面对一些简单问题时,如何抽象并支持未来的扩展。用户登录权限控制模块看上去很简单,但由于业余时间总是有限的。所以借助此机会实践一次用户敏捷开发。首先拆分模块,本次只实现用户登录和登出。apit ......

      本次是在原有apitemplate项目之上,增加一个用户登录权限控制模块,用于验证apitemplate项目在面对一些简单问题时,如何抽象并支持未来的扩展。用户登录权限控制模块看上去很简单,但由于业余时间总是有限的。所以借助此机会实践一次用户敏捷开发。首先拆分模块,本次只实现用户登录和登出。

apitemplate项目地址:https://github.com/cqhaibin/apitemplate

一、总结放前面

最小化任务范围

  • 本次任务只限定在了《用户名+密码登录》这个任务上,并且不包含数据的持久化, 这样在做的时候反复考查自己,不让自己超出范围。所以
  • 查询用户注册信息、在线用户存储相关接口只做定义和模拟实现,不做具体的存储实现
  • 考虑到业务逻辑是稳定的,而存储是可变的,所以数据库实体对象与业务实体对象分离

给任务一个期限

像本次就只列出了任务的期限,而没有列出每个子阶段的期限,如:一个需求必须要经过需求分析、模块设计、代码实现等阶段。这些子阶段也需要给出具体的期限。

从外向里逐层推进

  • 定义ui/服务层接口
    因为ui接口有多种提供方式(如:rest api, rpc等),所以基本以服务层接口为标准,ui接口层只是做了一次简单转换和调用。其中ui/服务层接口输入/输出参数的moddel也随之定义(两层共享model)
  • 实现服务层接口
    此步实现服务层接口,你会发现还需要依赖在线用户管理模块,以及数据库层(查询注册用户信息),在这里我只定义了查询注册用户信息的接口,而暂不做具体的实现。然后进入第三步
  • 定义在线用户模块的接口
    此步包含:在线用户管理实体接口、在线用户实体接口。定义好后先不实现。完善服务层实现中对此模块的依赖调用,在这里你可能会反复调整在线用户模块的方法输入/输出参数的model,以达到与服务层的融合
  • 实现在线用户模块的接口
    此步实现 在线用户管理实体接口、在线用户实体接口。此时我们发现还要依赖在线用户存储接口(只定义,不做实现)

二、用户需求

实现根据用户名的登录、登出接口。

三、需求分析

  • 用户名:支持英文、数字、汉字、以及特殊字符;用户名不区分大小写
  • 密码:支持英文、数字、特殊字符,区分大小写
  • 提示:用户不存在与密码错误要区分提示
  • 此阶段不考虑数据持久化,因为要快速验证原型的可行性

四、系统设计

接口设计

接口统一使用rest api, 实现登录、登出两个接口

  • 登入接口
    • 接口名:postlogin
    • 请求类型:post
    • 输入参数
{
    username<string>, //用户名
    password<string> //密码
}
  • 返回参数
{
    issuccess<bool>, //请求是否成功
    resultcode<number>, //请求状态code 200006:账号不存在;200001:账号被禁用;200002:密码错误
    data<object>:{
        token<string> //登录成功后,返回的token
        user<object>:{ //用户对象
            realname<string>, //用户名
            username<string>, //登录名
            id<int>, //用户id
            config<string>, //用户扩展信息,json字符串
            mobilephone<string>, //电话号码
        }
    }
}
  • 登出接口
    • 接口名称:loginout
    • 请求类型:get
    • 输入参数
      通过url, header, cookie的顺序获取token
    • 返回参数
  • {
        issuccess<bool>, //请求是否成功
        resultcode<number>, //请求状态code
    }

    详细设计

    登入接口详细设计

    • 流程
      记一次业余项目的敏捷开发实践
    • 在线用户管理
      • 在线用户管理接口类
      class ionlineusermgr{
          /// <summary>
          /// 将用户添加到在线用户列表,此方法需要对登入信息持久化
          /// </summary>
          /// <param name="entity"></param>
          void add(iuserentity entity);
          /// <summary>
          /// 根据token移除对应的用户,此方法需要对登出信息持久化
          /// </summary>
          /// <param name="token"></param>
          /// <returns></returns>
          bool remove(string token);
          /// <summary>
          /// 根据用户id移除用户,此方法需要对登出信息持久化
          /// </summary>
          /// <param name="id"></param>
          /// <returns></returns>
          bool remove(int id);
          /// <summary>
          /// 从持久化层恢复在线用户
          /// </summary>
          void load();
          /// <summary>
          /// 获取所有在线用户
          /// </summary>
          ilist<iuserentity>  getall();
      
          iuserentity get(int userid);
      }
      • 用户实体接口类
      class iuserentity{
          userinfo userinfo { get; }
      
          string token { get; }
      
          /// <summary>
          /// 客户端信息
          /// </summary>
          requestclientinfo clientinfo { get; }
      
          datetime logintime { get; }
      
          datetime expiredtime { get; }
          /// <summary>
          /// 用户登录配置
          /// </summary>
          userauthoption option { get; }
      
          tokenentity gettokenentity();
      }
    • 说明
      • token生成规则
        用户key = token_userid_username_ip_os_time,然后将用户key通过md5计算出的值作为token
      • uaparser
        实现useragent字符串到对象的转换。

    登出接口详细设计

    • 流程

    记一次业余项目的敏捷开发实践

    五、数据字典

    • 在线用户信息

    • 用户