插件开发技术说明(12)---面向业务对象编程:2种风格的对比

实现业务功能时要求面向业务对象编程,并且是完全对象化处理。

协议处理不要直接操作数据库,而是通过业务对象的封装完成。


以下是7125协议的2种实现。

风格1:

int CSbaService::OnApplyTrial(CWrappedMsg<> *in,vector<CWrappedMsg<> *> &out,DISPATCH_RESULT &or)
{
	or.err_code_ = CE_DATABASE;
	CMsg* pMsgIN = in->msg;
	long lEId=0,lUserId=0,lCoEId,lGoodsId=0,lApplyNum=0;
	if(-1==pMsgIN->GetParam("EId",lEId) || -1==pMsgIN->GetParam("UserId",lUserId) || -1==pMsgIN->GetParam("CoEId",lCoEId)
		 || -1==pMsgIN->GetParam("GoodsID",lGoodsId) || -1==pMsgIN->GetParam("ApplyNum",lApplyNum))
	{
		or.err_code_ = CE_PARAM_ERROR;
		return -1;
	}
	
	GETDBC(pdbor,local_dbc_.c_str());
	FAIL_RETURN(pdbor->BeginTrans(),,-1);

	CTrialSale* pVenTrialSale = CTrialSale::Get((int)lCoEId,(int)lGoodsId);
	if( pVenTrialSale->IsOutofdate() || pVenTrialSale->IsOverbalanceTotal((int)lApplyNum) ) ///<过期,申请超量
	{
		or.err_code_ = CE_DATA_ERROR;
		return -1;
	}
	if(pVenTrialSale->GetLimitBQty() - pVenTrialSale->GetApplyQty()<lApplyNum)  ///< 判断是否超出总量
	{
		return -1;
	}
	///< 查询门店已申请数量
	string strSql = LogMsg("select sum(applyqty) from t_ven_applytrial where refobjectid=%d and eid=%d",
		pVenTrialSale->GetObjectId(), lEId);
	unsigned long ulSumNum = 0;
	int nRes = CQueryFunc::Query(pdbor, strSql, ulSumNum);
	if(-1==nRes || 0==nRes)
	{
		return -1;
	}
	if(pVenTrialSale->IsOverbalanceSingle(ulSumNum + lApplyNum))  ///< 判断是否超出每个门店可以申请的数量
	{
		or.err_code_ = CE_DATA_ERROR;
		return -1;
	}	
	strSql = LogMsg("insert into t_ven_applytrial(refobjectid,eid,applyqty,applytime,proposer) values(%d,%d,%d,GetDate(),%d)",
		pVenTrialSale->GetObjectId(),lEId,lApplyNum,lUserId);
	string sql = LogMsg("update t_Ven_TrialSale set ApplyQty=ApplyQty+%d where eid=%d and goodsid=%d",lApplyNum,lCoEId,lGoodsId);
	if (!pdbor->Execute(strSql.c_str())) {
		return -1;
	}	
	if (!pdbor->Execute(sql.c_str())  ) {
		return -1;
	}
	FAIL_RETURN(pdbor->CommitTrans(),,-1);
	return 0;
}

这种方式的实现的问题:

。记录未锁定:存在并发问题

。非完全面向对象:业务逻辑和数据结构裸露


风格2:

todo: 增加业务错误码

int CSbaService::OnApplyTrial(CWrappedMsg<> *in,vector<CWrappedMsg<> *> &out,DISPATCH_RESULT &or)
{
	or.err_code_ = CE_DATABASE;
	CMsg* pMsgIN = in->msg;
	long lEId=0,lUserId=0,lCoEId,lGoodsId=0,lApplyNum=0;
	CHECK_MSG_PARAMETER2(pMsgIN,"EId",lEId,-1);
	CHECK_MSG_PARAMETER2(pMsgIN,"UserId",lUserId,-1);
	CHECK_MSG_PARAMETER2(pMsgIN,"CoEId",lCoEId,-1);
	CHECK_MSG_PARAMETER2(pMsgIN,"GoodsID",lGoodsId,-1);
	CHECK_MSG_PARAMETER2(pMsgIN,"ApplyNum",lApplyNum,-1);

	GETDBC(pdbor,local_dbc_.c_str());
	FAIL_RETURN(pdbor->BeginTrans(),,-1);

	///< 读指定供应商指定商品的试销信息(在有效期内只能由一条有效记录)
	///< 只取有效试销信息,需要锁定读取的记录以便后续修改已申请数
	CTrialSale* trial_sale = CTrialSale::Get((int)lCoEId,(int)lGoodsId,true,true);
	///< 检查总量限量是否已到
	if (!trial_sale->CheckTotalQty()) {
		return -1; ///< 总量已申请完
	}
	CTrialApply trial_apply; ///< 试销申请对象
	///< 为试销申请成员赋值
	trial_apply.trial_sale_ = trial_sale; ///< 试销申请关联的试销商品信息对象
	trial_apply.eid_ = lEId;
	trial_apply.creator_ = lUserId;
	trial_apply.co_eid_ = lCoEId;
	trial_apply.apply_qty_ = lApplyNum; ///< 本次申请数量
	int ret = trial_apply.CanApply(); ///< 检查是否可申请
	if (ret==-1) ///< 错误产生
		return -1;
	if (ret==0) { ///< 申请超量
		or.err_code_ = CE_DATA_ERROR;
		return -1;
	}
	///< 生成单据编号
	if (trial_apply.ApplyID())
		return -1;
	CDateTime::GetDateTime(trial_apply.create_time_);
	///< 写入数据库
	if (trial_apply.Insert()) {
		return -1;
	}
	///< 增加已申请数量
	trial_sale->m_nApplyQty += lApplyNum;
	///< 更新试销商品信息
	if (trial_sale->Update()) 
		return -1;

	FAIL_RETURN(pdbor->CommitTrans(),,-1);

	return 0;
}

