您的位置:首页 > 编程语言

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

2015-06-26 19:13 661 查看
实现业务功能时要求面向业务对象编程,并且是完全对象化处理。

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

以下是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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: