設計で悩んでます
Re:設計で悩んでます
オブジェクト指向で組むと考えるなら、左の案がいいと思います。
バージョン管理というのは、ゲームのバージョンの管理ということですか?
それとも CVS などのソースコードの管理のことでしょうか?
バージョン管理というのは、ゲームのバージョンの管理ということですか?
それとも CVS などのソースコードの管理のことでしょうか?
Re:設計で悩んでます
>どの設計がいいでしょうか?
これ UMLですか?
CData1 / CData2とか CClientとか CVersionというのは一体何を扱うクラスなのか
(継承していること以外)さっぱりで、よくわかりません。
もう少し補足して下さい。
Re:設計で悩んでます
>御津凪さん
回答ありがとうございます
バージョン管理というのは、ソースコード上(オブジェクト指向)で
使用するクラスを変更することによって違ったオブジェクトを生成することです
ソースで示すと
この X の部分だけを変更することによってあたかもバージョンが変わったかのような
動作をさせることです
私専用の言葉でしたらすいません
>Justyさん
CData -> ゲームの情報を格納するクラス
CVersion -> バージョンを管理するクラス
CClient -> 実際にインスタンス化されるクラス
となっております
簡潔な図になるように説明などは省きました すいません
なお 下のLevelは私が考え出した順につけたものです
特に意味はありません
画像の投稿がキャッシュがきいているのか反映されないかもしれないので
最初の画像と同じだったら下の画像をごらんください
http://gazoubbs.com/2ji/img/1223727923/365.jpg
回答ありがとうございます
バージョン管理というのは、ソースコード上(オブジェクト指向)で
使用するクラスを変更することによって違ったオブジェクトを生成することです
ソースで示すと
class Version1 { }; class Version2 { }; ... class Version99{ }; class Client : public VersionX { };のようにどのクラスを継承するかでオブジェクトの動作を変更する方法です
この X の部分だけを変更することによってあたかもバージョンが変わったかのような
動作をさせることです
私専用の言葉でしたらすいません
>Justyさん
CData -> ゲームの情報を格納するクラス
CVersion -> バージョンを管理するクラス
CClient -> 実際にインスタンス化されるクラス
となっております
簡潔な図になるように説明などは省きました すいません
なお 下のLevelは私が考え出した順につけたものです
特に意味はありません
画像の投稿がキャッシュがきいているのか反映されないかもしれないので
最初の画像と同じだったら下の画像をごらんください
http://gazoubbs.com/2ji/img/1223727923/365.jpg
Re:設計で悩んでます
> CData -> ゲームの情報を格納するクラス
> CVersion -> バージョンを管理するクラス
> CClient -> 実際にインスタンス化されるクラス
という意味なのであればたかぎさんと同じく一番右ですね。
> この X の部分だけを変更することによってあたかもバージョンが変わったかのような
> 動作をさせることです
継承でそのような動作をさせるのなら、
# こういう構造でないと実装段階でおかしなことになると思います。
> CVersion -> バージョンを管理するクラス
> CClient -> 実際にインスタンス化されるクラス
という意味なのであればたかぎさんと同じく一番右ですね。
> この X の部分だけを変更することによってあたかもバージョンが変わったかのような
> 動作をさせることです
継承でそのような動作をさせるのなら、
class Client { }; class Version1 : public Client { }; class Version2 : public Client { }; ... class Version99 : public Client { };のほうが正しいです。
# こういう構造でないと実装段階でおかしなことになると思います。
Re:設計で悩んでます
>御津凪さん たかぎ さん
お返事ありがとうございます
class Client { };
class Version1 : public Client { };
class Version2 : public Client { };
...
class Version99 : public Client { };
このようにすると
実際のコードは
ような気がするのですが
ポリモーフィズムを使えば解決しますが
お返事ありがとうございます
class Client { };
class Version1 : public Client { };
class Version2 : public Client { };
...
class Version99 : public Client { };
このようにすると
実際のコードは
void main() { Version1 obj; obj.Show(); }のようになり ここでの obj変数がVersion1 となり クライアントと意図が伝わらない
ような気がするのですが
ポリモーフィズムを使えば解決しますが
void main() { Client *obj; obj = new VersionX(); obj->Show(); }こういった方法の方がいいのでしょうかね
Re:設計で悩んでます
補足ありがとうございます。
なんとなくわかりました。
つまりバージョンは「挙動」を変える為のものである、と。
だとしたら、添付のように CClientは Versionのインターフェースを
持って、実際の挙動は各 CVersionに任せた方が自然ではないでしょうか。
CDataは具体的に CClientにとってどういうものなのか、によって
どこが持つべきか変わります。
が、多分ほとんどのケースで継承することはないでしょう。
普通にメンバとしてもたせれば十分です。
なんとなくわかりました。
つまりバージョンは「挙動」を変える為のものである、と。
だとしたら、添付のように CClientは Versionのインターフェースを
持って、実際の挙動は各 CVersionに任せた方が自然ではないでしょうか。
CDataは具体的に CClientにとってどういうものなのか、によって
どこが持つべきか変わります。
が、多分ほとんどのケースで継承することはないでしょう。
普通にメンバとしてもたせれば十分です。
Re:設計で悩んでます
こんな風にするのはどうでしょう。
class ClientBase { public: virtual void Show() = 0; }; template <class Version> class Client : public ClientBase { ... };とすれば、
class Version1 { ... }; int main() { ClientBase* obj = new Client<Version1>; obj->Show(); ... }問題にされている箇所は、一通り解消する気がするのですが...
Re:設計で悩んでます
>Justyさん
コンポジションを利用するのですね
参考になりました
>たかぎさん
template関数は私の勉強不足でして、まだ理解していない分野です
精進不足ですいません
バージョン管理というか、挙動変更の為の修正は
なんとなく結局はプログラマの好みにたどりつくような気がします
マクロで行うか、switchで分けるか、継承で分けるか、
ポリモーフィズムを使うか、templateを使うか、ファイルから読み込むかなどなど
ご回答ありがとうございました
Justyさんの参考を元に作ると以下のようになりました
コンポジションを利用するのですね
参考になりました
>たかぎさん
template関数は私の勉強不足でして、まだ理解していない分野です
精進不足ですいません
バージョン管理というか、挙動変更の為の修正は
なんとなく結局はプログラマの好みにたどりつくような気がします
マクロで行うか、switchで分けるか、継承で分けるか、
ポリモーフィズムを使うか、templateを使うか、ファイルから読み込むかなどなど
ご回答ありがとうございました
Justyさんの参考を元に作ると以下のようになりました
#include <stdio.h> class IVersion { protected: public: double version; virtual void Show() = 0; }; class CVersion1 : public IVersion { public: void Show() { printf( "version1\n" ); } }; class CVersion2 : public IVersion { public: void Show() { printf( "version2\n" ); } }; class CClient { public: IVersion *ver; CClient(); ~CClient(); }; CClient::CClient() { // どっちかを採用 ver = new CVersion1(); // ver = new CVersion2(); } CClient::~CClient(){ delete ver; } void main() { CClient client; client.ver->Show(); }
Re:設計で悩んでます
class CClient { public: IVersion *ver; CClient(); ~CClient(); };↑は駄目でしょう。
せめて、
class CClient { IVersion *ver; public: void Show() const { return ver->Show(); } CClient(); ~CClient(); };とすべきですね。
ちなみにテンプレートを使うと、
struct Version1 { static const char value[/url]; }; const chat Version1::value[/url] = "version1"; class ClientBase { public: virtual void Show() const = 0; }; template <class Version> class Client : public ClientBase { public: virtual void Show() const { std::printf("%s\n", Version::value); } };あるいは、
struct Version1 { static const char value[/url]; }; const chat Version1::value[/url] = "version1"; class ClientBase { public: void Show() const { std::printf("%s\n", version); protected: explicit ClientBase(const char* ver) : version(ver) {} private: const char* version; }; template <class Version> class Client : public ClientBase { public: Client() : ClientBase(Version::value) {} };のようにすることが可能です。