内容总结自李建忠老师C++设计模式
1.分类
1.组件协作
- Template Method
- Strategy
- Observer/Event
2.单一职责
- Decorator
- Bridge
3.对象创建
- Factory Method
- Abstract Factory
- Prototype
- Builder
4.对象性能
- Singleton
- Flyweight
5.接口隔离
- Facade
- Proxy
- Mediator
- Adapter
6.状态变化
- Memento
- State
7.数据结构
- Composite
- Iterator
- Chain of Resposibility
8.行为变化
- Command
- Visitor
2.重构关键技法
- 静态 -> 动态
- 早绑定 -> 晚绑定
- 继承 -> 组合
- 编译时依赖 -> 运行时依赖
- 紧耦合 -> 松耦合
3.组件协作
现代软件专业分工之后的第一个结果就是 “框架和应用程序的划分”,"组件协作"模式通过晚期绑定,来实现框架和应用程序之间的松耦合,是二者之间协作时常用的模式
1.Template Method
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
//面向结构
//程序库
class Library{
public :
void Step1(){
}
void Step3(){
}
void Step5(){
}
}
//应用开发
class Application{
public:
bool Step2(){
}
void Step4(){
}
}
int main(){
Library lib();
Application app();
lib.Step1();
if(app.Step2){
lib.Step3();
}
for(int i=0;i<4;i++){
app.Step4();
}
}
//面象对象
class Library{
public:
//稳定的template method
void Run(){
Step1();
if(Step2()){ //支持变化 ==>虚函数的多态调用
Step3();
}
for(int i=0; i<4;i++){
Step4(); //支持变化 ==>虚函数的多态调用
}
Step5();
}
virtual ~Library(){};
protected :
void Step1(){ //稳定
}
void Step3(){ //稳定
}
void Step5(){ //稳定
}
virtual bool Step2()=0; //变化
virtual void Step4()=0; //变化
}
class Application:public Library{
protected:
virtual bool Step2(){
//子类重写实现
}
virtual void Step4(){
//子类重写实现
}
}
int main(){
Library* plib=new Application();
lib.Run();
delete plib;
}
2. Strategy 策略模式
在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用的算法也是一个性能负担。
如何在运行时根据需要透明的更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
//strategy
//old
enum TaxBase{
CN_Tax,
US_Tax,
DE_Tax,
FR_Tax //变化
}
class SalesOrder{
TaxBase tax;
public:
double CalculateTax(){
if(tax == CN_Tax){
}else if(tax == US_Tax){
}else if(tax == DE_Tax){
}else if(tax == FR_Tax){ //变化
}
}
}
//Strategy
class TaxStrategy{
public:
virtual double Calculate(const Context& context)=0;
virtual ~TaxStrategy(){}
}
class CNTax:public TaxStrategy{
public:
virtual double Calculate(const Context& context){
}
}
class USTax:public TaxStrategy{
public:
virtual double Calculate(const Context& context){
}
}
class DETax:public TaxStrategy{
public:
virtual double Calculate(const Context& context){
}
}
class SalesOrder{
private:
TaxStrategy* strategy; //指针,基类抽象,不能用TaxStrategy strategy;对象,没有多态性
public:
SalesOrder(StrategyFactory* strategyFactory){
this->strategy=strategyFactory->NewStrategy();
}
~SalesOrder(){
delete this->strategy;
}
public double CalculateTax(){
Context context();
double val=strategy->Calculate(context); //多态调用
}
}
3. Observer 观察者模式
在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系"----一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好的抵御变化。
使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
//observe
class MainForm: public Form{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_click(){
string filePath=txtFilePath->getText();
int number=atoi(txtFileNumber->getText().c_str());
FileSplitter splitter(filePath, number, progressBar);
splitter.split();
}
}
class FileSplitter{
string m_filePath;
int m_fileNumber;
ProgressBar* m_progressBar;
public:
FileSplitter(const string& filePath, int fileNumber,ProgressBar* progressBar):m_filePath(filePath),m_fileNumber(fileNumber),m_progressBar(progressBar){
}
void split(){
//...
for(int i=0; i< m_fileNumber; i++){
if(m_progressBar!=nullptr){
m_progressBar->setValue((i+1)/m_fileNumber); //更新
}
}
}
}
//--------------
//observe
class MainForm: public Form, public IProgress{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_click(){
string filePath=txtFilePath->getText();
int number=atoi(txtFileNumber->getText().c_str());
ConsoleNotifier cn;
FileSplitter splitter(filePath, number);
splitter.addIProgress(this);
splitter.addIProgress(&cn);
splitter.split();
splitter.removeIProgress(this);
}
}
class ConsoleNotifier : public IProgress {
public:
virtual void DoProgress(float value){
cout << ".";
}
};
class IProgress{
public:
virtual void DoProgress(float value)=0;
virtual ~IProgress(){}
}
class FileSplitter{
string m_filePath;
int m_fileNumber;
//ProgressBar* m_progressBar; //具体通知控件
List<IProgress*> m_iprogressList; //抽象通知机制,支持多个观察者
public:
FileSplitter(const string& filePath, int fileNumber):m_filePath(filePath),m_fileNumber(fileNumber){
}
void split(){
//...
for(int i=0; i< m_fileNumber; i++){
if(m_progressBar!=nullptr){
float progressValue = m_fileNumber;
progressValue = (i + 1) / progressValue;
onProgress(progressValue); //更新
}
}
}
void addIProgress(IProgress* iprogress){
m_iprogressList.add(iproress);
}
void removeIProgress(IProgress* iprogress){
m_iprogressList.remove(iprogress);
}
protected:
virtual void onProgress(float value){
List<IProgress*>::iterator itor=m_iprogressList.begin();
while(itor != m_iprogressList.end()){
(*itor)->DoProgress(value); //更新进度条
itor++;
}
}