策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
场景:加密数据时候,可以通过不同的算法来加密数据,但是呢,加密逻辑的相同的,我们把这加密过程用策略模式来实现,可以实现,选择不同的加密算法,或者自定义算法。
UML类图
加密接口如下:
class IEncrypt
{
public:
typedef unsigned char uint_8;
virtual void encrypt(const uint_8* src, size_t len, uint_8*& dst, size_t& dst_len, const uint_8* key, size_t key_len) = 0;
void getInfo(uint_8* ecry, size_t len)
{
printf("\n=================================\n");
printf("Encrypt result:");
for (int i = 0; i < len;i++)
{
printf("%c", ecry[i]);
}
printf("\n");
printf("=================================\n");
}
};
实现加密算法簇
//亦或加密
class XorEncrypt :public IEncrypt
{
public:
virtual void encrypt(const uint_8* src, size_t len, uint_8*& dst, size_t& dst_len, const uint_8* key, size_t key_len)
{
dst_len = len;
dst = new uint_8[len];
for (int i = 0; i < len;i++)
{
dst[i] = src[i] ^ key[i%key_len];
}
}
};
//改变值加密
class ChangeEncrypt :public IEncrypt
{
public:
virtual void encrypt(const uint_8* src, size_t len, uint_8*& dst, size_t& dst_len, const uint_8* key, size_t key_len)
{
dst_len = len;
dst = new uint_8[len];
int key_sum = 0;
for (int i = 0; i < key_len; i++)
key_sum += key[i];
key_sum /= key_len;
for (int i = 0; i < len;i++)
{
dst[i] = src[i] + key_sum;
}
}
};
加密策略选择
class Encrypt
{
public:
enum encry_type
{
Xor,
Change
};
Encrypt() :pres(nullptr), encry_algorithm(nullptr), res_len(0){}
~Encrypt()
{
if (encry_algorithm)
delete encry_algorithm;
if (pres)
delete pres;
}
void make(encry_type type, IEncrypt::uint_8* src, size_t len, IEncrypt::uint_8* key,size_t key_len)
{
switch (type)
{
case Encrypt::Xor:
encry_algorithm = new XorEncrypt;
break;
case Encrypt::Change:
encry_algorithm = new ChangeEncrypt;
break;
default:
encry_algorithm = nullptr;
break;
}
if (encry_algorithm)
{
encry_algorithm->encrypt(src, len, pres, res_len, key, key_len);
}
}
void makeself(IEncrypt* new_algorithm, IEncrypt::uint_8* src, size_t len, IEncrypt::uint_8* key, size_t key_len)
{
encry_algorithm = new_algorithm;
if (encry_algorithm)
{
encry_algorithm->encrypt(src, len, pres, res_len, key, key_len);
}
}
void show()
{
if (encry_algorithm)
{
encry_algorithm->getInfo(pres, res_len);
}
}
protected:
IEncrypt* encry_algorithm;
IEncrypt::uint_8 *pres;
size_t res_len;
};
测试
int main()
{
char srcStr[] = "hello,this is a case";
char key[] = "password";
Encrypt e;
e.make(Encrypt::Xor, (IEncrypt::uint_8*)srcStr, 20, (IEncrypt::uint_8*)key, 8);
e.show();
Encrypt ex;
ex.make(Encrypt::Change, (IEncrypt::uint_8*)srcStr, 20, (IEncrypt::uint_8*)key, 8);
ex.show();
getchar();
return 0;
}