想到一个极端的例子,主要是想说如何提取变化的东西和设计的取舍。
先看一个题目:考试分数为百分制,请将给定的分数进行分类,分类规则是
[0,60) 不及格
[60,70) 合格
[70,80) 良好
[80,90) 优秀
[90,100] 杰出
嗯,题目简单,做法也很简单,如下,简便起见,假设分数为整形:
char* get_result(int x)
{
if ( x < 60 ) return "..";
else if ( x < 70 ) return "...";
else if ( x < 80 ) return "....";
else if ( x < 90 ) return ".....";
else return "....."
}
以这个简单的例子,说明一下抽象的思想。一个规律,凡是用到了if else 的地方,就有抽象可以派上用场。我来过度设计一下,变成这样的:
struct score
{
virtual char* result()=0;
};
struct score_bad : public score
{
char* result(){ return "bad";}
};
struct score_yes : public score
{
char* result(){ return "yes";}
};
....
score* get_score(int x)
{
if( x< 60 ) return new score_bad;
else ( x< 70 ) return new score_yes;
...
}
char* get_result(int x)
{
score* s = get_score( x );
return s->result();
}
有的人说,有的时候,用if只是简单判断下参数是否正确而已,可以像上面进行抽象么?如:
int abc::get_xyz(int x)
{
if ( x < 0 ) return -1;
set(x);
draw(x);
y=x+1;
return 0;
}
当然可以过度设计一把。
struct doer
{
virtual int do()=0;
};
struct error : public doer
{
int x;
error(int _x) : x(_x){}
int do(){return -1;}
};
struct yes:public doer
{
int x;
abc* a;
yes(int _x,abc* _a):x(_x),a(_a){}
int do()
{
a->set(x);
a->draw(x);
a->y=x+1;
return 0;
}
};
int abc::get_xyz(int x)
{
doer* d = x < 0 ? new error(x) : new yes(x,this);
return d->do();
}
嗯,这里好像用上了一个简单工厂模式,根据输入的参数不同,返回不同的产品。这里都把产品抽象了一下。虽然过度设计的厉害,但是实际上思想都差不多的。