Context(应用场景):

1、须要使用ConcreteStrategy提供的算法。

2、内部维护一个Strategy的实例。

3、 负责动态设置执行时Strategy详细的实现算法。

4、负责跟Strategy之间的交互和数据传递。

Strategy(抽象策略类):

1、 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。

ConcreteStrategy(详细策略类):

2、 实现了Strategy定义的接口,提供详细的算法实现。

UML类图:

MFC样例实现关键类代码:

// STRATEGY_MFCDlg.cpp : 实现文件
// #include "stdafx.h"
#include "STRATEGY_MFC.h"
#include "STRATEGY_MFCDlg.h"
#include "afxdialogex.h" #ifdef _DEBUG
#define new DEBUG_NEW
#endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx
{
public:
CAboutDlg(); // 对话框数据
enum { IDD = IDD_ABOUTBOX }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现
protected:
DECLARE_MESSAGE_MAP()
}; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
} void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP() // CSTRATEGY_MFCDlg 对话框 CSTRATEGY_MFCDlg::CSTRATEGY_MFCDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CSTRATEGY_MFCDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CSTRATEGY_MFCDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_PRICE, m_Edit_Price);
DDX_Control(pDX, IDC_EDIT_NUM, m_EditNum);
DDX_Control(pDX, IDC_EDIT_SHOW, m_EditShow);
DDX_Control(pDX, IDC_COMBO1, m_ComboBoxComp);
DDX_Control(pDX, IDC_EDIT_TOTAL, m_EditTotal);
} BEGIN_MESSAGE_MAP(CSTRATEGY_MFCDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_SURE, &CSTRATEGY_MFCDlg::OnBnClickedButtonSure)
ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CSTRATEGY_MFCDlg::OnBnClickedButtonClear)
END_MESSAGE_MAP() // CSTRATEGY_MFCDlg 消息处理程序 BOOL CSTRATEGY_MFCDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 将“关于...”菜单项加入�到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。当应用程序主窗体不是对话框时,框架将自己主动
// 运行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此加入�额外的初始化代码
m_ComboBoxComp.AddString(_T("正常收费"));
m_ComboBoxComp.AddString(_T("打八折"));
m_ComboBoxComp.AddString(_T("满300元返100元")); total=0.0;
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} void CSTRATEGY_MFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
} // 假设向对话框加入�最小化button,则须要以下的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自己主动完毕。 void CSTRATEGY_MFCDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
} //当用户拖动最小化窗体时系统调用此函数取得光标
//显示。
HCURSOR CSTRATEGY_MFCDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
} void CSTRATEGY_MFCDlg::OnBnClickedButtonSure()
{
// TODO: 在此加入�控件通知处理程序代码
//取单位价格
CString strPrice;
double price=0.0;
m_Edit_Price.GetWindowTextW(strPrice);
//strPrice.Format(_T("%.2f"),price);
m_strShow=m_strShow+strPrice+_T(" ");
price=_ttof(strPrice);
//取数量
CString strNum;
double num=0.0;
m_EditNum.GetWindowTextW(strNum);
//strNum.Format(_T("%.2f"),num);
m_strShow+=strNum+_T(" ");
num=_ttof(strNum);
//取计算方式
CString strComp;
//m_ComboBoxComp.SetCurSel(1);
int nIndex=m_ComboBoxComp.GetCurSel();
m_ComboBoxComp.GetLBText(nIndex,strComp);
m_strShow+=strComp;
//
CashContext* cc=NULL; if(strComp=="正常收费")
{
cc=new CashContext(new CashNormal());
}
else if(strComp=="满300元返100元")
{
cc=new CashContext(new CashReturn(_T("300"),_T("100")));
}
else if(strComp=="打八折")
{
cc=new CashContext(new CashRebate(0.8));
}
//
double totalPrice=0.0;
totalPrice=cc->GetResult(price*num);
total+=totalPrice;
CString strTemp;
strTemp.Format(_T("%.2f"),total);
m_EditTotal.SetWindowTextW(strTemp);
m_EditShow.SetWindowTextW(m_strShow);
} void CSTRATEGY_MFCDlg::OnBnClickedButtonClear()
{
// TODO: 在此加入�控件通知处理程序代码
}



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

