浅谈敏捷开发中的设计
敏捷开发在当今业界已经大行其道,想要快速交付,采用敏捷开发方法似乎是最好的方式,是否必须要用这就另当别论了。敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发,不过,想要真正做到快速交付,合理地根据实际情况采用敏捷开发才是正确的方式。
当我们熟练的采用了敏捷开发后,不要以为开发人员就是编码就行了,编码前进行详细设计(本文中说到设计都指详细设计)才是保证软件质量的根本,敏捷也是一样要进行设计,只是设计输出相比传统的开发方式要简化,本文中说到设计都统一为详细设计。传统软件开发的详细设计一般有数据结构设计、代码结构设计、详细算法设计、复杂流程设计(流程图)、性能设计等。
对于数据结构设计,传统的方式和敏捷方式可以说并无差异,因为最终目标是转换成物理表结构和关系。数据结构设计更贴切的说是做模型设计,先定义好业务模型(领域模型),然后转换成PO实体模型,最后转成实际的物理表。下面以订单为例,讲解数据结构设计的过程。
先进行领域模型设计, 简单的订单领域模型有订单信息和订单明细连个领域实体
补充PO实体模型应有信息的,转换成PO实体模型
PO模型与物理表结构是一一对应的,把PO模型添加上对应的主键、索引信息后转换成表结构创建的SQL脚本,数据结构设计工作就完成了。
传统软件开发的代码结构设计,针对需求功能要先用UML图输出用例图、类图、时序图等,有复杂算法的要在类图中说明算法的实现说明,然后根据这些图进行代码主要结构的搭建,供开发人员补充详细的实现代码。敏捷开发就不需要画这么多开发人员都不想看的图,直接根据需求功能对应的用户故事设计核心代码结构,复杂算法直接在代码注释中说明,清晰、可读性高、命名友好的代码才是高质量代码的保证。下面是订单功能的代码设计示例:
领域模型有:订单信息领域模型(OrderInfoBo)、订单明细领域模型(OrderDetailBo)
PO实体有:订单信息PO实体(OrderInfoPo)、订单明细PO实体(OrderDetailPo)
订单信息领域模型:
/**
* 订单信息领域模型.<br>
*/
public class OrderInfoBo {
/**
* 订单号.
*/
private String orderNo;
/**
* 订单日期.
*/
private Date orderDate;
/**
* 客户名称.
*/
private String custName;
/**
* 订单总金额.
*/
private BigDecimal totalAmount;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(final String newOrderNo) {
orderNo = newOrderNo;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(final Date newOrderDate) {
orderDate = newOrderDate;
}
public String getCustName() {
return custName;
}
public void setCustName(final String newCustName) {
custName = newCustName;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(final BigDecimal newTotalAmount) {
totalAmount = newTotalAmount;
}
}
订单明细领域模型:
/**
* 订单明细领域模型.<br>
*/
public class OrderDetailBo {
/**
* 商品名称.
*/
private String prodName;
/**
* 商品名称.
*/
private String prodprice;
/**
* 商品名称.
*/
private String prodQty;
public String getProdName() {
return prodName;
}
public void setProdName(final String newProdName) {
prodName = newProdName;
}
public String getProdprice() {
return prodprice;
}
public void setProdprice(final String newProdprice) {
prodprice = newProdprice;
}
public String getProdQty() {
return prodQty;
}
public void setProdQty(final String newProdQty) {
prodQty = newProdQty;
}
}
订单信息PO实体:
/**
* 订单信息PO实体.<br>
*/
public class OrderInfoPo {
/**
* 订单ID.
*/
private String orderId;
/**
* 订单号.
*/
private String orderNo;
/**
* 订单日期.
*/
private Date orderDate;
/**
* 客户名称.
*/
private String custName;
/**
* 订单总金额.
*/
private BigDecimal totalAmount;
public String getOrderId() {
return orderId;
}
public void setOrderId(final String newOrderId) {
orderId = newOrderId;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(final String newOrderNo) {
orderNo = newOrderNo;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(final Date newOrderDate) {
orderDate = newOrderDate;
}
public String getCustName() {
return custName;
}
public void setCustName(final String newCustName) {
custName = newCustName;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(final BigDecimal newTotalAmount) {
totalAmount = newTotalAmount;
}
}
订单明细PO实体:
/**
* 订单明细PO实体.<br>
*/
public class OrderDetailPo {
/**
* 订单ID.
*/
private String orderId;
/**
* 商品名称.
*/
private String prodName;
/**
* 商品名称.
*/
private String prodprice;
/**
* 商品名称.
*/
private String prodQty;
public String getOrderId() {
return orderId;
}
public void setOrderId(final String newOrderId) {
orderId = newOrderId;
}
public String getProdName() {
return prodName;
}
public void setProdName(final String newProdName) {
prodName = newProdName;
}
public String getProdprice() {
return prodprice;
}
public void setProdprice(final String newProdprice) {
prodprice = newProdprice;
}
public String getProdQty() {
return prodQty;
}
public void setProdQty(final String newProdQty) {
prodQty = newProdQty;
}
}
有了领域模型和PO实体,还需要对PO实体操作和查询的接口,下面是设计的基本代码结构:
/**
* 订单信息持久化接口.<br>
*/
public interface IOrderInfoDao {
/**
* 保存订单信息.
* @param po
*/
void save(OrderInfoPo po);
}
/**
* 订单信息持久化<br>
*/
public class OrderInfoDao implements IOrderInfoDao{
public void save(final OrderInfoPo newPo) {
// TODO Auto-generated method stub
}
}
/**
* 订单信息查询接口.<br>
*/
public interface IOrderInfoQueryDao {
List<OrderInfoPo> findByKey(final String orderId);
}
/**
* 订单信息查询<br>
*/
public class OrderInfoQueryDao implements IOrderInfoQueryDao{
public List<OrderInfoPo> findByKey(final String newOrderId) {
// TODO Auto-generated method stub
return null;
}
}
/**
* 订单明细持久化接口.<br>
*/
public interface IOrderDetailDao {
/**
* 保存订单明细.
* @param po
*/
void save(OrderDetailPo po);
}
/**
* 订单明细持久化<br>
*/
public class OrderDetailDao implements IOrderDetailDao{
public void save(final OrderDetailPo newPo) {
// TODO Auto-generated method stub
}
}
/**
* 订单明细信息查询接口.<br>
*/
public interface IOrderDetailQueryDao {
List<OrderDetailPo> findByKey(final String orderId);
}
/**
* 订单明细查询<br>
*/
public class OrderDetailQueryDao implements IOrderDetailQueryDao{
public List<OrderDetailPo> findByKey(final String newOrderId) {
// TODO Auto-generated method stub
return null;
}
}
有了上面设计好清晰的代码框架,开发人员补充具体的实现,有复杂逻辑的要调整的及时沟通调整,这才是敏捷设计。
对于传统软件开发的复杂流程设计(流程图)、性能设计,我认为在敏捷开发中也是不需要的,所有的内容体现就是代码,高质量的代码,可维护容易扩展的代码,可以快速交付,才是敏捷的核心思想。我们应该借鉴传统软件开发的经验,拥抱变化,遵循敏捷实践去发现问题,应用设计原则去诊断问题,应用设计模式去解决问题。
版权声明: 本文为 InfoQ 作者【czjczk】的原创文章。
原文链接:【http://xie.infoq.cn/article/6053fc0e31fa00e44e6bad7ca】。未经作者许可,禁止转载。
评论