鑑於以下預先存在的框架,我需要找到好的設計模式來創建派生類的不同實例。是模式創建包含許多字段本身和基類的派生類
我有主要的挑戰如下:
挑戰-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
,然後又通過classBA
通過DataClassA
至classA
。 =>缺點:類型DataClassBA
和classBA
是類似的類型,除了一個包含操作而另一個不包含操作。另外,將結構傳遞給構造函數時,會有副本和副本的處罰。想象一下,對於每個不同的類,我們必須定義一個類似的結構以保存所有的初始化數據。類和它的相應結構之間的關鍵不同是類包含一些方法,而結構純粹用於傳輸數據。實例的每次創建會引發許多函數的調用和非常昂貴:
方法3>通過設置功能
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>將地圖傳遞給基類和派生類的所有構造函數。
=>缺點:我認爲這是個壞主意,儘管它使數據傳遞變得簡單。
challenge-2>基類的默認值由其不同的派生類決定。 例如,基於不同的派生類,默認值classA::m_iField2
是不同的。
針對這個問題,我可以找出兩個解決方案,但沒有一個對我有吸引力。
方法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;
}
你對#2的否定不一定是正確的。考慮使用'DataForA','DataForB'和'DataForAAndB:DataForA,DataForB'類。然後,'A'可以有一個DataForA類型的數據成員,'B'可以有一個'DataForB'類型的數據成員。沒有重複,你得到'命名參數'。 – 2011-12-21 04:47:00