私は C++ を初めて使用し、クラスでオーバーヘッドを生成するところまで来ました。QTcpSocket があり、そこからメッセージを読み取り、MessageJoin、MessagePart、MessageUserData などのオブジェクトを作成します。これらのオブジェクトをクライアントに送信して表示します (+ UI の更新を行います)。
ここに私の問題があります。いくつかの設計手法をテストしましたが、どれもそれほど素晴らしいものではありません。
- シグナル/スロット接続でメッセージ オブジェクトの各パラメータをクライアントに渡す - オーバーヘッドは小さいが見栄えはよくない
- Message-Type (messageJoinReceived、messageNoticeReceived など) ごとにメソッドを作成します。
- 1 つのメソッドを作成し、dynamic_cast を使用して各クラスをキャストし、テストします
理解を深めるために、自分の dynamic_cast バージョンを追加しました。言われているように、コードは見苦しく使い物になりません。私の質問は次のとおりです。
- (a)dynamic_castでそれを行うより良い方法はありますか
- このような問題を解決する別の方法 (たとえば設計パターン) はありますか? クラスにメソッドを追加して、型などを返すかもしれません
- ビジターパターンについて読みました。このパターンは、Getter/Setter メソッドの動的オブジェクト タイプ専用ですか?
いくつかの補足事項
- RTTIが使える
- 速度は大した問題ではありません。クリーンでわかりやすいコードがより重要
- 私は Qt を使用しており、qobject_cast と signal/slots を使用する可能性があります
これが私のコードです(Pastebin-Link):
// Default class - contains the complete message (untouched)
class Message
{
public:
QString virtual getRawMessage() { return dataRawMessage; }
protected:
QString dataRawMessage;
};
// Join class - cointains the name of the joined user and the channel
class MessageJoin : public Message
{
public:
MessageJoin(const QString &rawmessage, const QString &channel, const QString &user)
{
dataRawMessage = rawmessage;
dataChannel = channel;
dataUser = user;
}
QString getChannel() { return dataChannel; }
QString getUser(){ return dataUser; }
private:
QString dataChannel;
QString dataUser;
};
// Notice class - contains a notification message
class MessageNotice : public Message
{
public:
MessageNotice(const QString &rawmessage, const QString &text)
{
dataRawMessage = rawmessage;
dataText = text;
}
QString getText() { return dataText;}
private:
QString dataText;
};
// Client code - print message and update UI
void Client::messageReceived(Message *message)
{
if(message)
{
MessageJoin *messagejoin;
MessagePart *messagepart;
MessageNotice *messagenotice;
if((messagejoin = dynamic_cast<MessageJoin *>(message)) != 0)
{
qDebug() << messagejoin->getUser() << " joined " << messagejoin->getChannel();
// Update UI: Add user
}
else if((messagenotice = dynamic_cast<MessageNotice *>(message)) != 0)
{
qDebug() << messagenotice->getText();
// Update UI: Display message
}
else
{
qDebug() << "Cannot cast message object";
}
delete message; // Message was allocated in the library and is not used anymore
}
}