打包,一种简洁的美
封装,一种简洁的美
代码的封装是复用的基础,同时封装使得代码模块的内聚性增强;通过提供接口与外界通信,大大削弱了模块之间的耦合;
一般来说,我们把几句执行一定功能的语句,编写成一个函数,这是一种封装;把几个执行一定功能的函数在放到一个类中统一管理,这也是一种封装。我们可以把封装后的模块想像成一块集成电路,接口就是管脚;配置完成后,有输入,就会有输出;我们不管它的具体实现,只考量它的逻辑功能;
按照封装的思想,我编写了绘制柱状图的类CBar和一维数据柱状图显示类CDataBar。代码如下:
头文件:
/* 文件名:Bar.h 功能: 棒状图绘制,可作为振动监测状态或进度条使用 */ class CBar { public: CBar(); virtual ~CBar(); void SetBarRange(double min,double max); void SetBarValue(double value); void SetBarColor(COLORREF rgb); void DrawBar(CRect &client,CClientDC &dc); private: double m_min,m_max; double m_value; COLORREF m_rgb; };
实现文件:
/* 实现文件: Bar.cpp */ CBar::CBar() { m_min=0; m_max=100.0; m_value=0; m_rgb=RGB(255,0,0); } CBar::~CBar() { } void CBar::SetBarColor(COLORREF rgb) { m_rgb=rgb; } void CBar::SetBarValue(double value) { if(value>m_max) { AfxMessageBox("超过最大值!"); return; } m_value=value; } void CBar::SetBarRange(double min,double max) { m_min=min; m_max=max; } void CBar::DrawBar(CRect &client,CClientDC &dc) { CRect m_client; CRect m_bar; CBrush *pBrush=NULL; pBrush=new CBrush(m_rgb); int N=100; double dh=(double)client.Height()/N; double dvalue=(m_max-m_min)/N; int N2=m_value/dvalue; m_bar.left =client.left; m_bar.right =client.right; m_bar.top =client.bottom -N2*dh; m_bar.bottom =client.bottom; m_client=client; m_client.InflateRect(1,1,1,1); dc.Rectangle(m_client); dc.FillRect(m_bar,pBrush); dc.SetBkMode(TRANSPARENT); CString cs; cs.Format("%.2f",m_min); dc.TextOut(m_client.right +2,m_client.bottom -15,cs); cs.Format("%.2f",m_max); dc.TextOut(m_client.right+2,m_client.top +2,cs); cs.Format("%.2f",m_value); dc.TextOut(m_client.right,(m_client.top+m_client.bottom)/2,cs); delete pBrush; pBrush=NULL; }
调用范例:
CClientDC dc(this); CRect m_bar1(100,50,150,190); CRect m_bar2(200,50,250,190); CBar bar; bar.SetBarRange(0,100); bar.SetBarColor(RGB(0,255,0)); bar.SetBarValue(50); bar.DrawBar(m_bar1,dc); bar.SetBarRange(0,100); bar.SetBarValue(25); bar.SetBarColor(RGB(0,0,255)); bar.DrawBar(m_bar2,dc);
运行效果:
基于相同原理,CDataBar代码略。其测试效果如下: