客户端分页处理器

来源:互联网 发布:2016linux运维面试题 编辑:程序博客网 时间:2024/06/08 13:58

分页(查询)是客户端开发经常面临的问题.

经常性或者带有普遍性的问题, 好的对策是用抽象,而不是重复。
重复行为没有价值,而且有害,浪费资源(开发者资源,发布,运行时资源),代码臃肿,增加阅读和维护困难,弄不好牵一发而动全身。

程序的原始目的之一是把重复的事情交给系统自动完成,重复开发的结果是程序员在程序级别的同样行为。

当产生重复的冲动,需要ctrl+c/ctrl+v时,通常意味着结构性的提升机会出现,应该停下来去思考了,而不是去堆砌代码。
这种情况说明有被设计师忽略的事实,实际上对于一个非完全模式化有可因循的案例的系统,很难预见到一切.

通过实现分页处理器,可以简化客户端分页功能的开发。
在简化开发方面有以下参考原则:
.问自己能够再简化吗?
.通用不等于万能:清楚地认识能力和缺陷,不要强求

客户端在实现分页功能的场景如下:
在查询较大的数据量时,无法(也没有必要)一次全部获取结果,用户需要分次从服务器获取,浏览所关心的信息。
有价值的分页信息包括:总记录数,页数,当前页记录数.
用户可以通过界面控件在这些页之间导航,常用的有"下一页",下一页",到"首页",到"尾页",直接跳转到某页"Goto".

分页结果有几十页已经算是上限了,超过这个范围已经没有实际操作意义了,应该审视应用规划是否存在问题,如统计角度不实用。


使用分页处理器的步骤:
1.创建一个分页处理器
2.把分页处理器与控件绑定,设置页处理函数(页处理函数负责业务逻辑)
3.实现页处理函数


todo:
.按钮支持TLabel
.Goto支持:TEdit,TSpinEdit(TUpdown+TEdit)
.内部创建界面控件
.VCL组件化


*构造大型设备也是从零件入手,不要做成铁板一块的系统.
系统构造的几个要素是:组件,接口,活动机制(组件间协调)



头文件中声明分页处理器对象

#include "page_op.h"//---------------------------------------------------------------------------class TfrmGoodsResult : public TfrmBase1 {    ///....private:    CPageOp<TSpeedButton> page_op_; ///< 分页操作对象    int Query(unsigned int page_no);};



实现文件中绑定控件,设置页处理函数
//---------------------------------------------------------------------------void __fastcall TfrmGoodsResult::FormCreate(TObject *Sender){    page_op_.SetControl(btFirst,btBack,btNext,btLast,cbPageNo);    page_op_.SetAction(new CPageAction<TfrmGoodsResult>(this,&TfrmGoodsResult::Query));}//---------------------------------------------------------------------------///< 页处理函数///< 如:构造请求包向服务器请求int TfrmGoodsResult::Query(unsigned int page_no) {    CMsg *pMsg = new CMsg;    pMsg->SetMsgType(umxns::MT_REQUEST);    pMsg->SetMsgID(11127);            /// 构造请求消息内容        /// ...            qry_cond_.page_no_ = page_no;    CPagizeHelper::PutPageCond(pMsg,&qry_cond_);    int result = 0;    CMsg* pAns = 0;    int ret = CBasePluginModule::sc_->call(pMsg, result,&pAns);    if (ret||result)        return -1;    if (!CMsgHelper::CheckResult(pAns,0,1)) {        pAns->Release();        return -1;    }        ///< 处理返回消息        ///....            pAns->Release();    return 0;}

分页处理器定义如下:

文件:page_op.h

