設計で悩んでます

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dic

設計で悩んでます

#1

投稿記事 by dic » 16年前

C/C++でゲームの製作をしようと思っているのですが、
最初の肝心の基本設計が自分で決められず困ってます

案は3つあるので、どれにするかで悩んでます

ソースコード上でのバージョン管理も含めた設計を考えています
どの設計がいいでしょうか?

優柔不断なものですいません

画像は設計図です

御津凪

Re:設計で悩んでます

#2

投稿記事 by 御津凪 » 16年前

オブジェクト指向で組むと考えるなら、左の案がいいと思います。

バージョン管理というのは、ゲームのバージョンの管理ということですか?
それとも CVS などのソースコードの管理のことでしょうか?

Justy

Re:設計で悩んでます

#3

投稿記事 by Justy » 16年前


>どの設計がいいでしょうか?

 これ UMLですか?
 CData1 / CData2とか CClientとか CVersionというのは一体何を扱うクラスなのか
(継承していること以外)さっぱりで、よくわかりません。

 もう少し補足して下さい。

dic

Re:設計で悩んでます

#4

投稿記事 by dic » 16年前

>御津凪さん
回答ありがとうございます

バージョン管理というのは、ソースコード上(オブジェクト指向)で
使用するクラスを変更することによって違ったオブジェクトを生成することです

ソースで示すと
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:設計で悩んでます

#5

投稿記事 by たかぎ » 16年前

具体的なことがさっぱり分かりません。
これだけの情報で、どれか一つ選べということであれば一番右でしょうか。

御津凪

Re:設計で悩んでます

#6

投稿記事 by 御津凪 » 16年前

> CData -> ゲームの情報を格納するクラス
> CVersion -> バージョンを管理するクラス
> CClient -> 実際にインスタンス化されるクラス

という意味なのであればたかぎさんと同じく一番右ですね。

> この X の部分だけを変更することによってあたかもバージョンが変わったかのような
> 動作をさせることです

継承でそのような動作をさせるのなら、
class Client { };
class Version1 : public Client { };
class Version2 : public Client { };
...
class Version99 : public Client { };
のほうが正しいです。

# こういう構造でないと実装段階でおかしなことになると思います。

dic

Re:設計で悩んでます

#7

投稿記事 by dic » 16年前

>御津凪さん たかぎ さん
お返事ありがとうございます

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();
}
こういった方法の方がいいのでしょうかね

Justy

Re:設計で悩んでます

#8

投稿記事 by Justy » 16年前

 補足ありがとうございます。
 なんとなくわかりました。

 つまりバージョンは「挙動」を変える為のものである、と。
 だとしたら、添付のように CClientは Versionのインターフェースを
持って、実際の挙動は各 CVersionに任せた方が自然ではないでしょうか。

 CDataは具体的に CClientにとってどういうものなのか、によって
どこが持つべきか変わります。
 が、多分ほとんどのケースで継承することはないでしょう。
 普通にメンバとしてもたせれば十分です。

たかぎ

Re:設計で悩んでます

#9

投稿記事 by たかぎ » 16年前

こんな風にするのはどうでしょう。
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:設計で悩んでます

#10

投稿記事 by たかぎ » 16年前

さっきの投稿で「熟練のプログラマー」に降格してしまいましたね。
こんなの初めて見ました。

Justy

Re:設計で悩んでます

#11

投稿記事 by Justy » 16年前


>さっきの投稿で「熟練のプログラマー」に降格してしまいましたね

 あ、ほんとだ。降格してる・・・。
 私も初めて見ました(w

dic

Re:設計で悩んでます

#12

投稿記事 by dic » 16年前

>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:設計で悩んでます

#13

投稿記事 by たかぎ » 16年前

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) {}
};
のようにすることが可能です。

閉鎖

“C言語何でも質問掲示板” へ戻る