У меня есть общий вопрос о дизайне класса C ++. Например, мне нужен генератор пакетов. Поэтому, учитывая тип пакета, я должен создать пакет этого типа. Итак, у меня есть базовый класс генератора пакетов.
Подход 1:
class BasePacketGenerator {
public:
virtual Packet* generatePacket (int type); // implements the generic case
// hence not pure virtual
protected:
//
// Common functionality for all types
//
virtual void massagePacket (Packet& pkt); // called by generatePacket
// but needs special handling for
// some types
virtual void calculateCheckSum(Packet& pkt); // called by generate packet
...
};
Производные классы для обработки каждого типа:
class Type1PacketGenerator : public BasePacketGenerator {
public:
// Dont have to override any base class implementationa
protected:
void calculateCheckSum(Packet& pkt) override;
};
class Type2PacketGenerator : public BasePacketGenerator {
public:
Packet* generatePacket(int type) override;
};
Здесь для генератора Type1 мы используем полиморфизм. Но вызовы базового класса, функциональность производного класса полиморфно. Интересно, это хорошая идиома? Или должен быть класс-посредник
Подход 2:
class TypeHandler {
virtual Packet* setupPacket();
virtual void calculateCheckSum(Packet& pkt);
virtual void setupFields (Packet& pkt);
}
class PacketGenerator {
public:
TypeHandler *handler_; // lets say this is setup based on the type
Packet* generatorPacket(int type)
{
auto packet = handler_->setupPacket();
handler_->massagePacket();
handler_->calculateCheckSum(*packet);
return packet;
}
}
Есть ли какое-то преимущество в использовании одного или другого подхода?
Подход1 более гибок, так как он не должен следовать тому же самому пути действий. Например: если Type2Generator не нужна контрольная сумма, ему даже не нужно вызывать calcCheckSum () или если ему нужны некоторые дополнительные функции, нам не нужно добавлять его ко всем генераторам типов.
Но Подход 2 более читабелен, поскольку все типы делают вещи одинаково.