1 命令模式
对每个执行请求进行封装。
interface Command {
void execute();
};
class OpenCommand : Command {
void execute() {
// open file
}
}
class CloseCommand : Command {
void execute() {
// close file
}
}
// 菜单项实体与执行过程的解耦
class MenuItem {
string m_caption;
Command m_command;
void on_clicked() {
m_command.execute();
}
};
// 复合命令
class CompositeCommand : Command {
OpenCommand m_openCmd;
CloseCommand m_closeCmd;
void execute() {
m_openCmd.execute();
// write file ...
m_closeCmd.execute();
}
}
2 迭代器模式
顺序访问容器对象中的各个元素,同时不暴露容器的内部实现。
std::list<int> lst;
std::list<int>::iterator iter = lst.begin();
while( iter != lst.end() ) {
printf("%d\n", *iter);
++iter;
}
3 中介者模式
用一个中介对象,封装其他一系列对象的交互操作,减少这些其他对象间操作的耦合依赖。示例:
1. 按钮点击后,在文本框中显示消息。
2. 按钮与文本框没有直接耦合依赖,按钮通过中介窗口传递消息。
// 中介接口
interface Mediator {
void button_clicked();
}
class Button {
Mediator m_mediator;
// 按钮的点击事件,通知中介者进行处理
void on_click() {
m_mediator.button_clicked();
}
}
class TextBox {
void setText(string text) { ... }
}
class Window : Mediator {
Button m_button;
TextBox m_textbox;
void init() {
m_button.m_mediator = this;
}
// 按钮通过窗口将事件消息传递给
void button_clicked() {
m_textbox.setText("button clicked");
}
}
4 观察者模式
对象间的一对多依赖关系,一个对象状态发生改变,其他依赖其的对象会立即得到通知。
另称为订阅-发布模式。
class Observer {
void update(int state);
}
class Subject {
vector<Observer> m_obsList;
int m_state;
void addObserver(Observer obs) {
m_obsList.add(obs);
}
void changeState(int state) {
m_state = state;
for(i = 0; i < m_obsList.size(); ++i) {
m_obsList[i].update(state);
}
}
}
5 模板方法模式
定义一个固定的算法或执行过程骨架,执行或算法的详细过程在子类中实现。class Storage {
public:
// 对外公共接口,实现用于向目标存储单元写入数据的骨架过程
void saveData(char[] data) {
this.open();
this.write(data);
this.close();
}
protected:
// 由具体的存储单位实现
void open() {}
void write(char[] data) {}
void close() {}
}
// 文件存储单元
class FileStorage : Storage {
void open() {
// open file ...
}
void write(char[] data) {
// write data to file
}
void close() {
// close file
}
}
// 数据库存储单元
class DBStorage : Storage {
void open() {
// open db connection ...
}
void write(char[] data) {
// insert data to db table
}
void close() {
// close db connection
}
};