C++设计模式---Strategy模式

时间:2022-04-21 18:20:56

一、前言

  学习的第一个设计模式!不知道理解的对不对,期望大家一起多交流~

  Strategy模式:策略模式,定义了算法族,分别封装起来,此模式可以让算法的变化独立于使用算法的客户。Strategy模式将逻辑算法封装到一个类中,通过组合的方式将具体的算法实现在组合对象中,再通过委托的方式将抽象的接口的实现委托给组合对象实现。其模型结构图如下:

C++设计模式---Strategy模式

 二、Strategy策略实例

  最近在写遥感影像融合相关算法,PCA、Brovey和SFIM算法,正好可以用于这次学习Strategy策略。

  关于这三个融合算法都属于替换类算法,大概思路就是用一个替换另外一个。然后获得高分辨的高频信息和地分辨的光谱信息。

  依据Strategy策略的思想,我们首先定义一个CContextFusion类,里面有一个DoFusionAction()方法,主要用于实现算法逻辑抽象接口,其头文件如下:

#pragma once
#include "StrategyFusion.h" class CStrategyFusion; class CContextFusion
{
public:
CContextFusion(CStrategyFusion *stg);
~CContextFusion(void); bool DoFusionAction(); private:
CStrategyFusion *m_stg;
};

  cpp文件如下:

#include "ContextFusion.h"

CContextFusion::CContextFusion( CStrategyFusion *stg )
{
m_stg = stg;
}
CContextFusion::~CContextFusion(void)
{
if(!m_stg)
delete m_stg;
} bool CContextFusion::DoFusionAction()
{
return m_stg->runFusion();
}

  

完成这个类后,我们首先定义一个融合算法超类CStrategyFusion,考虑到以上三种算法都要实现影像的重采样和增益系数的计算。为此,我们把这两个方法的实现放在超类中,对于其他与融合算法相关的方法,放到具体的算法类中。其类结构关系如下所示:

C++设计模式---Strategy模式

头文件分别如下:

#pragma once
#include <iostream>
#include <string>
#include <omp.h>
#include <gdal_alg_priv.h> class CStrategyFusion
{
public:
CStrategyFusion(void);
virtual ~CStrategyFusion(void);
virtual bool runFusion() = 0; protected:
int ReSampleMSSToPAN();
void getGAIN(); std::string m_panFileName;
std::string m_mssFileName;
std::string m_resampleFileName;
std::string m_FusionFileName;
GDALDataType m_dt;
int m_resampleModel; int m_gainX; // X方向增益像元个数
int m_gainY; // Y方向增益像元个数
int m_FusionWidth; // 融合后影像宽
int m_FusionHeight; // 融合后影像高
double m_FusionGeoTransform[6]; //private: };

  

#pragma once
#include "strategyfusion.h" class CStrategyFusionByPCA :
public CStrategyFusion
{
public:
CStrategyFusionByPCA(void);
~CStrategyFusionByPCA(void); bool runFusion(); private:
double *calMSSMean();
double *calCovMaxtrix(double *bandMean);
bool eejcb(double a[],int n,double v[],double eps,int jt);
void sortEigenVector( int iBandCount,double * eigenVector,double * covAfterEejcb);
void PCATransform(double *eigenVector);
double* cdf(int *h,int length);
void matchHistogram();
void inverseMatrix( double *matrix, int n );
void invertPCA(double * eigenVector); std::string m_PCAFileName;
std::string m_PanNewFileName;
};

  

#pragma once
#include "strategyfusion.h" class CStrategyFusionByBrovey :
public CStrategyFusion
{
public:
CStrategyFusionByBrovey(void);
~CStrategyFusionByBrovey(void); bool runFusion(); private:
bool CNByBrovery();
};

  

#pragma once
#include "strategyfusion.h" class CStrategyFusionBySFIM :
public CStrategyFusion
{
public:
CStrategyFusionBySFIM(void);
~CStrategyFusionBySFIM(void); bool runFusion(); private:
bool FilterMeanByPan();
bool SFIM();
};

  

总结:通过Strategy策略,我们可以*、方便的补充新的基于替换类的融合算法,甚至其他所有的融合算法,换句话说就是可以*定制自己的融合算法类,这种基于接口的实现不会因为继承而导致不可预计的危险。