二维码网站建设,弹出网站代码,网站性能需求,多合一建网站行为模式
观察者模式#xff0c;策略模式#xff0c;命令模式#xff0c;中介者模式#xff0c;备忘录模式#xff0c;模板方法模式#xff0c;迭代器模式#xff0c;状态模式#xff0c;责任链模式#xff0c;解释器模式#xff0c;访问者模式
保存/封装 行为/请求…行为模式
观察者模式策略模式命令模式中介者模式备忘录模式模板方法模式迭代器模式状态模式责任链模式解释器模式访问者模式
保存/封装 行为/请求Strategy 模式抽象出同一的接口执行不同的算法Command 模式封装一个请求从而决定何时、怎样满足请求Visitor 模式某些可作用于一个组对象上的操作但不修改这些对象的类x对多的依赖关系Observer 模式一对多对多个对象依赖于另外一个对象而这些对象又如何保持一致Mediator 模式多对多对象间怎样交互、和谁交互组件协作Template 模式对算法中的某些步骤状态变化State 模式对象的状态Memento 模式对一个对象中哪些私有信息存放在该对象之外以及在对什么时候进行存储数据结构Chain of Responsibility 模式满足一个请求的对象链Iterator 模式如何遍历、访问一个聚合的各元素领域问题Interpreter 模式对一个语言的文法及解释
保存/封装 行为/请求
Strategy
结构化设计 分而治之
ifelse switch case中 if else绝对不变可以用面相对象 抽象来解决。
code
#include cstdio
#include cstdlibclass Strategy {
public:virtual ~Strategy() default;virtual void excute() 0;
};class Strategy_allin : public Strategy {
public:void excute() {printf(塔塔开!\n);}
};class Strategy_giveup : public Strategy {
public:void excute() {printf(点了点了点了.\n);}
};class ChasingGame {
public:void play() {if (this-mStrategy) {mStrategy-excute();} else {printf(挂机等着输.\n);}}void set_strategy(Strategy* strategy) {if (this-mStrategy) {delete this-mStrategy;}this-mStrategy strategy;}Strategy* mStrategy nullptr;
};int main() {ChasingGame* mGame new ChasingGame;mGame-play();Strategy* mStrategy new Strategy_allin;mGame-set_strategy(mStrategy);mGame-play();mStrategy new Strategy_giveup;mGame-set_strategy(mStrategy);mGame-play();return 1;
}
command (保存)
将 请求/行为 封装成对象。
基类 Command 虚方法 excute子类继承后实现excute方法。到此为止的话 和策略模式特别类似但区别是 存在一个容器(复合命令对象)存放cmd对象执行其中所有的命令。 策略模式往往需要工厂模式创建一个对象 执行该对象的方法。 cmd模式一般自行创建cmd对象将请求放入队列中。怎么执行这个请求是队列决定的
函数对象和cmd模式存在相似。 函数对象 执行函数对象是通过重载()操作符 函数对象以函数签名来定义行为接口规范 编译时绑定(泛型编程 使用模板编译时解析类型) 更灵活性能更高。 cmd模式 以面相对象的 “接口 实现”来定义行为接口规范更严格有性能损失运行时绑定 编译时绑定
#include cstdio
#include cstdlib
#include vectorclass Command {
public:virtual ~Command() default;virtual void excute() 0;
};class Command_EatApple : public Command {
public:void excute() {printf(eat an Apple\n);}
};class Command_DrinkTea : public Command {
public:void excute() {printf(drink a cup of tea\n);}
};class CmdQueue {
public:void enqueueCmd(Command* cmd) {this-cmds.push_back(cmd);}void handleCmd() {for (auto cmd : this-cmds) {cmd-excute();}cmds.clear();}std::vectorCommand* cmds;
};int main() {CmdQueue* mQueue new CmdQueue;Command_DrinkTea* cmd1 new Command_DrinkTea;Command_EatApple* cmd2 new Command_EatApple;mQueue-enqueueCmd(cmd1);mQueue-enqueueCmd(cmd2);printf(容器决定什么时候执行cmd);mQueue-handleCmd();delete cmd1;delete cmd2;delete mQueue;return 0;
}
visitor (升维)
概念
对 Strategy模式 的维度提升——
原先Strategy
实现处 基类定义 子类实现一个方法 excute。使用处 调用。
后来Command更进一步
将 Strategy 视为一个可移动的对象使用处决定 执行/不执行 什么时候执行 其中的 excute 方法。
**现在visitor **作用与对象结构的二次辨析dispatch
实现处同时实现多个不同的动作不同的使用处选择执行其中一个动作
体现在使用上 实现处 visitor 类 基类要求各个方法的接口足够稳定 定义若干虚函数 actionA, actionB ... 子类 实现虚函数 actionA, actionB ... 使用处 element类层次结构稳定其中面临的操作面临频繁的变化。 基类 element以下接口稳定 虚函数action不同的子类对其进行实现 否则一旦基类element添加新的虚函数就需要修改所有子类。 方法accept(visitor) 接收保存一个 visitor 对象不用保存若干不同的 Strategy/Command 对象—— all in one 子类要求数量稳定 实现接口 action实现的方法是调用 所保存的 visitor 对象的不同 actionX。例如 elementA 的方法action执行visitor.actionAelementB 的方法action执行visitor.actionB
code
// 作用与对象结构的二次辨析
#include cstdioclass Visitor {
public:virtual ~Visitor() default;virtual void action_lunch() 0;virtual void action_dinner() 0;
};class Visitor_Shanghai : public Visitor {
public:virtual void action_lunch() {printf(山西午餐吃炸酱面\n);}virtual void action_dinner() {printf(山西晚餐吃刀削面\n);}
};class Visitor_ShanXi : public Visitor {
public:virtual void action_lunch() {printf(上海午餐吃酱鸭子\n);}virtual void action_dinner() {printf(上海晚餐吃剩下的酱鸭子\n);}
};class Element {
public:virtual ~Element() default;virtual void eat_meal() 0;virtual void accept(Visitor* visitor) {mVisitor visitor;}Visitor* mVisitor;
};class Element_Lunch : public Element {
public:virtual void eat_meal() {if (mVisitor) {mVisitor-action_lunch();}}
};class Element_dinner : public Element {
public:virtual void eat_meal() {if (mVisitor) {mVisitor-action_dinner();}}
};int main() {Visitor* mShanxi new Visitor_ShanXi;Visitor* mShanghai new Visitor_Shanghai;Element* meal new Element_Lunch;meal-accept(mShanghai);meal-eat_meal();delete meal;meal new Element_dinner;meal-accept(mShanxi);meal-eat_meal();delete meal;delete mShanghai;delete mShanxi;return 1;
}x对多的依赖关系
Observer 观察者模式(单向)
Observer 模式要解决的问题为
指多个对象间存在一对多的依赖关系当一个对象的状态发生改变 “一”变化的时候所有依赖于这个“一”的多对象都得到通知并被自动更新。
Subject 提供 依赖于它的观察者 Observer 的 注册registerObserver注销remove操作 使依赖于它的所有观察者同步的操作notifyObserver
观察者 Observer 提供
Update 操作注意这里的 Observer 的 Update 操作并不在 Observer 改变了 Subject 目标状态的时候就对自己进行更新这个更新操作要延迟到 Subject 对象发出 Notify 通知所有Observer 进行修改调用 Update。
#include cstdio
#include iostream
#include string
#include listclass Observer;
class Subscriber;class Subject {
public:virtual ~Subject() default;virtual void registObserver(Observer*) 0;virtual void removeObserver(Observer*) 0;virtual void notifyObserver() 0;std::listObserver* mObservers;
};class Subscriber {
public:Subscriber(std::string name) : name(name){};std::string name;void watchVideo() {printf(%s start watching . \n, this-name.c_str());}
};class Observer {
public:void addSubscriber(Subscriber*);void removeSubscriber(Subscriber*);void notifySubscriber();std::listSubscriber* mSubcribers;
};class Subject_Bilibili : public Subject {
public:virtual void registObserver(Observer* observer) {this-mObservers.push_back(observer);};virtual void removeObserver(Observer* observer) {this-mObservers.remove(observer);};virtual void notifyObserver() {printf(bilibili update! \n);for (auto observer : this-mObservers) {observer-notifySubscriber();}}
};void Observer::addSubscriber(Subscriber* subscriber) {this-mSubcribers.push_back(subscriber);
}
void Observer::removeSubscriber(Subscriber* subscriber) {this-mSubcribers.remove(subscriber);
}
void Observer::notifySubscriber() {printf(好的这就通知\n);for (auto subscriber : this-mSubcribers) {subscriber-watchVideo();}
}int main() {Subject* biblibili new Subject_Bilibili;Observer* mObserver new Observer;Subscriber* A new Subscriber(张三);Subscriber* B new Subscriber(李四);Subscriber* C new Subscriber(王五);biblibili-registObserver(mObserver);mObserver-addSubscriber(A);mObserver-addSubscriber(B);mObserver-addSubscriber(C);mObserver-removeSubscriber(C);biblibili-notifyObserver();return 1;
}Mediator 中介模式(双向/多向)
Mediator 解耦系统内多个类之间需要大量密集复杂的相互交互对他们进行集中管理。
依赖倒置原则 在多对象模型中的体现类似交换机要求 通信规范实现 让这些类继承相同的接口/成为某一基类的子类子类都持有中介的指针中介持有所有子类的指针
基类成员 基类::成员名与子类成员进行区分。
#include cstdio
#include iostream
#include string
#include listclass Mediator;class Client {
public:virtual ~Client() default;void registMediator(Mediator* mediator);void callSomeTeam(int type);virtual void responce() 0;Mediator* mMediator;int type;std::string name;
};class Client_Boss : public Client {
public:virtual ~Client_Boss() default;Client_Boss(std::string name, Mediator* mediator) {Client::name name;Client::type 99;registMediator(mediator);}virtual void responce() {printf(Boss %s here! what do u want?\n, name.c_str());}
};class Client_Engineer : public Client {
public:virtual ~Client_Engineer() default;Client_Engineer(std::string name, Mediator* mediator) {Client::name name;Client::type 1;registMediator(mediator);}virtual void responce() {printf(Engineer %s here! how can i help u?\n, name.c_str());}
};class Mediator {
public:void registClient(Client* client) {this-mClient.push_back(client);}void removeClient(Client* client) {this-mClient.remove(client);}void callClient(int type) {printf(callClient type %d \n, type);for (auto client : this-mClient) {if (client-type type) {client-responce();}}}std::listClient* mClient;
};void Client::callSomeTeam(int type) {if (this-mMediator)this-mMediator-callClient(type);elseprintf(unset Mediator\n);
}void Client::registMediator(Mediator* mediator){this-mMediator mediator;mediator-registClient(this);
}int main() {Mediator* mMediator new Mediator;Client_Boss* mBoss new Client_Boss(fajie, mMediator);Client_Engineer* mEngineer1 new Client_Engineer(pengyi 1, mMediator);Client_Engineer* mEngineer2 new Client_Engineer(pengyi 2, mMediator);mBoss-callSomeTeam(1);printf(10mins after\n);mEngineer1-callSomeTeam(99);return 1;
}组件协作
Template 模板模式
对于某一个业务逻辑算法实现在不同的对象中有不同的细节实现但是逻辑算法的框架或通用的应用算法是相同的。
Template 模式采用继承的方式实现这一点 抽象基类 定义细节的接口定义逻辑算法框架 子类 实现逻辑细节。 在子类实现详细的处理算法时并不会改变算法中的执行次序。
#include iostream
using namespace std;//做饮料模板
class TemplateDrink {
public:virtual ~TemplateDrink() default;//煮水virtual void BoildWater() 0;//冲泡virtual void Brew() 0;//倒入杯中virtual void PourInCup() 0;//加辅助材料virtual void AddSomething() 0;//模板方法void Make() {BoildWater();Brew();PourInCup();AddSomething();}
};class Coffee : public TemplateDrink {virtual void BoildWater() {cout 煮纯净水 endl;}virtual void Brew() {cout 冲泡咖啡 endl;}virtual void PourInCup() {cout 咖啡倒入杯中 endl;}virtual void AddSomething() {cout 加牛奶 endl;}
};class Tea :public TemplateDrink {virtual void BoildWater() {cout 煮山泉水 endl;}virtual void Brew() {cout 冲泡铁观音 endl;}virtual void PourInCup() {cout 茶水倒入杯中 endl;}virtual void AddSomething() {}
};int main()
{Tea* tea new Tea;tea-Make();Coffee* coffee new Coffee;coffee-Make();delete tea;delete coffee;
}状态变化
State 状态模式
主要解决Switch/Case 的爆炸
Switch/Case 的缺点 当状态数目很多的时候维护一大组的Switch/Case 语句将是一件异常困难并且容易出错的事情。 状态逻辑和动作实现没有分离。 动作的实现代码直接写在状态的逻辑当中。 后果是系统的扩展性和维护得不到保证。
概念
和策略模式类似
每个人、事物在不同的状态下会有不同表现动作而一个状态又会在不同的表现下转移到下一个不同的状态State。
状态机
不同状态的operation高度相似相对固定。operation依据某个变量state发生变化。
优点
State类枚举可能的状态 可以方便地增加新的状态只需要改变对象状态即可改变对象的行为。 封装了转换规则。在枚举状态之前需要确定状态种类。
Process将所有与某个状态有关的行为放到一个类中
允许状态转换逻辑与状态对象合成一体而不是某一个巨大的条件语句块。
系统资源
通常与单例模式一起使用可以让多个环境对象共享一个状态对象从而减少系统中对象的个数。
实现上
State State基类 除虚析构外还持有 一系列operation虚函数看情况 process指针使用该指针更改process中的下一个statestate指针(指向下一个状态)(上下文指针) State子类继承State基类 重写operarion函数。
Process Process 基类 持有State指针一系列operation虚函数。 Process 子类 重写operation 调用State指针的operation 让State更新为下一个状态 state state-next。
code
// main.cpp#include cstdio
#include cstdlib
#include processImpl.cpp
#include stateImpl.cppint main() {Process* mProcess new Process(10);mProcess-buy(101);mProcess-buy(1);mProcess-recharge(10);mProcess-buy(1);mProcess-recharge(1000);mProcess-buy(100);delete mProcess;return 1;
}// process.h#include cstdio
#include cstdlib
#include state.h
#pragma onceclass Process {
public:Process(int 10);void set_state(State* state);void recharge(int money);void buy(int price);int query_money();int balance;State* mState nullptr;
};
// processImpl.cpp#include process.h
#include state.h
#include cstdio
#pragma onceProcess::Process(int init_money) {this-balance init_money;if (init_money 0) {this-set_state(new State_rich);} else {this-set_state(new State_poor);}
}int Process::query_money() {return this-balance;
}void Process::set_state(State* state) {if (mState)delete this-mState;this-mState state;this-mState-set_process(this);
}void Process::recharge(int money) {bool result this-mState-recharge(money);this-balance money;if (result) {printf(尊贵的用户: 充值后余额 %d\n, this-query_money());} else {printf(欠费的用户: 充值后余额 %d\n, this-query_money());}
}void Process::buy(int price) {if (this-mState-buy(price))printf(购买成功 余额 %d\n, this-query_money());elseprintf(购买失败 请充值 余额 %d\n, this-query_money());
}// state.h
#include cstdio
#include cstdlib
#pragma once
class Process;class State {
public:virtual ~State() default;void set_process(Process* process) {this-process process;}Process* get_process() {return this-process;}virtual bool buy(int) 0; virtual bool recharge(int) 0; Process* process;
};class State_rich : public State {
public:bool buy(int) override;bool recharge(int) override;
};class State_poor : public State {
public:bool buy(int) override;bool recharge(int) override;
};// stateImpl.cpp#include cstdio
#include cstdlib
#include state.h
#include process.h
#pragma oncebool State_rich::buy(int price) {this-process-balance - price;int balance this-process-query_money();if (balance 0) {this-process-set_state(new State_poor);}return true;
}bool State_rich::recharge(int money) {int balance this-process-query_money();if (money balance 0) {return true;}return false;
}bool State_poor::buy(int price) {// int balance this-process-query_money();return false;
}bool State_poor::recharge(int money) {int balance this-process-query_money();if (money balance 0) {this-process-set_state(new State_rich);return true;}return false;
}Memento (过时)
Memento 备忘录模式
信息隐藏条件下对对象的快照。
原发器持有state保存快照时 根据state创建并返回一个memnto对象。恢复时传入memnto对象设置 原发器的state对象。 实现对原发器对外的信息隐藏。
现在来看太低级了 java c#等具有高效成熟容易正确实现的对象序列化支持有更容易正确实现的序列化方案。
不怎么介绍也没关系
迭代器
从性能角度讲——编译期多态好过运行时多态 泛型编程的迭代器 面相对象的迭代器 虚函数成本过高
但在 java c# php等等语言不支持编译时多态仍然在使用运行时多态
责任链模式
运行时的类型判断。一个请求者可能有多个接受者但最后真正的接受者或者说处理者只有一个。运行时动态添加 修改请求的处理职责。
避免请求的发送者和接受者之间的耦合关系。
数据结构构成的处理模型。链表
行为变化将组件的行为与组件本身进行解耦
非虚函数静态函数 地址在编译时绑定的方式。
虚函数是运行时使用虚函数表指针绑定的。
Interpreter 模式
对一个语言的文法及解释