目录
[1. 什么是设计模式?](#1. 什么是设计模式?)
[2. 设计模式的核心分类](#2. 设计模式的核心分类)
[3. Linux C++设计模式核心原则](#3. Linux C++设计模式核心原则)
[1. 单例模式(Singleton)------ 全局唯一实例](#1. 单例模式(Singleton)—— 全局唯一实例)
[1. 核心原理](#1. 核心原理)
[2. Linux C++实现(三种方案,按优先级排序)](#2. Linux C++实现(三种方案,按优先级排序))
[3. Linux实战场景与面试考点](#3. Linux实战场景与面试考点)
[2. 工厂方法模式(Factory Method)------ 封装对象创建](#2. 工厂方法模式(Factory Method)—— 封装对象创建)
[1. 核心原理](#1. 核心原理)
[2. Linux C++实现(协议解析场景)](#2. Linux C++实现(协议解析场景))
[3. 优化与场景](#3. 优化与场景)
[3. 其他创建型模式](#3. 其他创建型模式)
[1. 适配器模式(Adapter)------ 接口兼容转换](#1. 适配器模式(Adapter)—— 接口兼容转换)
[1. 核心原理](#1. 核心原理)
[2. Linux C++实现(系统调用适配场景)](#2. Linux C++实现(系统调用适配场景))
[3. 实战场景](#3. 实战场景)
[2. 代理模式(Proxy)------ 资源管控与增强](#2. 代理模式(Proxy)—— 资源管控与增强)
[1. 核心原理](#1. 核心原理)
[2. Linux C++实现(权限代理场景)](#2. Linux C++实现(权限代理场景))
[3. 装饰器模式(Decorator)------ 动态增强功能](#3. 装饰器模式(Decorator)—— 动态增强功能)
[1. 观察者模式(Observer)------ 事件通知机制](#1. 观察者模式(Observer)—— 事件通知机制)
[1. 核心原理](#1. 核心原理)
[2. Linux C++实现(服务器连接事件通知)](#2. Linux C++实现(服务器连接事件通知))
[3. 注意事项](#3. 注意事项)
[2. 策略模式(Strategy)------ 动态切换算法](#2. 策略模式(Strategy)—— 动态切换算法)
[3. 模板方法模式(Template Method)------ 框架钩子设计](#3. 模板方法模式(Template Method)—— 框架钩子设计)
[1. Linux高性能日志服务器](#1. Linux高性能日志服务器)
[1. 架构设计(多模式组合)](#1. 架构设计(多模式组合))
[2. 核心代码框架](#2. 核心代码框架)
[1. 单例模式的线程安全实现方案对比?Linux内核与用户态实现差异?](#1. 单例模式的线程安全实现方案对比?Linux内核与用户态实现差异?)
[2. 工厂方法与抽象工厂的区别?Linux场景下如何选择?](#2. 工厂方法与抽象工厂的区别?Linux场景下如何选择?)
[3. 观察者模式在多线程场景下的线程安全问题如何解决?](#3. 观察者模式在多线程场景下的线程安全问题如何解决?)
[4. 适配器模式与装饰器模式的核心差异?各自适用场景?](#4. 适配器模式与装饰器模式的核心差异?各自适用场景?)
[5. 设计模式过度使用的危害?Linux项目中如何把握度?](#5. 设计模式过度使用的危害?Linux项目中如何把握度?)
[6. 单例模式在Linux服务器集群场景下的局限性?如何解决?](#6. 单例模式在Linux服务器集群场景下的局限性?如何解决?)
设计模式是解决软件设计中重复问题的标准化方案,是Linux C++开发从"能实现"到"写优雅、可扩展、高可靠代码"的核心桥梁。
一、设计模式基础认知
1. 什么是设计模式?
设计模式是对"软件设计中反复出现的问题、解决方案、场景约束"的总结提炼,本质是可复用的架构经验模板。它不是现成代码,而是一套设计思路,核心目标是:
- 解耦:分离模块职责,降低组件间依赖(如Linux服务器中业务逻辑与网络IO解耦)。
- 可扩展:新增功能无需修改原有代码(如新增日志输出方式、协议类型)。
- 可维护:代码逻辑清晰、符合直觉,便于定位问题与迭代(如内核模块的分层设计)。
- 高可靠:规避资源泄漏、线程安全等常见坑(如单例模式的线程安全实现)。
类比:设计模式像Linux系统的"命令范式"------ls、cd等命令对应固定场景的解决方案,无需重复造轮子;设计模式对应软件设计的"场景范式",如"全局唯一实例"用单例模式,"多模块通知"用观察者模式。
2. 设计模式的核心分类
| 分类 | 核心目标 | Linux C++高频模式 | 典型场景 |
|---|---|---|---|
| 创建型模式 | 控制对象创建过程,隐藏创建细节,优化资源分配 | 单例、工厂方法、抽象工厂、建造者 | 日志器、线程池、配置解析器、对象池 |
| 结构型模式 | 优化对象组合关系,实现灵活的结构适配与功能扩展 | 适配器、装饰器、代理、组合 | 系统调用封装、日志增强、权限代理、目录树遍历 |
| 行为型模式 | 规范对象间交互行为,实现职责分配与通信解耦 | 观察者、策略、模板方法、命令 | 服务器事件通知、算法切换、框架钩子、任务队列 |
3. Linux C++设计模式核心原则
设计模式的底层逻辑围绕5大原则展开,是判断代码设计优劣的核心标准:
- 单一职责:一个类只负责一项功能(如Linux日志类只处理日志,不负责配置读取)。
- 开放封闭:对扩展开放、对修改关闭(如新增日志输出到文件,无需修改日志核心逻辑)。
- 依赖倒置:依赖抽象而非具体实现(如线程池依赖"任务抽象接口",而非具体业务任务)。
- 接口隔离:拆分庞大接口为专用接口(如Linux驱动接口拆分,避免依赖无用方法)。
- 里氏替换:子类可替换父类且不改变原有逻辑(如不同协议解析子类替换,不影响上层调用)。
二、创建型模式:精准控制对象创建
1. 单例模式(Singleton)------ 全局唯一实例
1. 核心原理
保证一个类在全局只有一个实例,提供唯一访问入口,避免重复创建对象导致的资源浪费(如Linux日志器、配置管理器)。核心约束:私有构造函数、静态实例、静态访问方法。
2. Linux C++实现(三种方案,按优先级排序)
cpp
#include <iostream>
#include <pthread.h>
#include <atomic>
using namespace std;
// 方案1:C++11静态局部变量(推荐,线程安全、简洁)
class Singleton {
private:
// 私有构造/析构,禁止外部创建/销毁
Singleton() { /* 初始化资源,如打开日志文件 */ }
~Singleton() { /* 释放资源,如关闭文件 */ }
// 禁止拷贝/赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
// 静态访问接口,C++11保证静态局部变量初始化线程安全
static Singleton& GetInstance() {
static Singleton instance; // 首次调用时初始化,仅一次
return instance;
}
// 业务方法(示例:日志输出)
void Log(const string& msg) {
cout << "[Log] " << msg << endl;
}
};
// 方案2:懒汉模式(双重检查锁定,兼容C++11前)
class SingletonLazy {
private:
SingletonLazy() {}
~SingletonLazy() {}
SingletonLazy(const SingletonLazy&) = delete;
SingletonLazy& operator=(const SingletonLazy&) = delete;
static atomic<SingletonLazy*> instance; // 原子变量保证线程安全
static pthread_mutex_t mutex; // 互斥锁
public:
static SingletonLazy* GetInstance() {
SingletonLazy* ptr = instance.load(memory_order_acquire);
if (!ptr) { // 第一次检查,避免每次加锁
pthread_mutex_lock(&mutex);
ptr = instance.load(memory_order_relaxed);
if (!ptr) { // 第二次检查,防止多线程并发创建
ptr = new SingletonLazy();
instance.store(ptr, memory_order_release);
}
pthread_mutex_unlock(&mutex);
}
return ptr;
}
// 手动释放(可选,适用于内核模块等无析构时机场景)
static void DestroyInstance() {
SingletonLazy* ptr = instance.load(memory_order_acquire);
if (ptr) {
delete ptr;
instance.store(nullptr, memory_order_release);
}
}
};
// 初始化静态成员
atomic<SingletonLazy*> SingletonLazy::instance(nullptr);
pthread_mutex_t SingletonLazy::mutex = PTHREAD_MUTEX_INITIALIZER;
// 方案3:饿汉模式(预初始化,线程安全但浪费资源)
class SingletonHungry {
private:
SingletonHungry() {}
~SingletonHungry() {}
SingletonHungry(const SingletonHungry&) = delete;
SingletonHungry& operator=(const SingletonHungry&) = delete;
static SingletonHungry instance; // 程序启动时初始化
public:
static SingletonHungry& GetInstance() {
return instance;
}
};
SingletonHungry SingletonHungry::instance; // 全局静态变量初始化
// 测试代码
int main() {
// 方案1调用
Singleton::GetInstance().Log("Hello Linux Singleton");
// 方案2调用
SingletonLazy::GetInstance()->Log("Lazy Singleton Test");
// 方案3调用
SingletonHungry::GetInstance().Log("Hungry Singleton Test");
SingletonLazy::DestroyInstance();
return 0;
}
3. Linux实战场景与面试考点
实战场景:系统日志器、全局配置管理器、线程池实例、内核模块中的全局控制器。
面试考点:
- 线程安全实现:C++11静态局部变量的线程安全原理(编译器生成初始化屏障)、双重检查锁定的原子操作必要性(避免指令重排)。
- 销毁时机:用户态程序依赖析构函数自动销毁,内核模块需手动调用DestroyInstance(无进程退出析构时机)。
- 优缺点对比:饿汉(简单但预占资源)、懒汉(按需初始化但需锁)、静态局部变量(兼顾简洁与安全,推荐生产使用)。
2. 工厂方法模式(Factory Method)------ 封装对象创建
1. 核心原理
定义一个创建对象的接口,由子类决定具体创建哪种对象,实现"创建与使用分离"。适用于Linux中"同一接口、多种实现"场景(如不同协议解析器、不同存储引擎)。
2. Linux C++实现(协议解析场景)
cpp
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
// 抽象产品:协议解析器接口
class IProtocolParser {
public:
virtual ~IProtocolParser() {} // 虚析构,保证子类析构
virtual string Parse(const string& data) = 0; // 纯虚方法,协议解析
};
// 具体产品1:HTTP协议解析器
class HttpParser : public IProtocolParser {
public:
string Parse(const string& data) override {
return "[HTTP] Parse Data: " + data;
}
};
// 具体产品2:TCP协议解析器
class TcpParser : public IProtocolParser {
public:
string Parse(const string& data) override {
return "[TCP] Parse Data: " + data;
}
};
// 抽象工厂:协议解析器工厂接口
class IProtocolFactory {
public:
virtual ~IProtocolFactory() {}
virtual IProtocolParser* CreateParser() = 0; // 工厂方法
};
// 具体工厂1:HTTP工厂
class HttpFactory : public IProtocolFactory {
public:
IProtocolParser* CreateParser() override {
return new HttpParser();
}
};
// 具体工厂2:TCP工厂
class TcpFactory : public IProtocolFactory {
public:
IProtocolParser* CreateParser() override {
return new TcpParser();
}
};
// Linux服务端调用示例
int main() {
// 模拟根据配置选择协议工厂
string protocol_type = "HTTP"; // 可从配置文件读取
IProtocolFactory* factory = nullptr;
if (protocol_type == "HTTP") {
factory = new HttpFactory();
} else if (protocol_type == "TCP") {
factory = new TcpFactory();
}
// 创建解析器并使用
if (factory) {
IProtocolParser* parser = factory->CreateParser();
cout << parser->Parse("GET /index.html HTTP/1.1") << endl;
delete parser;
delete factory;
}
return 0;
}
3. 优化与场景
优化点:1. 结合单例模式,让工厂实例全局唯一;2. 用智能指针(unique_ptr/shared_ptr)管理对象,避免内存泄漏;3. 增加工厂注册机制(哈希表),支持动态扩展协议类型。
实战场景:Linux服务器协议解析模块、数据库中间件存储引擎适配、日志输出器工厂(控制台/文件/网络日志)。
3. 其他创建型模式
- 抽象工厂模式:工厂方法的扩展,用于创建"一组相关联的对象"(如Linux GUI中的按钮、文本框属于同一主题),适用于成套组件创建场景。
- 建造者模式:拆分复杂对象的构建过程,分步构建(如Linux内核进程控制块PCB的创建,分步初始化PID、内存空间、文件描述符),适用于对象构造逻辑复杂场景。
三、结构型模式:优化对象组合与适配
1. 适配器模式(Adapter)------ 接口兼容转换
1. 核心原理
将一个类的接口转换成客户端期望的另一个接口,解决不同接口间的兼容性问题(如Linux系统调用封装、第三方库接口适配)。分为类适配器(继承)和对象适配器(组合,推荐)。
2. Linux C++实现(系统调用适配场景)
cpp
#include <iostream>
#include <unistd.h> // Linux系统调用头文件
#include <string>
using namespace std;
// 目标接口:客户端期望的文件操作接口(统一封装)
class IFileOperator {
public:
virtual ~IFileOperator() {}
virtual bool Write(const string& data) = 0; // 写入数据
virtual bool Close() = 0; // 关闭文件
};
// 适配者:Linux原生系统调用(接口不统一,需适配)
class LinuxFileSys {
public:
// 原生系统调用封装
int Open(const string& path) {
return open(path.c_str(), O_WRONLY | O_CREAT, 0644); // 打开/创建文件
}
ssize_t Write(int fd, const string& data) {
return write(fd, data.c_str(), data.size()); // 原生写入
}
int Close(int fd) {
return close(fd); // 原生关闭
}
private:
int fd_ = -1; // 文件描述符
};
// 对象适配器:组合适配者,实现目标接口
class FileAdapter : public IFileOperator {
public:
FileAdapter(const string& path) : path_(path) {}
~FileAdapter() {
if (fd_ != -1) {
linux_file_.Close(fd_);
}
}
// 适配Write接口
bool Write(const string& data) override {
if (fd_ == -1) {
fd_ = linux_file_.Open(path_);
if (fd_ == -1) {
cerr << "Open file failed: " << strerror(errno) << endl;
return false;
}
}
ssize_t ret = linux_file_.Write(fd_, data);
return ret == data.size();
}
// 适配Close接口
bool Close() override {
if (fd_ != -1) {
int ret = linux_file_.Close(fd_);
fd_ = -1;
return ret == 0;
}
return true;
}
private:
LinuxFileSys linux_file_; // 组合适配者
string path_; // 文件路径
int fd_ = -1; // 文件描述符
};
// 客户端调用(无需关心原生系统调用,依赖统一接口)
int main() {
IFileOperator* file_op = new FileAdapter("/tmp/adapter_test.txt");
if (file_op->Write("Hello Linux Adapter Pattern")) {
cout << "Write success" << endl;
}
file_op->Close();
delete file_op;
return 0;
}
3. 实战场景
Linux系统调用封装(如将open/write/close适配为统一文件接口)、第三方库接口适配(如不同日志库适配为自定义日志接口)、内核驱动接口适配(将不同硬件驱动适配为统一内核接口)。
2. 代理模式(Proxy)------ 资源管控与增强
1. 核心原理
为对象提供一个代理类,控制对原对象的访问,可实现权限校验、资源缓存、日志增强等功能(如Linux权限代理、远程服务代理)。
2. Linux C++实现(权限代理场景)
cpp
#include <iostream>
#include <string>
#include <unistd.h> // 获取用户ID
using namespace std;
// 抽象主题:文件操作接口
class IFileAccess {
public:
virtual ~IFileAccess() {}
virtual bool Read(const string& path) = 0;
virtual bool Write(const string& path, const string& data) = 0;
};
// 真实主题:实际文件操作
class RealFileAccess : public IFileAccess {
public:
bool Read(const string& path) override {
cout << "Read file: " << path << endl;
return true;
}
bool Write(const string& path, const string& data) override {
cout << "Write file: " << path << ", Data: " << data << endl;
return true;
}
};
// 代理类:权限校验代理(Linux用户权限控制)
class PermissionProxy : public IFileAccess {
public:
PermissionProxy(IFileAccess* real_access) : real_access_(real_access) {}
~PermissionProxy() {
delete real_access_;
}
bool Read(const string& path) override {
// 权限校验:只有root用户(UID=0)可读取
if (getuid() != 0) {
cerr << "Permission denied: Only root can read " << path << endl;
return false;
}
return real_access_->Read(path);
}
bool Write(const string& path, const string& data) override {
if (getuid() != 0) {
cerr << "Permission denied: Only root can write " << path << endl;
return false;
}
return real_access_->Write(path, data);
}
private:
IFileAccess* real_access_; // 真实对象
};
// 客户端调用
int main() {
IFileAccess* file_access = new PermissionProxy(new RealFileAccess());
// 非root用户运行时,权限校验失败
file_access->Read("/etc/passwd");
file_access->Write("/etc/passwd", "test");
delete file_access;
return 0;
}
3. 装饰器模式(Decorator)------ 动态增强功能
动态给对象添加额外功能,无需修改原类代码(符合开放封闭原则)。适用于Linux日志增强、网络IO过滤等场景,比继承更灵活。
实战场景:给基础日志器添加"时间戳装饰""级别过滤装饰",给网络请求添加"加密装饰""日志装饰"。
四、行为型模式:规范对象交互(服务器核心)
1. 观察者模式(Observer)------ 事件通知机制
1. 核心原理
定义对象间的一对多依赖关系,当一个对象状态变化时,所有依赖它的对象会自动收到通知并更新。适用于Linux事件驱动场景(如服务器连接事件、内核信号通知)。
2. Linux C++实现(服务器连接事件通知)
cpp
#include <iostream>
#include <vector>
#include <string>
#include <pthread.h>
using namespace std;
// 前向声明
class Subject;
// 抽象观察者:事件接收接口
class Observer {
public:
virtual ~Observer() {}
virtual void Update(const string& event) = 0; // 事件更新
};
// 抽象主题:事件发布者
class Subject {
public:
virtual ~Subject() {}
// 注册观察者
virtual void Attach(Observer* observer) {
pthread_mutex_lock(&mutex_);
observers_.push_back(observer);
pthread_mutex_unlock(&mutex_);
}
// 移除观察者
virtual void Detach(Observer* observer) {
pthread_mutex_lock(&mutex_);
auto it = find(observers_.begin(), observers_.end(), observer);
if (it != observers_.end()) {
observers_.erase(it);
}
pthread_mutex_unlock(&mutex_);
}
// 通知所有观察者
virtual void Notify(const string& event) {
pthread_mutex_lock(&mutex_);
for (auto observer : observers_) {
observer->Update(event);
}
pthread_mutex_unlock(&mutex_);
}
private:
vector<Observer*> observers_; // 观察者列表
pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER; // 线程安全锁
};
// 具体主题:服务器连接管理器
class ConnectionManager : public Subject {
public:
// 模拟新连接事件
void OnNewConnection(const string& client_ip) {
string event = "New connection from " + client_ip;
Notify(event); // 通知所有观察者
}
// 模拟连接断开事件
void OnDisconnect(const string& client_ip) {
string event = "Disconnect from " + client_ip;
Notify(event);
}
};
// 具体观察者1:日志观察者
class LogObserver : public Observer {
public:
void Update(const string& event) override {
cout << "[Log Observer] " << event << endl;
}
};
// 具体观察者2:统计观察者
class StatObserver : public Observer {
public:
void Update(const string& event) override {
static int conn_count = 0;
if (event.find("New connection") != string::npos) {
conn_count++;
} else if (event.find("Disconnect") != string::npos) {
conn_count--;
}
cout << "[Stat Observer] Current connections: " << conn_count << endl;
}
};
// 测试:多线程模拟事件触发
void* SimulateEvents(void* arg) {
ConnectionManager* manager = (ConnectionManager*)arg;
// 模拟客户端连接/断开
manager->OnNewConnection("192.168.1.1");
sleep(1);
manager->OnNewConnection("192.168.1.2");
sleep(1);
manager->OnDisconnect("192.168.1.1");
return nullptr;
}
int main() {
ConnectionManager manager;
LogObserver log_observer;
StatObserver stat_observer;
// 注册观察者
manager.Attach(&log_observer);
manager.Attach(&stat_observer);
// 启动线程模拟事件
pthread_t tid;
pthread_create(&tid, nullptr, SimulateEvents, &manager);
pthread_join(tid, nullptr);
// 移除观察者
manager.Detach(&log_observer);
manager.Detach(&stat_observer);
return 0;
}
3. 注意事项
- 线程安全:观察者列表的增删改查需加互斥锁(如pthread_mutex_t),避免多线程并发问题。
- 避免循环依赖:观察者与主题尽量避免互相持有强引用,可使用弱指针(weak_ptr)。
- 异步通知:高并发场景下,可将通知逻辑放入线程池异步执行,避免阻塞主题线程。
2. 策略模式(Strategy)------ 动态切换算法
定义一系列算法,封装成独立类,可动态切换算法而不修改调用代码。适用于Linux中"同一任务多种实现"场景(如压缩算法、排序算法、加密算法切换)。
3. 模板方法模式(Template Method)------ 框架钩子设计
定义一个操作的骨架流程,将可变步骤延迟到子类实现。适用于Linux框架设计(如内核驱动框架、服务器请求处理框架),规范流程并保留扩展点。
五、设计模式组合应用(Linux服务器案例)
单一模式难以应对复杂场景,结合Linux高性能服务器设计,展示多模式组合用法,提供可落地的架构思路。
1. Linux高性能日志服务器
1. 架构设计(多模式组合)
- 单例模式:日志器全局唯一实例,避免重复创建资源。
- 工厂方法模式:日志输出器工厂(控制台/文件/网络输出),支持动态扩展。
- 装饰器模式:给日志添加时间戳、级别过滤、加密装饰。
- 观察者模式:日志事件通知(如异常日志触发告警)。
2. 核心代码框架
cpp
#include <iostream>
#include <string>
#include <memory> // 智能指针
using namespace std;
// 1. 日志输出器接口(工厂方法产品)
class ILogger {
public:
virtual ~ILogger() {}
virtual void Log(const string& msg) = 0;
};
// 具体日志输出器(文件/控制台)
class FileLogger : public ILogger {
public:
void Log(const string& msg) override {
cout << "[File Logger] " << msg << endl;
}
};
class ConsoleLogger : public ILogger {
public:
void Log(const string& msg) override {
cout << "[Console Logger] " << msg << endl;
}
};
// 日志输出器工厂
class LoggerFactory {
public:
static unique_ptr<ILogger> CreateLogger(const string& type) {
if (type == "file") {
return make_unique<FileLogger>();
} else if (type == "console") {
return make_unique<ConsoleLogger>();
}
return nullptr;
}
};
// 2. 装饰器基类
class LoggerDecorator : public ILogger {
public:
LoggerDecorator(unique_ptr<ILogger> logger) : logger_(move(logger)) {}
void Log(const string& msg) override = 0;
protected:
unique_ptr<ILogger> logger_;
};
// 时间戳装饰器
class TimeDecorator : public LoggerDecorator {
public:
TimeDecorator(unique_ptr<ILogger> logger) : LoggerDecorator(move(logger)) {}
void Log(const string& msg) override {
// 模拟获取时间戳
string timestamp = "[2024-05-01 12:00:00]";
logger_->Log(timestamp + " " + msg);
}
};
// 3. 单例日志管理器(组合工厂与装饰器)
class LogManager {
public:
static LogManager& GetInstance() {
static LogManager instance;
return instance;
}
void Init(const string& logger_type) {
// 工厂创建日志器,装饰器增强
auto logger = LoggerFactory::CreateLogger(logger_type);
if (logger) {
logger_ = make_unique<TimeDecorator>(move(logger));
}
}
void Log(const string& msg) {
if (logger_) {
logger_->Log(msg);
}
}
private:
LogManager() {}
~LogManager() {}
LogManager(const LogManager&) = delete;
LogManager& operator=(const LogManager&) = delete;
unique_ptr<ILogger> logger_;
};
// 测试
int main() {
// 初始化日志管理器(控制台输出+时间戳)
LogManager::GetInstance().Init("console");
LogManager::GetInstance().Log("Server started successfully");
LogManager::GetInstance().Log("Received client request");
return 0;
}
六、补充知识点
1. 单例模式的线程安全实现方案对比?Linux内核与用户态实现差异?
方案(静态局部变量/双重检查锁定/饿汉);线程安全原理(编译器屏障/原子操作/预初始化);内核与用户态差异(内核无进程退出析构时机,需手动销毁;用户态可依赖析构函数)。
2. 工厂方法与抽象工厂的区别?Linux场景下如何选择?
区别(工厂方法创建单一产品,抽象工厂创建成套产品);选型(单一产品扩展选工厂方法,如协议解析;成套组件创建选抽象工厂,如GUI主题组件)。
3. 观察者模式在多线程场景下的线程安全问题如何解决?
问题(观察者列表并发修改、通知逻辑阻塞);解决方案(互斥锁保护列表、异步通知(线程池)、弱指针避免循环依赖)。
4. 适配器模式与装饰器模式的核心差异?各自适用场景?
差异(适配器解决接口兼容,不改变原功能;装饰器增强原功能,不改变接口);场景(适配器用于接口转换,如系统调用封装;装饰器用于功能扩展,如日志增强)。
5. 设计模式过度使用的危害?Linux项目中如何把握度?
危害(代码复杂度上升、性能开销、可读性下降);把握原则(简单场景不用模式,如单一对象创建;复杂场景(可扩展、解耦)按需使用,优先选择轻量级模式)。
6. 单例模式在Linux服务器集群场景下的局限性?如何解决?
局限性(单例仅进程内唯一,集群多进程场景无法保证全局唯一);解决方案(结合分布式锁(如Redis)、集群配置中心,实现分布式全局唯一)。