相关定义与实现代码

class CTrialApply : public CSheet {
public:
	SLIC_OBJECTID ref_object_id_; ///< 关联试销商品记录编号
	float apply_qty_; ///< 申请数量
	float accept_qty_; ///< 确认数量

	CTrialSale *trial_sale_; ///< 试销商品对象
public:
	CTrialApply():CSheet(),ref_object_id_(0),apply_qty_(0),accept_qty_(0),trial_sale_(0) {
		sheet_type_ = 1060;
	}
	int Insert();
	int CanApply(); ///< 是否能申请
};


//
int CTrialSale::Update() {
	USEDBC(pdbor,CDataEnv::env_->dbc_name_.c_str());
	ITableHandler *th = CDataEnv::env_->db_helper_->NewTableHandler(pdbor,"t_Ven_TrialSale");
	AUTO_POINTER_NODECLARE(ITableHandler,th);

	th->BindField("ObjectId",(char**)&this->m_nObjectId,sizeof(this->m_nObjectId)); 
	th->BindField("ApplyQty",(char**)&this->m_nApplyQty,sizeof(this->m_nApplyQty));
	th->SetKeyField("ObjectId",0);

	if (th->Insert()) 
		return -1;

	return 0;
}

//
int CTrialApply::CanApply() {
	int applied_qty = trial_sale_->QueryAppliedQty(this->eid_);
	if (applied_qty==-1)
		return -1;

	return (applied_qty+this->accept_qty_)<trial_sale_->m_nLimitBQty ? 1:0;
}

//
int CTrialApply::Insert() {
	USEDBC(pdbor,CDataEnv::env_->dbc_name_.c_str());
	ITableHandler *th = CDataEnv::env_->db_helper_->NewTableHandler(pdbor,"t_ven_applytrial");
	AUTO_POINTER_NODECLARE(ITableHandler,th);

	th->BindField("RefObjectId",(char**)&this->ref_object_id_,sizeof(this->ref_object_id_)); 
	th->BindField("EId",(char**)&this->eid_,sizeof(this->eid_));
	th->BindField("ApplyQty",(char**)&this->apply_qty_,sizeof(this->apply_qty_));
	th->BindField("Proposer",(char**)&this->creator_,sizeof(this->creator_));
	th->BindField("ApplyTime",this->create_time_);

	if (th->Insert(false)) 
		return -1;

	return 0;
}

//
CTrialSale* CTrialSale::Get(int nEId,int nGoodsId,bool active,bool lock) {
	string expr;
	if (active) {
		string today = CDateTime::Now().GetDateTime();
		expr = LogMsg(" and (DataType=0 or (cast('%s' as datetime)>=bdate and cast('%s' as datetime)<=edate))",today.c_str(),today.c_str());

	}
	USEDBC(pdbor,CDataEnv::env_->dbc_name_.c_str());
	string strSql = LogMsg("select ObjectId,EId,GoodsID,LimitBQty,LimitQty,ApplyQty,SaleQty,DateType,BDate,EDate,CreateTime "
		" from t_Ven_TrialSale %s where eid=%d and goodsid=%d %s %s",
		lock ? pdbor->GetDBExt()->WithLock().c_str() : "",nEId,nGoodsId,active ? expr.c_str() : "",lock ? pdbor->GetDBExt()->ForUpdate().c_str():"");

	AUTO_QUERY_RECORDSET(CRecordset,prs,pdbor);
	prs = pdbor->Query(adCmdText,strSql.c_str());
	if (prs==0 || prs->IsEof()) {
		return NULL;
	}
	CRecordsetBindObject<CTrialSale> binder;
	binder.BindRecordset(prs);
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nObjectId,"ObjectId"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nEId,"EId"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nGoodsId,"GoodsID"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nLimitBQty,"LimitBQty"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nLimitQty,"LimitQty"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nApplyQty,"ApplyQty"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_INT,0,m_nSaleQty,"SaleQty"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_UINT,0,m_unDateType,"DateType"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_STRING,0,m_strBDate,"BDate"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_STRING,0,m_strEDate,"EDate"));
	binder.BindField(NEW_FIELD_BIND(CTrialSale,ORM_FIELD_TYPE_STRING,0,m_strCreateTime,"CreateTime"));

	return  binder.ToObject();
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值