设计模式是重构的目标,它在代码复用和扩展方面有着非常重要的作用。学习面向对象,重构和设计模式的重要性自然不言而喻。那么,学习设计模式需要与软件设计,软件编码相结合起来,以例子为驱动。本文将通过MFC计算器的实现来学习简单工厂模式。
无论怎么样,首先应该抽象出MFC计算器的实体类。通过查找名词,动名词等等,准确找到实体类是第一步。
显然,它的核心实体类是Operator运算类。细想之,它的实现恰好与简单工厂密切相关。
简单工厂模式解释:
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式的UML图:
简单工厂模式中包含的角色及其相应的职责如下:
工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。
抽象(Product)产品角色:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。
计算器的设计自然就出来了,请看类图。
在这里,C++语言的多态特性——父类对象指针操作子类对象。核心类是OperatorFactory 和 Operator 。以字符串传参。
下面附上关键代码和工程分享。
// CALCULATOR_MFCDlg.h : 头文件 // #pragma once #include <stack> #include "afxwin.h" //#include "Operator.h" #include "OpertorFactory.h" using namespace std; // CCALCULATOR_MFCDlg 对话框 class CCALCULATOR_MFCDlg : public CDialogEx { // 构造 public: CCALCULATOR_MFCDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据 enum { IDD = IDD_CALCULATOR_MFC_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedButton0(); CEdit m_EditNumA; CEdit m_EditOperator; CEdit m_EditNumB; //CString m_strNumA; double m_NumA; double m_NumB; double m_Num; double m_Result; CString m_strTemp; char m_Oper; afx_msg void OnBnClickedButtonpoint(); afx_msg void OnBnClickedButtonequal(); afx_msg void OnBnClickedButton1(); afx_msg void OnBnClickedButton2(); afx_msg void OnBnClickedButton3(); afx_msg void OnBnClickedButton4(); afx_msg void OnBnClickedButton5(); afx_msg void OnBnClickedButton6(); afx_msg void OnBnClickedButton7(); afx_msg void OnBnClickedButton8(); afx_msg void OnBnClickedButton9(); afx_msg void OnBnClickedButtonadd(); afx_msg void OnBnClickedButtonsub(); afx_msg void OnBnClickedButtonmul(); afx_msg void OnBnClickedButtondiv(); afx_msg void OnBnClickedButtonclear(); double StrTempToDou(); stack<double> S_Num; stack<char>S_Oper; //OpertorFactory OF; double GetFinalResult(double a,double b,char op); void CalSNum(); void ExEOperator(char op); };
void CCALCULATOR_MFCDlg::OnBnClickedButton0() { // TODO: 在此添加控件通知处理程序代码 //CString str=_T("0"); //m_EditNumA.GetWindowText(str); m_strTemp+=_T("0"); //m_strNumA+=str; m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButtonpoint() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("."); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButtonequal() { // TODO: 在此添加控件通知处理程序代码 //OpertorFactory OF; /* m_NumB=StrTempToDou(); m_strTemp=_T(""); Operator* oper=NULL; oper=OF.createOperator(m_Oper); oper->SetNumberA(m_NumA); oper->SetNumberB(m_NumB); double result=oper->GetResult(); m_Result=result; //m_NumA=m_Result; m_strTemp.Format(_T("%.2f"),result); m_EditNumA.SetWindowTextW(m_strTemp); m_EditNumB.SetWindowTextW(_T("")); */ m_Num=StrTempToDou(); m_strTemp=_T(""); S_Num.push(m_Num); /* double a=S_Num.top(); S_Num.pop(); double b=S_Num.top(); S_Num.pop(); char op=S_Oper.top(); S_Oper.pop(); m_Result=GetFinalResult(a,b,op); */ CalSNum(); m_strTemp.Format(_T("%.2f"),m_Result); m_EditNumA.SetWindowTextW(m_strTemp); //clear while(!S_Num.empty())S_Num.pop(); while(!S_Oper.empty())S_Oper.pop(); m_Result=0.0; } void CCALCULATOR_MFCDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("1"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("2"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("3"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton4() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("4"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton5() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("5"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton6() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("6"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton7() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("7"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton8() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("8"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButton9() { // TODO: 在此添加控件通知处理程序代码 m_strTemp+=_T("9"); m_EditNumA.SetWindowTextW(m_strTemp); } void CCALCULATOR_MFCDlg::OnBnClickedButtonadd() { // TODO: 在此添加控件通知处理程序代码 /* m_NumA=StrTempToDou(); m_strTemp+=_T("+"); m_EditNumB.SetWindowTextW(m_strTemp); m_Oper='+'; //UpdateData(FALSE); m_strTemp=_T(""); m_EditNumA.SetWindowTextW(m_strTemp); S.push(m_NumA); if(S.size==2) { } */ /* m_Num=StrTempToDou(); m_strTemp=_T(""); S_Num.push(m_Num); if(S_Num.size()==2) { /* double A=S_Num.top(); S_Num.pop(); double B=S_Num.top(); S_Num.pop(); char op=S_Oper.top(); S_Oper.pop(); m_Result=GetFinalResult(A,B,op); CalSNum(); S_Num.push(m_Result); S_Oper.push('+'); } else { //S_Num.push(m_Num); S_Oper.push('+'); } */ ExEOperator('+'); } void CCALCULATOR_MFCDlg::OnBnClickedButtonsub() { // TODO: 在此添加控件通知处理程序代码 ExEOperator('-'); } void CCALCULATOR_MFCDlg::OnBnClickedButtonmul() { // TODO: 在此添加控件通知处理程序代码 ExEOperator('*'); } void CCALCULATOR_MFCDlg::OnBnClickedButtondiv() { // TODO: 在此添加控件通知处理程序代码 ExEOperator('/'); } void CCALCULATOR_MFCDlg::OnBnClickedButtonclear() { // TODO: 在此添加控件通知处理程序代码 //m_strTemp+=_T("."); m_EditNumA.SetWindowTextW(_T("")); } double CCALCULATOR_MFCDlg::StrTempToDou() { double Num=0.0;//=atof(m_strTemp); //m_strTemp.Format(_T("%.2f"),Num); Num=_ttof(m_strTemp); //m_strTemp=_T(""); return Num; } double CCALCULATOR_MFCDlg::GetFinalResult(double a,double b,char op) { OpertorFactory OF; Operator* oper=NULL; oper=OF.createOperator(op); oper->SetNumberA(a); oper->SetNumberB(b); double result=oper->GetResult(); return result; } void CCALCULATOR_MFCDlg::CalSNum() { double A=S_Num.top(); S_Num.pop(); double B=S_Num.top(); S_Num.pop(); char op=S_Oper.top(); S_Oper.pop(); if(op=='+' || op=='*') m_Result=GetFinalResult(A,B,op); else m_Result=GetFinalResult(B,A,op); } void CCALCULATOR_MFCDlg::ExEOperator(char op) { m_Num=StrTempToDou(); m_strTemp=_T(""); S_Num.push(m_Num); if(S_Num.size()==2) { /* double A=S_Num.top(); S_Num.pop(); double B=S_Num.top(); S_Num.pop(); char op=S_Oper.top(); S_Oper.pop(); m_Result=GetFinalResult(A,B,op); */ CalSNum(); S_Num.push(m_Result); S_Oper.push(op); } else { //S_Num.push(m_Num); S_Oper.push(op); } }
MFC工程下载:http://download.csdn.net/detail/greenapple_shan/7735979
参考资料:程杰 《大话设计模式》
简单工厂模式——MFC计算器实现