//---------------------------------------------------------------------------class CPageActionBase {public:    virtual int Do(unsigned int page_no) = 0;};//---------------------------------------------------------------------------///< 页活动类///< 分页操作的活动内容template <class T> class CPageAction : public CPageActionBase {    typedef int (T::*PageActionFunc)(unsigned int page);    T *obj_;    PageActionFunc func_;public:    CPageAction(T *obj,PageActionFunc func):obj_(obj),func_(func) {    }    int Do(unsigned int page_no) {        return (obj_->*func_)(page_no);    }};//---------------------------------------------------------------------------///< 分页操作类template <class T> class CPageOp {    unsigned int cur_page_; ///< 当前页号(页号从1开始)    unsigned int page_count_; ///< 总页数    T *first_;    T *prev_;    T *next_;    T *last_;    TComboBox *cbList_;    unsigned int page_no_; ///< 输入的页号    CVarValidator<unsigned int> page_no_validator_; ///< 输入页号校验器    CIntValidator iv_; ///< 页号校验器    CPageActionBase *action_;    void UIControl_i();public:    CPageOp():page_count_(0),cur_page_(0),action_(0) {        first_ = prev_ = next_ = last_ = 0;        page_no_ = 0;    }    ~CPageOp() {        if (action_) delete action_;    }    ///< 设置控件    void SetControl(T *first,T *prev,T *next,T *last,TComboBox *cbList);    void SetAction(CPageActionBase *action) {        action_ = action;    }    void SetPageCount(unsigned int page_count);    unsigned long GetPageCount() const { return page_count_; }    void First(); ///< 第一页    void Prev();  ///< 上一页    void Next();  ///< 下一页    void Last();  ///< 最后一页    void GoTo(unsigned int page_no); ///< 转到page_no页private:    void __fastcall OnFirst(TObject *Sender);    void __fastcall OnPrev(TObject *Sender);    void __fastcall OnNext(TObject *Sender);    void __fastcall OnLast(TObject *Sender);    void __fastcall OnGoto(TObject *Sender);};#include "page_op.cpp"

page_op.cpp
//---------------------------------------------------------------------------///< 设置控件template <class T> void CPageOp<T>::SetControl(T *first,T *prev,T *next,T *last,TComboBox *cbList) {    first_ = first;    prev_ = prev;    next_ = next;    last_ = last;    cbList_ = cbList;    first_->OnClick = OnFirst;    prev_->OnClick = OnPrev;    next_->OnClick = OnNext;    last_->OnClick = OnLast;    cbList_->OnChange = OnGoto;    first_->Enabled = false;    prev_->Enabled = false;    next_->Enabled = false;    last_->Enabled = false;//    cbList_->Style = csDropDownList;    page_no_validator_.SetVar(&page_no_,ORM_FIELD_TYPE_INT,"页号");    page_no_validator_.SetValidator(&iv_);    page_no_validator_.BindControl(new CComboBox(cbList_));}//---------------------------------------------------------------------------template <class T> void __fastcall CPageOp<T>::OnFirst(TObject *Sender) {    First();}//---------------------------------------------------------------------------template <class T> void __fastcall CPageOp<T>::OnPrev(TObject *Sender) {    Prev();}//---------------------------------------------------------------------------template <class T> void __fastcall CPageOp<T>::OnNext(TObject *Sender) {    Next();}//---------------------------------------------------------------------------template <class T> void __fastcall CPageOp<T>::OnLast(TObject *Sender) {    Last();}//---------------------------------------------------------------------------template <class T> void __fastcall CPageOp<T>::OnGoto(TObject *Sender) {    int index = cbList_->ItemIndex;    if (index!=-1) {        GoTo(index+1);    }}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::SetPageCount(unsigned int page_count) {    page_count_ = page_count;    if (page_count==0) {        first_->Enabled = false;        prev_->Enabled = false;        next_->Enabled = false;        last_->Enabled = false;        cbList_->Clear();        return;    }    for(int i=1;i<=page_count;i++)        cbList_->Items->Add(String(i));    iv_.SetMinValue(1);    iv_.SetMaxValue(page_count_);}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::First() {    if (action_->Do(1)) {        return;    }    cur_page_ = 1;    UIControl_i();}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::Prev() {    if (action_->Do(cur_page_-1)) {        return;    }   cur_page_--;   UIControl_i();}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::Next() {    if (action_->Do(cur_page_+1)) {        return;    }   cur_page_++;   UIControl_i();}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::Last() {    if (action_->Do(page_count_)) {        return;    }    cur_page_ = page_count_;    UIControl_i();}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::UIControl_i() {   cbList_->ItemIndex = cur_page_-1;   first_->Enabled = cur_page_!=1;   prev_->Enabled = cur_page_!=1;   next_->Enabled = cur_page_!=page_count_;   last_->Enabled = cur_page_!=page_count_;}//---------------------------------------------------------------------------template <class T> void CPageOp<T>::GoTo(unsigned int page_no) {    if (action_->Do(page_no)) {        return;    }    cur_page_ = page_no;    UIControl_i();}



原创粉丝点击