设计模式C++学习笔记之六(Facade门面模式)
Facade门面模式,也是比较常用的一种模式,基本上所有软件系统中都会用到。 GOF 在《设计模式》一书中给出如下定义:为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。简单说,就是将复杂的逻辑封装起来,对外公开简单的接口,由客户程序调用。这里举了一个发送邮件的例子,我们理解为电子邮件吧,普通的邮件应该不需要告诉邮局,我们写的信件内容(呵呵有点较真了)。这个例子更详细的内容及说明可以参考原作者博客:cbf4life.cnblogs.com。
9.1.解释
main(),客户
ILetterProcess,接口
CLetterProcessImpl,信件处理的4个函数
CLetterPolice,警察
CModenPostOffice,邮局
说明:邮局对外只有一个窗口,接收信件内容和邮件地址。对内调用邮件处理的4个函数。将复杂逻辑封装在邮局的里面,当需要增加警察来检查信件时,只需在邮局内增加警察检查信件的方法。
注意:将复杂逻辑封装起来,对外只有一个简单的接口。
看代码:
//ILetterProcess.h
#pragma once
#include <iostream>
using std::string;
class ILetterProcess
{
public:
ILetterProcess(void);
virtual ~ILetterProcess(void);
virtual void WriteContext(string context) = 0;
virtual void FillEnvelope(string address) = 0;
virtual void LetterIntoEnvelope() = 0;
virtual void SendLetter() = 0;
};
//ILetterProcess.cpp
#include "StdAfx.h"
#include "ILetterProcess.h"
ILetterProcess::ILetterProcess(void)
{
}
ILetterProcess::~ILetterProcess(void)
{
}
//LetterprocessImpl.h
#pragma once
#include "iletterprocess.h"
class CLetterProcessImpl :
public ILetterProcess
{
public:
CLetterProcessImpl(void);
~CLetterProcessImpl(void);
void WriteContext(string context);
void FillEnvelope(string address);
void LetterIntoEnvelope();
void SendLetter();
};
//LetterProcessImpl.cpp
#include "StdAfx.h"
#include "LetterProcessImpl.h"
#include <iostream>
using std::string;
using std::cout;
using std::endl;
CLetterProcessImpl::CLetterProcessImpl(void)
{
}
CLetterProcessImpl::~CLetterProcessImpl(void)
{
}
void CLetterProcessImpl::WriteContext(string context)
{
cout << "填写信的内容... ..." << endl;
}
void CLetterProcessImpl::FillEnvelope(string address)
{
cout << "填写收件人地址及姓名... ..." << endl;
}
void CLetterProcessImpl::LetterIntoEnvelope()
{
cout << "把信放到信封中..." << endl;
}
void CLetterProcessImpl::SendLetter()
{
cout << "邮递信件..." << endl;
}
//ModenPostOffice.h
#pragma once
#include "ILetterProcess.h"
#include "LetterProcessImpl.h"
#include "LetterPolice.h"
#include <iostream>
using std::string;
class CModenPostOffice
{
public:
CModenPostOffice(void);
~CModenPostOffice(void);
void SendLetter(string context, string address);
private:
ILetterProcess *m_pLetterProcess;
CLetterPolice *m_pLetterPolice;
};
//ModenPostOffice.cpp
#include "StdAfx.h"
#include "ModenPostOffice.h"
CModenPostOffice::CModenPostOffice(void)
{
this->m_pLetterProcess = new CLetterProcessImpl();
this->m_pLetterPolice = new CLetterPolice();
}
CModenPostOffice::~CModenPostOffice(void)
{
delete m_pLetterProcess;
delete m_pLetterPolice;
}
void CModenPostOffice::SendLetter( string context, string address )
{
//帮忙写信
m_pLetterProcess->WriteContext(context);
//写好信封
m_pLetterProcess->FillEnvelope(address);
//警察要检查信件了
m_pLetterPolice->CheckLetter(m_pLetterProcess);
//把信放到信封中
m_pLetterProcess->LetterIntoEnvelope();
//邮递信件
m_pLetterProcess->SendLetter();
}
//LetterPolice.h
#pragma once
#include "ILetterProcess.h"
class CLetterPolice
{
public:
CLetterPolice(void);
~CLetterPolice(void);
void CheckLetter(ILetterProcess *pLetterProcess);
};
//LetterPolice.cpp
#include "StdAfx.h"
#include "LetterPolice.h"
CLetterPolice::CLetterPolice(void)
{
}
CLetterPolice::~CLetterPolice(void)
{
}
void CLetterPolice::CheckLetter( ILetterProcess *pLetterProcess )
{
//检查信件,此处省略一万字。
return;
}
//Facade.cpp
#include "stdafx.h"
#include "ILetterProcess.h"
#include "LetterProcessImpl.h"
#include "ModenPostOffice.h"
#include<iostream>
using std::string;
using std::cout;
using std::endl;
void DoItByPostOffice()
{
CModenPostOffice modenPostOffice;
string context = "Hello, It's me, do you know who I am? I'm your old lover. I'd like to ... ...";
string address = "Happy Road No. 666, Beijing City, China";
modenPostOffice.SendLetter(context, address);
}
void DoItYourself()
{
ILetterProcess *pLetterProcess = new CLetterProcessImpl();
pLetterProcess->WriteContext("Hello, It's me, do you know who I am? I'm your old lover. I'd like to ... ...");
pLetterProcess->FillEnvelope("Happy Road No. 666, Beijing City, China");
pLetterProcess->LetterIntoEnvelope();
pLetterProcess->SendLetter();
delete pLetterProcess;
}
int _tmain(int argc, _TCHAR* argv[])
{
//现在的调用方式。对于客户来说确实简单多了。
//如需要增加逻辑,例如让警察来检查邮件。可以在邮局里完成这项工作。
DoItByPostOffice();
//原来的调用方式。
DoItYourself();
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
_CrtDumpMemoryLeaks();
return 0;
}

