策略模式是设计模式中一个基本模式。关于该模式的定义和例子也很多,我结合我个人学习过程中遇到的一些问题,说一下我对该模式的看法。
策略模式的定义很简单,大体的意思是定义一组可以互换的算法。但是要用好该模式却并非易事,我觉得主要原因是在我们学习面向对象的基础知识时,许多教材告诉我们类里面应封装相应的属性(成员变量)和行为(成员函数)。问题恰恰出在这个行为上。因为许多的行为就是我们所说的“策略”。如果一组类继承了相同行为接口,那么这里很可能就可以提取一组策略。
知道了如何提取“策略”了,下面再深入一点,为什么要提取策略?这个问题笼统的回答一般是:为了程序的扩展和易维护。这样说可能好多人都理解不了。我觉得可以和继承(接口)对比来看可能会更清晰一些。
举个例子,我们写了如下一组类;C++代码如下:
class animal
{
public:
virtual void run() = 0;
};
class dog:public animal
{
public:
virtual void run(){//run with four feet};
}
class duck:public animal
{
public:
virtual void run(){//run with two feet};
}
class cat:public animal
{
public:
vietual void run(){//run with four feet};
}
聪明的你可能看出来了,cat和dog中run()的实现时一样,这样就导致了代码的重复,而重复的代码可是代码腐化的一个标志哟。所以要消除这些重复的代码。这个时候策略模式就闪亮登场了。
class crun
{
public:
virtual ~crun(){};
virtual void run() = 0;
}
class crunwithtwofeet:public crun
{
public:
virtual void run(){//run with two feet};
}
class crunwithfourfeet:public crun
{
public:
virtual void run(){//run with four feet};
}
class animal
{
public:
animal()
{
pRun = NULL;
}
virtual ~animal()
{
if(pRun)
{
delete pRun;
}
pRun=NULL;
};
virtual void run() = 0;
protect:
crun* pRun;
}
class dog:public animal
{
public:
dog()
{
pRun = new crunwithfourfeet();
}
virtual void run()
{//run with four feet
assert(pRun);
pRun->run();
};
}
class duck:public animal
{
public:
duck()
{
pRun = new crunwithtwofeet();
}
virtual void run()
{//run with two feet
assert(pRun);
pRun->run();
};
}
class cat:public animal
{
public:
cat()
{
pRun = new crunwithfourfeet();
}
vietual void run()
{//run with four feet
assert(pRun);
pRun->run();
};
}
通过策略模式,我们消除了重复代码,使代码更容易扩展和维护。 从其中我们可以总结出,首先,类不能无所顾忌的包含一些东西,哪怕那些东西就是它的行为。要合理的将一些行为和类剥离开来。这是好多面向对象的入门教材所没有提及的。
其次,也不能把所有的行为都剥离开来,就上面的例子而言,如果没有后来的cat类,我们完全没有必要去更改它,模式只在该使用它的时候使用。
限于我对面向对象思想的粗浅认识,其中不乏不当之处,权当抛砖引玉,欢迎指正。
策略模式的定义很简单,大体的意思是定义一组可以互换的算法。但是要用好该模式却并非易事,我觉得主要原因是在我们学习面向对象的基础知识时,许多教材告诉我们类里面应封装相应的属性(成员变量)和行为(成员函数)。问题恰恰出在这个行为上。因为许多的行为就是我们所说的“策略”。如果一组类继承了相同行为接口,那么这里很可能就可以提取一组策略。
知道了如何提取“策略”了,下面再深入一点,为什么要提取策略?这个问题笼统的回答一般是:为了程序的扩展和易维护。这样说可能好多人都理解不了。我觉得可以和继承(接口)对比来看可能会更清晰一些。
举个例子,我们写了如下一组类;C++代码如下:
class animal
{
public:
virtual void run() = 0;
};
class dog:public animal
{
public:
virtual void run(){//run with four feet};
}
class duck:public animal
{
public:
virtual void run(){//run with two feet};
}
class cat:public animal
{
public:
vietual void run(){//run with four feet};
}
聪明的你可能看出来了,cat和dog中run()的实现时一样,这样就导致了代码的重复,而重复的代码可是代码腐化的一个标志哟。所以要消除这些重复的代码。这个时候策略模式就闪亮登场了。
class crun
{
public:
virtual ~crun(){};
virtual void run() = 0;
}
class crunwithtwofeet:public crun
{
public:
virtual void run(){//run with two feet};
}
class crunwithfourfeet:public crun
{
public:
virtual void run(){//run with four feet};
}
class animal
{
public:
animal()
{
pRun = NULL;
}
virtual ~animal()
{
if(pRun)
{
delete pRun;
}
pRun=NULL;
};
virtual void run() = 0;
protect:
crun* pRun;
}
class dog:public animal
{
public:
dog()
{
pRun = new crunwithfourfeet();
}
virtual void run()
{//run with four feet
assert(pRun);
pRun->run();
};
}
class duck:public animal
{
public:
duck()
{
pRun = new crunwithtwofeet();
}
virtual void run()
{//run with two feet
assert(pRun);
pRun->run();
};
}
class cat:public animal
{
public:
cat()
{
pRun = new crunwithfourfeet();
}
vietual void run()
{//run with four feet
assert(pRun);
pRun->run();
};
}
通过策略模式,我们消除了重复代码,使代码更容易扩展和维护。 从其中我们可以总结出,首先,类不能无所顾忌的包含一些东西,哪怕那些东西就是它的行为。要合理的将一些行为和类剥离开来。这是好多面向对象的入门教材所没有提及的。
其次,也不能把所有的行为都剥离开来,就上面的例子而言,如果没有后来的cat类,我们完全没有必要去更改它,模式只在该使用它的时候使用。
限于我对面向对象思想的粗浅认识,其中不乏不当之处,权当抛砖引玉,欢迎指正。