策略模式——MFC样例的更多相关文章

  1. java文件夹相关操作 演示样例代码

    java文件夹相关操作 演示样例代码 package org.rui.io; import java.io.File; import java.io.FilenameFilter; import ja ...

  2. 设计模式之策略模式&amp;简单工厂模式

    学习设计模式已经有非常长一段时间了,事实上先前已经敲过一遍了.可是老认为没有学到什么,认识也不够深刻.如今趁着重构机房,再又一次来过,也不晚. 事实上在敲了机房之后,看看模式,事实上,曾经非常难理解. ...

  3. JavaScript设计模式 样例二 —— 策略模式

    策略模式(Strategy Pattern): 定义:定义了一族算法: 封装了每个算法: 这族的算法可互换代替. 目的:将算法的使用与算法的实现分离开来. 场景:可用来消除大量的条件分支语句. 例:J ...

  4. java 状态模式 解说演示样例代码

    package org.rui.pattern; import junit.framework.*; /** * 为了使同一个方法调用能够产生不同的行为,State 模式在代理(surrogate)的 ...

  5. Android中MVP模式与MVC模式比較(含演示样例)

    原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...

  6. Android设计模式之中的一个个样例让你彻底明确装饰者模式(Decorator Pattern)

    导读 这篇文章中我不会使用概念性文字来说明装饰者模式.由于通常概念性的问题都非常抽象.非常难懂.使得读者非常难明确究竟为什么要使用这样的设计模式.我们设计模式的诞生,肯定是前辈们在设计程序的时候遇到了 ...

  7. Android线程池(二)——ThreadPoolExecutor及其拒绝策略RejectedExecutionHandler使用演示样例

    MainActivity例如以下: package cc.vv; import java.util.concurrent.LinkedBlockingQueue; import java.util.c ...

  8. MVC模式编程演示样例-登录验证(静态)

    好,上篇博客分享了本人总结的JSP-Servlet-JavaBean三层架构编程模式的实现思想和基本流程,接下来给大家分享一个MVC编程模式的实现演示样例-登录验证的过程,这里我仍然用的是静态的验证u ...

  9. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

随机推荐

  1. abap优化工具事务代码: ST05

  2. SGU114-Telecasting station

    114. Telecasting station time limit per test: 0.5 sec. memory limit per test: 4096 KB Every city in ...

  3. 【ASP.NET Web API教程】2.3.6 创建产品和订单控制器

    原文:[ASP.NET Web API教程]2.3.6 创建产品和订单控制器 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. Part 6 ...

  4. Skype无法显示登录界面

    Skype升级之后突然抽风,双击运行程序之后,输入用户名和密码的窗口都没了,截图如下(本机为Windows 7 32bit版本): 卸载重新安装,也无济于事.删除注册表中的Skype的相关信息后问题依 ...

  5. HDU 4691(多校第九场1006) 后缀数组

    ...还能多说什么. 眼角一滴翔滑过. 一直以为题意是当前串与所有之前输入的串的LCP...然后就T了一整场. 扫了一眼标程突然发现他只比较输入的串和上一个串? 我心中突然有千万匹草泥马踏过. 然后随 ...

  6. Haproxy+Keepalived搭建Weblogic高可用负载均衡集群

    配置环境说明: KVM虚拟机配置 用途 数量 IP地址 机器名 虚拟IP地址 硬件 内存3G  系统盘20G cpu 4核 Haproxy keepalived 2台 192.168.1.10 192 ...

  7. phpStorm 新建文件SVN不提交的解决的方法

    phpStorm中新建文件夹,可是打开文件夹.却没有提交到SVN.导致每次都必须手动增加.假设新增的文件夹或者文件较多文件夹较深,easy遗漏.(default7#zbphp.com) 解决的方法: ...

  8. UVA 11054 Wine trading in Gergovia 葡萄酒交易 贪心+模拟

    题意:一题街道上很多酒店,交易葡萄酒,正数为卖出葡萄酒,负数为需要葡萄酒,总需求量和总售出量是相等的,从一家店到另外一家店需要路费(路费=距离×运算量),假设每家店线性排列且相邻两店之间距离都是1,求 ...

  9. Mojo 分析日志接口

    #!/usr/bin/perl #取文件行数 ##循环开始清空文件 use POSIX; use DBI; my $dir = '/data01/applog_backup'; my $file = ...

  10. ASI简单实现网络编程

    使用iOS SDK中的HTTP网络请求API,相当的复杂,调用比較麻烦.ASIHTTPRequest 对CFNetwork API进行了封装.而且使用起来非常easy的一套API,在非常多比較老旧的项 ...