泛型结合多态

来源:互联网 发布:淘宝店铺如何改名字 编辑:程序博客网 时间:2024/06/05 09:36
 <转>

http://www.cnblogs.com/zhengzengyuan/archive/2009/12/18/1626746.html

一个关于泛型结合多态设计方面的文章。

先看段代码:

class IMaterialCoeff {
public:

virtual void ReadCoeff()=0;

};

class DenModelCoeff : public IMaterialCoeff {
public:

virtual void ReadCoeff();

virtual void GetModelCoeffByMaterialNo(const int, vector<ShcCoeffData>&     result);

};

class HccModelCoeff : public IMaterialCoeff {

public:

virtual void ReadCoeff();

virtual void GetModelCoeffByMaterialNo(const int, vector<HccCoeffData>&   result);

};

.....还有几个类似的继承方式。

在这个例子中IMaterialCoeff是一个抽象的接口,对于设计这个接口的目的有以下两个原因:

1):项目的后期读取系数的方式有可能会改变,所以设计了一个纯虚函数ReadCoeff()来应对以后的变化。

2):减少MaterialCoeff与其他模块之间的耦合性。

但是目前的实现的接口无法满足我的第二点要求。因为在其他模块中更频繁被使用的是派生类中GetModelCoeffByMaterialNo操作。实质上说接口并没有为降低耦合性提供帮助,甚至由于耦合性没有得到降低导致我的第一个实现目标都无法实现。

为什么第二个目的无法实现?很显然是GetModelCoeffByMaterialNo方法具有一个不同类型的参数。导致无法将这个方法抽象到接口中,而影响整个程序的设计和思路的展开。那么怎么样才能构建一个可变化的类型?第一个在我脑海中浮现的就是泛型(template),将接口设计成泛型。出于这个大胆的想法,我写了一段测试程序:

tempalte <typename T>

class Test {

public:

virtual void Func(T & result) = 0; // 将泛型和纯虚函数结合在一起
};

class TestImpl : public Test<int> {

public:

virtual void Func(int& result) { result = 10; std::cout << "TestImpl::Func() Called!" << std::endl; }

};

int main() { 

Test *test = new TestImpl;

int result; 

test->Func(result);  

return 0;

}

很顺利,程序立刻就能顺利的运行,并得到输出: TestImpl::Func() Called,派生类的成员函数通过多态的形式被调用了^_^。说明这种通过模板实现的接口是可行的而且非常的perfect。它仿佛能帮我们实现一个类型可变的多态。接下来,实现工作中的程序,完成下面的设计和代码。

 MaterialCoeffUML

 

通过模板参数列表类型延迟到模板id确定,实现一种类型可变化的多态假象。而使用泛型设计,实质上我们从上面的UML图可以看出,其实是在派生类和接口之间构建了一道桥梁,来重新衔接出一种继承方式,从而隔离了接口和派生类。OK,现在让我们看看写出来的代码吧。

template <typename Result>

class IMaterialCoeff {

public:

typedef Result result_type;

virtual void ReadCoeff() = 0;

virtual void GetModelCoeffByMaterialNo(const int, Result&) = 0;

};

class ShcModelCoeff : 

public IMaterialCoeff<std::vector<ShcCoeffData> > {

public:

virtual void ReadCoeff();

virtual void GetModelCoeffByMaterialNo(const int, result_type& result);

};

class HccModelCoeff : 

public IMaterialCoeff<std::vector<HccCoeffData> > {

public:

virtual void ReadCoeff();

virtual void GetModelCoeffByMaterialNo(const int, result_type& result);

};

OK,到目前为止,已经能成功的实现我项目的功能了。

最后,来点总结吧。

1):通过将泛型+多态结合,实现了一种虚函数参数类型可变化的多态。使得我们面临变化多端的程序,有能更好的灵活性。

2):编写程序的时候,要多发现变化之处,思考变化之处,怎么使变化的之处保持不变,最后以不变应万变。就好比上面看到GetModelCoeffByMaterialNo参数是变化的,才知道怎么让其不变。

3):泛型+多态真的很perfect

好吧!今天就聊到这。

 

原创粉丝点击