Учитывая следующую ранее существующую среду, мне нужно найти хорошие шаблоны проектирования для создания различных экземпляров производного класса.
Основные проблемы, с которыми я сталкиваюсь, следующие:
challenge-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
.=> cons: type DataClassBA
и classBA
являются схожими типами, за исключением того, что один содержит операции, а другой нет.Кроме того, при передаче структуры конструкторам, существует штраф за копии и дубликаты.Представьте, что для каждого отдельного класса мы должны определить аналогичную структуру для хранения всех данных инициализации.Ключевым отличием между классом и его соответствующей структурой является то, что класс содержит некоторые методы, в то время как структура используется исключительно для передачи данных.
Метод 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 > передает карту всем конструкторам базового и производного класса.
=> минусы: я действительно считаю, что это плохая идея, хотя она упрощает передачу данных.
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;
}