设计模式——策略模式

1、策略模式
定义:
定义了算法族,分别封装起来,让他们之间互相替换,此模式让算法的变化独立于使用算法的客户
设计原则:
1、找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起
2、针对接口编程,而不是针对实现编程
3、多用组合,少用继承
适用性:
1、许多相关的类仅仅是行为有异,策略模式提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态的在几种算法中选择一种
2、需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法,当这些变体实现为一个算法的类层次时,可以使用策略模式
3、算法使用客户不应知道的数据,可以使用策略模式避免暴露复杂的,与算法相关的数据结构
4、一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入他们格式的类中代替这些条件语句
实现:
1、定义所有支持算法的公共接口
2、继承接口类,实现具体的算法
3、维护一个对公共接口对象的引用,用该引用来调用具体的算法
任务:
使用策略模式制做一个类其可以把文本文件进行左对齐,右对齐和中对齐。

/*****************************************
使用策略模式制做一个类其可以把文本文件进行左对齐,右对齐和中对齐。
********************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>


using namespace std;


int CountMaxLine(const char *fileName) //统计最大行数
{
char buf[1024] = {0};
int nMax = 0;
int nLen = 0;
fstream file;

file.open(fileName,ios::in|ios::out);
if(!file.is_open())
{
return -1;
}

while(file.getline(buf,1023))
{
nLen = strlen(buf);
memset(buf,0,1024);
if(nLen > nMax)
{
nMax = nLen;
}
}
file.close();

printf("max %d\n",nMax);
return nMax;
}


char* EraseLeftSpace(char *line) //擦除字符串左边的空白字符
{
int nLen = 0;
int  i = 0;

if(NULL == line)
{
return NULL;
}

nLen = strlen(line);
for(; i<nLen; ++i)
{
if(!isspace(line[i]))
{
break;
}
}
line = &line[i];

return line;
}


char* EraseRightSpace(char *line) //擦除字符串右边的空白字符
{
int nLen = 0;
int  i = 0;

if(NULL == line)
{
return NULL;
}

nLen = strlen(line);
for(i=nLen-1; i>=0; --i)
{
if(!isspace(line[i]))
{
break;
}
}
line[i+1] = 0;

return line;
}

//接口类。设计文本对齐方法
class AlignInterface
{
public:
AlignInterface(){}
virtual ~AlignInterface(){}

virtual int Align(const char *fileName) = 0;
};




//左对齐
class AlignLeft:public AlignInterface
{
public:
AlignLeft()
{
printf("left align\n");
}
virtual ~AlignLeft(){};

int Align(const char *fileName)
{
char buf[1024] = {0};
char *pTemp = NULL;
fstream file;

file.open(fileName,ios::in|ios::out);
if(!file.is_open())
{
return -1;
}

while(file.getline(buf,1024))
{
pTemp = EraseLeftSpace(buf);

printf("%s\n",pTemp);
//file<<pTemp;
memset(buf,0,1024);
}

file.close();
return 0;
}
};


//右对齐
class AlignRight:public AlignInterface
{
public:
AlignRight()
{
printf("right align\n");
}
virtual ~AlignRight(){};

int Align(const char *fileName)
{
char buf[1024] = {0};
int nLen = 0;
char *pTemp = NULL;
int nMax = 0;
fstream file;

nMax = CountMaxLine(fileName);
file.open(fileName,ios::in|ios::out);
if(!file.is_open())
{
return -1;
}

while(file.getline(buf,1024))
{
char bufTemp[1024] = {0};

pTemp = EraseRightSpace(buf);
nLen = strlen(pTemp);
if(nLen < nMax)
{
memset(bufTemp,' ',nMax-nLen);
strcat(bufTemp,buf);
}
else
{
memcpy(bufTemp,buf,strlen(buf));
}

printf("%s\n",bufTemp);
//file<<bufTemp;
memset(buf,0,1024);
}

file.close();
return 0;
}
};




//居中对齐
class AlignMid:public AlignInterface
{
public:
AlignMid()
{
printf("middle align\n");
}
virtual ~AlignMid(){};

int Align(const char *fileName)
{
char buf[1024] = {0};
int nLen = 0;
char *pTemp = NULL;
int nMax = 0;
fstream file;

nMax = CountMaxLine(fileName);
file.open(fileName,ios::in|ios::out);
if(!file.is_open())
{
return -1;
}

while(file.getline(buf,1023))
{
char bufTemp[1024] = {0};

//file.seekp(-strlen(buf),ios::cur);
pTemp = EraseLeftSpace(buf);
pTemp = EraseRightSpace(pTemp);
nLen = strlen(pTemp);
if(nLen < nMax)
{
memset(bufTemp,' ',(nMax-nLen)/2);
strcat(bufTemp,buf);
}
else
{
memcpy(bufTemp,buf,strlen(buf));
}

printf("%s\n",bufTemp);
//file<<bufTemp;
memset(buf,0,1024);
}

file.close();
return 0;
}
};


//实现对接口的引用
class TextAlign
{
private:
AlignInterface *m_align;
char m_fileName[254];

public:
TextAlign(char *fileName)
{
m_align = new AlignLeft();//默认为左对齐
memcpy(m_fileName,fileName,strlen(fileName));
}
virtual ~TextAlign()
{
if(NULL != m_align)
{
delete m_align;
m_align = NULL;
}
}


int SetAlign(AlignInterface *align) //设置对齐方式
{
m_align = align;
align->Align(m_fileName);
}
};




int main()
{
TextAlign text("./test.txt");
text.SetAlign(new AlignMid());


return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值