学以致用C++设计模式 之 “门面模式“
时间:2022-07-23
本文章向大家介绍学以致用C++设计模式 之 “门面模式“,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
之前一直以为,把模块内聚封装起来叫”模板方法模式“,看来是我狭隘了。模板方法模式是将一组算法封装在一起,组成一个对外接口函数,而”门面模式“(我以前叫它”外观模式“)是将一个模块的函数封装出接口,组成一个模块对外开放接口组。
哦,是我读书不用功了。
实例图
整个模块打包成动态链接库,对外开放的接口只有 “增删查改” 四项功能函数名与参数列表,其余的场景类并不需要知道。 如果要拓展,也很简单,再来个操作类,依赖与数据库基类,被场景类依赖即可。
具体实现如下:
内部接口
#ifndef DB_BASE_H
#define DB_BASE_H
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<sstream>
#include<sqlite3.h>
#include<string.h>
using namespace std;
//数据库单例
class DB_base
{
public:
static DB_base* instence(char* name);//获取数据库单例
/*对查询结果进行操作*/
int return_serch_num(char* sql);//返回查询记录数
int ireturn_serch(char* sql, int n);//获取查询结果(单一结果)
char* creturn_serch(char* sql, int n);//获取查询结果(单一结果)
int ireturn_multi_serch(char* sql, int r, int c);
char* creturn_multi_serch(char* sql, int r, int c);
void ret_any(char* sql,char* ret);
bool excute(char* sql);
private:
DB_base(char* name);
~DB_base();
static DB_base* My_DB;//实例
static sqlite3* db;//数据库文件句柄
};
#endif
对外接口
#include"DB_base.h"
#include"Mutex.h"
class DB_command
{
private:
DB_base* My_DB;
Mutex* DB_Mutex;
public:
DB_command();
//增
int add_user(int id,int pwd,char* tel,char* err);
int add_file(char* file_name,int owner_id, int pwd, int mode,int dir_id,int force,char* err);//force,是否替换原文件
int add_list(int id,int pwd,int father_dir,char* dir_name,char* err);
//删
int del_user(int user_id,int pwd);
int del_file(int user_id,int pwd,int file_id,int dir_id,char* err);
int del_list(int user_id,int pwd,int dir_id,char* err);
//查
int login_check(int user_id,int pwd); //登录验证,不带目录id
int login(int user_id, int pwd,char* err); //带上id的登录验证
int pwd(int user_id,char* tel);
void file_list(int user_id,int pwd,int dir_id, char* ret,char* err);
int download(int user_id,int pwd,int file_id, int dir_id,int shared,char* err);
//改
int cpwd(int user_id, int old_pwd, int new_id,char* err);
int cfile_addr(int user_id,int pwd, int file_id, int old_dir, int new_dir,char* err);
int cdir_addr(int user_id,int pwd, int dir_id, int new_dir,char* err);
int share_file(int user_id, int pwd, int shared, int file_id, int dir_id,char* err);
int cfile_name(int user_id, int pwd, char* file_name, int file_id, int dir_id,char* err);
int cdir_name(int user_id, int pwd, char* dir_name, int dir_id,char* err);
};
场景类不需要知道函数怎么实现的,所以各位也不需要知道。 再来看看使用这个模块的一个场景:
使用场景
简单抽取一部分,其中task_db是数据库事物对象
switch (m_packet.getHead()->funcId)
{
case 0x01://登陆
{
err = new char[40];
Login_t* plogin = (Login_t*)(pData);
tru = task_db->login(plogin->id, plogin->pwd,err);
m_packet.replyLogin(tru, tru,err, m_packet.getHead()->fd);
m_send->Write_date(m_packet.getData(), m_packet.getSize());
}break;
case 0x02://注册
{
Register_t* pregister = (Register_t*)(pData);
tru = task_db->add_user(pregister->id, pregister->pwd, pregister->tel,err);
m_packet.replyRegist(tru,err,m_packet.getHead()->fd);
m_send->Write_date(m_packet.getData(), m_packet.getSize());
}break;
case 0x03://找回密码
{
F_Pwd_t* Fpwd = (F_Pwd_t*)(pData);
tru = task_db->pwd(Fpwd->id, Fpwd->tel);
m_packet.replyFpwd(tru, tru, m_packet.getHead()->fd);
m_send->Write_date(m_packet.getData(), m_packet.getSize());
}break;
门面模式
门面模式是个很好的模式,很符合面向接口编程,遵守了依赖倒置原则、迪米特法则等,当然,有些书说违背了开-闭原则,我个人认为,门面模式并不妨碍拓展,只要把基类抽取好,新功能只需要继承或依赖与基类即可。 至于说到既有功能失败而导致要修改原有功能,那跟设计模式没关系,哪个模式可以在不违背“开-闭原则”的情况下对错误功能进行修订啊?代理?适配器?还是啥?
门面模式的定义已经呼之欲出了:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
优点:高内聚,松耦合。安全,不通过门面上提供的方法,休想访问模块内部。
使用场景:还是那句:该用的时候,自然而然就用了,做一个项目的时候,应该有意识的将各个模块界定清楚,最好能达到每个都能独立封装成动态库,而后场景类调用动态库,这样一定封装的很不错了。
- ArrayList和LinkedList的区别
- 深入分析网络编程中踩过的坑
- java之自动过滤提交文本中的html代码script代码
- Enumerable#zip特性
- java小技术之生成二维码
- java实现发送邮件服务器,SMTP协议发送邮件
- HttpURLConnection实现两个服务端的对接
- java获取properties配置文件值
- 安全退出app,activoty栈管理
- JavaBean转Map方法
- JsBridge实现JavaScript和Java的互相调用
- JAVA-FTP批量大文件传输
- 独家 | 一文读懂TensorFlow(附代码、学习资料)
- 解决openssh漏洞,升级openssh版本
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 5.06-re
- Python3爬虫 利用百度地图api得到城市经纬度
- [未解决]报错: pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in y
- 6.01-re-split_chinese
- Mac上安装tesseract-OCR
- 6.02-news_re
- 6.03-news_xpath2
- 修改mysql密码
- 6.04-news_xpath3
- 6.05-btc
- 7.01-beautiful_soup
- mysql导入导出数据
- 7.01-beautiful_soup2
- 7.01-beautiful_soup3
- CentOS7上安装 JDK8 Hadoop Hive