个人BO
1-个人BO之强类型
2-个人BO之数据保护
3-个人BO之状态控制
4-个人BO之导航属性html
软件的运行离不开数据,数据通常存在对象中。这种对象在 Java 统称为 POJO,在 C# 则为 POCO。若 POJO 的Property(属性)
都是可读写的(public
的 get
/set
),没有方法或只有少许的持久化方法,这种称为贫血模型。java
贫血模型只存储数据而对数据没有控制,对象内部和外部都能修改。业务逻辑通常写在外部,就算写在内部也由于 Property 可由外界随意修改而控制不住数据。从而这个 POJO 只是存储数据,没有控制数据的能力,也就没有保护数据的能力。一个对象相关的逻辑不能被很好地集中管理,而是分散在各个外部方法中。从而产生了几个不良后果:post
-1
,另外一处却没有考虑值是-1
的状况。BO 中所有的 Property 对外都是只读的,外部没法直接修改 Property。只有 BO 本身内部才能修改属性,从而保护了数据。外部经过调用 BO 的业务方法修改一个或多个属性,业务方法可对参数和状态进行各类判断,知足条件才修改数据。从而保证任什么时候候 BO 的数据都是合法的。因为数据只能在内部修改,因此什么值表明什么意思是由 BO 本身决定的,统一决定,而不是由外部分散在各个地方的代码逻辑决定的,因此有效地保证了数据含义的统一性。this
虽然关于这个 BO 本身的业务都写到 BO 这个类中了(这里暂无须考虑经过继承写到多个类的状况),起到了集中控制的效果。但内部不一样的业务方法也可能有共用的逻辑,这些应该经过重构功能,以达到“一个功能只写一处”的状态。一个大功能会包含若干个小功能,这里的“功能”,是泛指大大小小的任何一个功能。不管是面向对象仍是面向过程,都应该努力作到“一个功能只写一处”。这是解决软件灵活性与软件正确性的惟一比较可取的作法。除非把人看成机器,面对以前大量“复制粘贴再改改”的代码须要修改时也能绝不遗漏地所有修改。lua
BO 被定义为任什么时候刻都是有意义的,因此并不能new
一个空对象,而后再赋值,数据必须在new
时就送来,因此 BO 须要提供一个所有属性的构造方法。另外为了持久化方便的考虑,也能够接收一个 PO,从 PO 获取各个属性的值。code
网上购物的订单
示例htm
public class OrderBo extends BoBase { Order order; @Autowired OrderDB orderDB; public OrderBo(Order order) { /* 传入 PO */ if (order == null) throw ParameterException.missData("order"); this.order = order; } public OrderBo(Long buyerId, Long postDistrictId, String postAddress, String postContactPhone, String evaluation, Date createTime, OrderStatus status, EvaluateStatus evaluateStatus) { /* 传入各个 Property */ Order entity = new Order(); entity.setBuyerId(buyerId); entity.setPostDistrictId(postDistrictId); entity.setPostAddress(postAddress); entity.setPostContactPhone(postContactPhone); entity.setEvaluation(evaluation); entity.setCreateTime(createTime); entity.setStatus(status.toString()); entity.setEvaluateStatus(evaluateStatus); this.order = entity; this.trackState = BoTrackState.Added; } // region 属性 public Long getId() { return order.getId(); } protected void setId(Long id) { /* 每一个 set 都不是 public */ order.setId(id); setTrackUpdate(); /* 父类方法,后续文章会介绍 */ } // 买家 Id public Long getBuyerId() { return order.getBuyerId(); } protected void setBuyerId(Long buyerId) { order.setBuyerId(buyerId); setTrackUpdate(); } // 区县 Id public Long getPostDistrictId() { return order.getPostDistrictId(); } protected void setPostDistrictId(Long postDistrictId) { order.setPostDistrictId(postDistrictId); setTrackUpdate(); } // 详细地址 public String getPostAddress() { return order.getPostAddress(); } protected void setPostAddress(String postAddress) { order.setPostAddress(postAddress); setTrackUpdate(); } // 联系手机 public String getPostContactPhone() { return order.getPostContactPhone(); } protected void setPostContactPhone(String postContactPhone) { order.setPostContactPhone(postContactPhone); setTrackUpdate(); } // 评价内容 public String getEvaluation() { return order.getEvaluation(); } protected void setEvaluation(String evaluation) { order.setEvaluation(evaluation); setTrackUpdate(); } // 下单时间,建立时间 public Date getCreateTime() { return order.getCreateTime(); } protected void setCreateTime(Date createTime) { order.setCreateTime(createTime); setTrackUpdate(); } // 订单状态 public OrderStatus getStatus() { String sStatus = order.getStatus(); return OrderStatus.valueOf(sStatus); } protected void setStatus(OrderStatus status) { String sStatus = status.toString(); order.setStatus(sStatus); setTrackUpdate(); } // 评价状态:未评价,已评价 public EvaluateStatus getEvaluateStatus() { String sStatus = order.getEvaluateStatus(); return EvaluateStatus.valueOf(sStatus); } protected void setEvaluateStatus(EvaluateStatus evaluateStatus) { String sStatus = evaluateStatus.toString(); order.setEvaluateStatus(sStatus); setTrackUpdate(); } // endregion 属性 // region 操做 public void delete() { this.setTrackDeleted(); this.save(); } // 评价 public void evaluat(string evaluation) { /* 不是特定的状态不能评价。如有须要,能够阻止内容为(空)的评价 */ if (this.getEvaluateStatus() != EvaluateStatus.未评价) { throw ParameterException.invalidStatus("订单" + this.getEvaluateStatus() + ",不能评价"); } /* 修改评价内容,并修改评价状态,而不是内容和状态能够被外部分别调用! */ this.setEvaluation(evaluation); this.setEvaluateStatus(EvaluateStatus.已评价); this.save(); /* 父类方法,后续文章会介绍 */ } // endregion 操做 }
打/* */
的内容是本文特地加的说明。对象
没有对构造时的数据进行合法性验证。解决办法能够在构造时检查,若非法则抛异常。也能够私有化构造方法,并提供public static
方法,若非法则返回null
。blog
感谢 Rayman(QQ:25625607) 在我为【BO 的属性该全只读,经过方法来修改】仍是【能够部分属性可写(public set
),并在写时做业务逻辑】犹豫不定时给我了确定的回答。我认为这是整个 BO 的关键所在。继承