c – 用于创建派生类的模式,该派生类包含本身和基类中的许多字段
|
鉴于以下预先存在的框架,我需要找到好的设计模式来创建派生类的不同实例.
我面临的主要挑战如下: 挑战 – 1>每个类都有10个以上的字段,以及如何将这些字段传递给派生类,然后有效地传递给基类. 为了解决这个问题,我可以找出四个解决方案,但没有一个能吸引我. 方法1>以简单格式传递所有参数 classA::classA(int field1,float field2,...,double field29) =>缺点:创建一个超过6~7个传入参数的函数不是一个好主意 方法2>将所有参数作为结构传递 struct DataClassA
{
int field1;
float field2;
...
double field29;
};
struct DataClassBA : DataClassA
{
int m_iField30;
// ...
double m_iField40;
};
首先,我将DataClassBA传递给classBA,然后依次将classB传递给classA. 方法3>按Set功能设置所有字段 classA
{
public:
int Field1() const { return m_iField1; }
classA& Field1(int field1)
{
m_iField1 = field1;
return *this;
}
...
}
classBA : public classA
{
public:
int Field30() const { return m_iField30; }
classBA& Field30(int field30)
{
m_iField30 = field30;
return *this;
}
...
}
=>缺点:每个实例的创建都会导致许多函数调用并且非常昂贵. 方法4>将映射传递给基类和派生类的所有构造函数. =>缺点:虽然它让数据传递变得容易,但我认为这是个坏主意. 挑战 – 2 – ;基类的默认值由其不同的派生类确定. 为了解决这个问题,我可以找到两个解决方案,但没有一个能吸引我. 方法1> 方法2> 我列出了我能想到的所有方法.但是,我仍然在寻找一个干净而专业的解决方案.如果有一个编写良好的API库,我可以用作参考来解决这个类似的问题,这将是最好的. 谢谢 /////////////////////// framework ////////////////////////////////////////
// Note:
// <1> the class hierarchy has to kept as this
// <2> getter and setter functions in each class have to kept as this
// <3> add new functions(i.e constructors) are allowed
// <4> add new classes or structures are allowed
/////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <map>
#include <string>
#include <iostream>
using namespace std;
/************************************************************************/
/* Class Name: classA (an abstract base class)
* default value of m_iField2 is determined by its derived class
/************************************************************************/
class classA
{
public:
virtual ~classA() = 0 {}
// ...
private: //
int m_iField1;
float m_iField2; // one of the potential field that has to get the default value
// ...
double m_iField29;
};
/************************************************************************/
/* Class Name: classBA
* If the pass-in parameters do NOT include value for the field classA::m_iField2
* then assign its value as 200.0f
/************************************************************************/
class classBA : public classA
{
// ...
private:
int m_iField30;
// ...
double m_iField40;
};
/************************************************************************/
/* Class Name: classCA
* If the pass-in parameters do NOT include value for the field classA::m_iField2
* then assign its value as 300.0f
/************************************************************************/
class classCA : public classA
{
// ...
private:
int m_iField50;
// ...
int m_iField60;
};
int main(int argc,char* argv[])
{
map<string,string> mapStrsBA;
mapStrsBA["name"] = "classBA";
mapStrsBA["field1"] = "5";
// ...
mapStrsBA["field40"] = "1.89";
// pass mapStrsBA to a factory class with function to create a new instance of class classBA
map<string,string> mapStrsCA;
mapStrsBA["name"] = "classCA";
mapStrsBA["field1"] = "6";
// ...
mapStrsBA["field60"] = "19";
// pass mapStrsCA to a factory class with function to create a new instance of class classCA
return 0;
}
解决方法
让我为挑战1添加一个方法5,这并不总是,但通常是适用的,特别是如果您碰巧有许多字段:查找严格属于一起的成员字段,并将它们收集到逻辑对象中.例如,假设您有一个类Shape,如下所示:
class Shape
{
public:
Shape(pass initial values for all member variables);
// ...
private:
// bounding box coordinates
int xmin,xmax;
int ymin,ymax;
// color
int red,green,blue;
int alpha;
// center point (for rotations)
int cx,cy;
};
这是10个变量.然而,那些并非真正无关.它们中的大多数是x / y对,然后有一组指定颜色.因此,您可以按如下方式重写: struct Point
{
int x,y;
Point(int ax,int ay): x(ax),y(ax) {}
};
struct Color
{
int red,blue,alpha;
Color(int r,int g,int b,int a): red(r),green(g),blue(b),alpha(a) {}
};
class Shape
{
public:
// ...
private:
// bounding box
Point lower_left,upper_right;
Color color;
Point center;
};
现在突然你只有四个变量传递.您甚至可以考虑制作一个由两个角点组成的矩形类型,并将其用于边界框,进一步将变量数量减少到3. 请注意,不仅要传递的参数数量减少,而且还增加了清晰度. 既然你没有提供关于你的课程的任何细节,我也不能说你的班级是否也可以进行这样的逻辑分组,但鉴于你提到的大量参数,如果不是,我会感到惊讶. 从挑战2开始,我认为最好将默认逻辑添加到派生类中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
