思考一个系统,在系统不断构建的过程中,系统需要支持多个不同版本的代码
这时,设计模式的工厂模式不禁就蹦出在脑海中,来解决不同版本的代码。
然而在追求极致性能的当下,是否这就是最终的答案?
工厂方法解决多版本
请看下面原始代码
class Draw {
int do();
}
class Speak {
int do();
}
.....
系统刚建立之初,系统有Draw类和Speak类,他们的行为穿插在千万行代码的系统中,千丝万缕
此时,业务发展壮大
原始的Draw和Speak已经不能支持更复杂的业务,这就迫使Draw发展出来Draw_version_1和Draw_version_2
Speak也出现了类似的发展
此时代码变成
class Draw_v1 {
int do();
}
class Draw_v2 {
int do();
}
class Speak_v1 {
int do();
}
class Speak_v2 {
int do();
}
class Speak_v3 {
int do();
}
非常不幸运,Draw::do()和Speak::do()在系统的调用位置非常多,多得无法逐个写if else来适配不同版本得Draw和Speak
此时,历史中中的四人帮出现在梦中,悄悄的留下工厂方法四个大字
一觉醒来
开始大刀阔斧的重构代码
class DrawInterface {
virtual int do();
}
class Draw_v1: DrawInterface {
virtual int do();
}
class Draw_v2: DrawInterface {
virtual int do();
}
class SpeakInterface {
virtual int do();
}
class Speak_v1: SpeakInterface {
virtual int do();
}
class Speak_v2: SpeakInterface {
virtual int do();
}
轰轰烈烈的写完后,仿佛完成了一件举世闻名的艺术品
沾沾自喜
随着业务的扩展,Draw更是发展出了更多的版本
此时改代码变得异常轻松
内心更加是自信的体无完肤
然而,一纸性能指标把人从天堂拉下了地狱
突然发现在Draw::do的调用发生了严重的性能问题,这个子类的函数比原生的方法性能差了好几倍
百思不得其解,甚至萌生出推翻所有,梦里惊醒,吓出一身冷汗
然而人总是坚强,不断的翻阅资料
功夫不负有心人,突然看到了一个子inline
是的,inline,一个编译优化的选项
然而virtual方法不能inline
class Speak {
virtual int do();
}
class Speak {
int do();
}
Speak::do是virtual函数,调用次数少当然没问题
但是这个系统,调用Speak::do千万次,这就导致一个小小的缺陷导致性能无法上升
模板化
动态多态并不是不能用,而是少用
动态多态对整个系统扩展,是非常好的设计
然而对于高频的调用,动态多态就不能拥有
class Draw_v1 {
int do(); // high frequce call
}
class Draw_v2 {
int do(); // high frequce call
}
class Speak_v1 {
int do(); // high frequce call
}
class Speak_v2 {
int do(); // high frequce call
}
class Speak_v3 {
int do(); // high frequce call
}
一般来说,对于某个业务,他用到的子类版本是固定,所以可以构造一下模板类
class BigBusinessInterface {
virtual doBig() = 0; //call draw/speak high frequce inside
}
Template<Draw_T,Speak_t>
class BigBusiness {
Draw_T draw_ins;
Speak_T speak_ins;
virtual doBig(); //call draw/speak high frequce inside
}
此时Speak::do和Draw::do不再是virtual函数
他们的调用可以很轻松的被编译器优化
实现更高的性能
同时系统的扩展性也可以得到很好的保留