Recentemente ho seguito un corso sui processi software e questa è la prima volta che cerco di progettare OO da solo. Sto cercando di seguire i principi di progettazione OO e le convenzioni C ++. Ho tentato e rinunciato a MVC per questa applicazione, ma sto cercando di "disaccoppiare" le mie classi in modo tale che possano essere facilmente testate unitamente e così posso facilmente cambiare la libreria GUI utilizzata e / o il SO di destinazione. Al momento, ho finito di progettare le classi ma non ho ancora iniziato a implementare i metodi.
La funzione del software è di registrare tutti i pacchetti inviati e ricevuti e visualizzarli sullo schermo (come WireShark, ma solo per un processo locale). Il software realizza ciò agganciando le funzioni send () e recv () in winsock32.dll, o qualche altra coppia di funzioni analoghe a seconda di quale sia l'obiettivo desiderato. Gli hook aggiungono pacchetti a SendPacketList / RecvPacketList. La classe GuiLogic avvia una discussione che verifica la presenza di nuovi pacchetti. Quando vengono trovati nuovi pacchetti, utilizza la classe PacketFilter per determinare la formattazione per il nuovo pacchetto e quindi lo invia a MainWindow, una finestra win32 nativa (con l'intenzione di portarla successivamente a Qt) .1
Ecco le mie classi in forma scheletro / intestazione (questo è il mio vero codice):
class PacketModel
{
protected:
std::vector<byte> data;
int id;
public:
PacketModel();
PacketModel(byte* data, unsigned int size);
PacketModel(int id, byte* data, unsigned int size);
int GetLen();
bool IsValid(); //len >= sizeof(opcode_t)
opcode_t GetOpcode();
byte* GetData(); //returns &(data[0])
bool GetData(byte* outdata, int maxlen);
void SetData(byte* pdata, int len);
int GetId();
void SetId(int id);
bool ParseData(char* instr);
bool StringRepr(char* outstr);
byte& operator[] (const int index);
};
class SendPacket : public PacketModel
{
protected:
byte* returnAddy;
public:
byte* GetReturnAddy();
void SetReturnAddy(byte* addy);
};
class RecvPacket : public PacketModel
{
protected:
byte* callAddy;
public:
byte* GetCallAddy();
void SetCallAddy(byte* addy);
};
//problem: packets may be added to list at any time by any number of threads
//solution: critical section associated with each packet list
class Synch
{
public:
void Enter();
void Leave();
};
template<class PacketType> class PacketList
{
private:
static const int MAX_STORED_PACKETS = 1000;
public:
static const int DEFAULT_SHOWN_PACKETS = 100;
private:
vector<PacketType> list;
Synch synch; //wrapper for critical section
public:
void AddPacket(PacketType* packet);
PacketType* GetPacket(int id);
int TotalPackets();
};
class SendPacketList : PacketList<SendPacket>
{
};
class RecvPacketList : PacketList<RecvPacket>
{
};
class Target //one socket
{
bool Send(SendPacket* packet);
bool Inject(RecvPacket* packet);
bool InitSendHook(SendPacketList* sendList);
bool InitRecvHook(RecvPacketList* recvList);
};
class FilterModel
{
private:
opcode_t opcode;
int colorID;
bool bFilter;
char name[41];
};
class FilterFile
{
private:
FilterModel filter;
public:
void Save();
void Load();
FilterModel* GetFilter(opcode_t opcode);
};
class PacketFilter
{
private:
FilterFile filters;
public:
bool IsFiltered(opcode_t opcode);
bool GetName(opcode_t opcode, char* namestr); //return false if name does not exist
COLORREF GetColor(opcode_t opcode); //return default color if no custom color
};
class GuiLogic
{
private:
SendPacketList sendList;
RecvPacketList recvList;
PacketFilter packetFilter;
void GetPacketRepr(PacketModel* packet);
void ReadNew();
void AddToWindow();
public:
void Refresh(); //called from thread
void GetPacketInfo(int id); //called from MainWindow
};
Sto cercando una revisione generale della mia progettazione OO, l'uso di UML e l'uso delle funzionalità C ++. Voglio soprattutto sapere se sto facendo qualcosa di molto sbagliato.
Da quello che ho letto, la revisione del design è in-topic per questo sito (e fuori tema per il sito Code Review).
Qualsiasi tipo di feedback è molto apprezzato. Grazie per aver letto questo.