上面的图仍然只是类图而已,用于帮助理解代码中类之间的关系,而不是模式的抽象类图。CModenPostOffice封装了复杂的处理逻辑,对外只有SendLetter这个函数接口。使客户程序容易了解到想要做什么,应该告诉邮局什么内容,邮局才能正确的工作。
目前为止,还都是比较简单的模式,越到后面越复杂。我的理解是当没有模式的时候,大家编写代码也需要考虑扩展性、伸缩性、稳定性等等。那个时候大家写程序都是自己在摸索经验,逐渐的才意识到程序应该可以适应需求的变化。于是总结很多方法来,让程序既能适应变化,又有一定的可靠性。这使得编程序更有趣,也更抽象了。所以软件开发就是提炼和抽象的过程。类似于哲学的提炼,从特殊到一般。
设计模式C++学习笔记之六(Facade门面模式)的更多相关文章
- 【设计模式】学习笔记17:代理模式之保护代理与Java反射
本文出自 http://blog.csdn.net/shuangde800 本笔记内容: 1. Java动态代理,反射机制 2. 保护代理 3. 应用保护代理实现的约会系统 ----------- ...
- 【设计模式】学习笔记15:代理模式(Proxy Pattern)
本文出自 http://blog.csdn.net/shuangde800 本笔记内容: 1. JAVA远程代理调用(RMI) 2. 代理模式 走进代理模式 在上一篇的状态模式中,我们实现了一个糖 ...
- 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式
装饰者模式是JDK中还有一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源代码,也是为了学习大牛们的设计思路.--- ...
- 【设计模式】学习笔记13:组合模式(Composite)
本文出自 http://blog.csdn.net/shuangde800 认识组合模式 上一篇中,我们可以用迭代器来实现遍历一个集合(数组,ArrayList, Vector, HashTabl ...
- 设计模式实例(Lua)笔记之六(Adapter模式)
1.描写叙述 "我"在 2004 年的时候带了一个项目,做一个人力资源管理,该项目是我们总公司发起的项目,公司一共同拥有 700 多号人,包含子公司,这个项目还是比較简单的,分为三 ...
- 《Head first设计模式》学习笔记 – 迭代器模式
<Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...
- jsp学习笔记:mvc开发模式
jsp学习笔记:mvc开发模式2017-10-12 22:17:33 model(javabe)与view层交互 view(视图层,html.jsp) controller(控制层,处理用户提交的信息 ...
- 【Visual C++】游戏编程学习笔记之六:多背景循环动画
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
随机推荐
- Python中表达式与语句
简述 Python中我暂时并未发现谁对着两个名词的明确定义:我对这两个名词的理解就是,表达式就是你想要执行的对象,语句就是你的具体执行操作. 这里应用慕课网老师的一段话,摘自网上"表达式(E ...
- PHP6天基础知识部分
---恢复内容开始--- (一).基础(PHP超文本预处理器) 1.PHP标记(2种) 1.<?php?>:大众的用法?和php之间不能有空格否则无效. 2.<??>:小众的用 ...
- HDU 1021(斐波那契数与因子3 **)
题意是说在给定的一种满足每一项等于前两项之和的数列中,判断第 n 项的数字是否为 3 的倍数. 斐波那契数在到第四十多位的时候就会超出 int 存储范围,但是题目问的是是否为 3 的倍数,也就是模 3 ...
- extern "C" 含义
extern "C" 被 extern 限定的函数或变量是 extern 类型的 被 extern "C" 修饰的变量和函数是按照 C 语言方式编译和链接的 e ...
- Openresty 学习笔记(四)lualocks包管理器安装使用
Luarocks是一个Lua包管理器,基于Lua语言开发,提供一个命令行的方式来管理Lua包依赖.安装第三方Lua包等,社区比较流行的包管理器之一,另还有一个LuaDist,Luarocks的包数量比 ...
- 细说tomcat之集群session共享方案
1. Tomcat Cluster官网:http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.htmlTomcat原生支持的集群方案,通过组播消息 ...
- 一个不错的Html5 DatePicker控件,主要支持手机端。
原地址不知道在哪了,下载地址 QQ群:616945527 Html5控件wen文件夹中DatePicker.rar
- C++使用libcurl
1.下载地址https://curl.haxx.se/download.html 2.选择zip压缩包下载 3.选择合适自己的vc版本 4.启动项目选择libcurl 5.因为暂时不需要ssh2,预处 ...
- QWidget-控件层级关系
lower() 将控件降低到最底层 raise_() 将控件提升到最上层 label.raise_() a.stackUnder(b) 让a放在b下面 注意:以上操作专指同级控件 ...
- 转载-HashMap1.7源码分析
原文地址-https://www.cnblogs.com/chengxiao/p/6059914.html HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重 ...