设计模式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中设计模式之一,但在软件开发中应用也较为 ...
随机推荐
- 网络编程基础【day09】:简单socket实例(二)
本节内容 1.概述 2.socket实例 3.总结 一.概述 之前我们只是介绍了soket的概念和一些逻辑图表,下面我们来看看,socket的客户端和服务端到底是怎么用的? 二.socket实例 2. ...
- Contrast Ratio(Enhanced) (Level AAA)
Contrast ratio between your text and background is at least 7:1 All of your users will benefit from ...
- Elasticsearch集群节点配置详解
注意:如果是在局域网中运行elasticsearch集群也是很简单的,只要cluster.name设置一致,并且机器在同一网段下,启动的es会自动发现对方,组成集群. 2.elasticsearch- ...
- cdqz2017-test1-数论 (BSGS + 二次剩余 + CRT)
若m=0, 就是求n^2n ≡ x mod p (x--) 因为一定优解,所以x一定是p的二次剩余 令g为p的1个原根,且g^k ≡ x mod p 则k是偶数,证明k是偶数: 假设 g1^k1 ≡ ...
- PHP7 网络编程(六)Socket和IO多路复用【待】
https://blog.csdn.net/zhang197093/article/details/77366407
- Java秒杀系统方案优化 高性能高并发实战(1)
首先先把 springboot +thymeleaf 搞起来 ,参考 springboot 官方文档 本次学习 使用 springboot + thymeleaf+mybatis+redis+Rabb ...
- 039、Data Volume 之 bind mount (2019-02-28 周四)
参考https://www.cnblogs.com/CloudMan6/p/7142150.html Date Volume 本质上是Dokcer host文件系统中的目录或者文件,能够直接被 ...
- Tornado基本应用
Tornado简介 Tornado有自己的socket(异步非阻塞,原生支持WebSocket),Django没有. Tornado的模板语言更接近Python风格,比Django要好理解. Demo ...
- python实现单向循环链表
单向循环链表 单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点. 实现 class Node(object): """节 ...
- SQL Server进阶(七)集合运算
概述 为什么使用集合运算: 在集合运算中比联接查询和EXISTS/NOT EXISTS更方便. 并集运算(UNION) 并集:两个集合的并集是一个包含集合A和B中所有元素的集合. 在T-SQL中.UN ...