首页 > 代码库 > 简单工厂模式——MFC计算器实现

简单工厂模式——MFC计算器实现

     设计模式是重构的目标,它在代码复用和扩展方面有着非常重要的作用。学习面向对象,重构和设计模式的重要性自然不言而喻。那么,学习设计模式需要与软件设计,软件编码相结合起来,以例子为驱动。本文将通过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

参考资料:程杰 《大话设计模式》