实战运用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;
门面模式
门面模式是个很好的模式,很符合面向接口编程,遵守了依赖倒置原则、迪米特法则等,当然,有些书说违背了开-闭原则,我个人认为,门面模式并不妨碍拓展,只要把基类抽取好,新功能只需要继承或依赖与基类即可。 至于说到既有功能失败而导致要修改原有功能,那跟设计模式没关系,哪个模式可以在不违背“开-闭原则”的情况下对错误功能进行修订啊?代理?适配器?还是啥?
门面模式的定义已经呼之欲出了:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
优点:高内聚,松耦合。安全,不通过门面上提供的方法,休想访问模块内部。
使用场景:还是那句:该用的时候,自然而然就用了,做一个项目的时候,应该有意识的将各个模块界定清楚,最好能达到每个都能独立封装成动态库,而后场景类调用动态库,这样一定封装的很不错了。
下一篇: 外观模式:Java设计模式详解
推荐阅读
-
实战运用C++设计模式:门面模式详解
-
4.1安全版组合模式:运用树状结构 - 结构型设计模式详解
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
C++ 单一示例设计模式详解
-
入门设计模式实战:第七章详解适配器模式——实例篇
-
入门JAVA设计模式:门面模式(外观模式)详解