- PR -

質問:オブジェクトの初期化について。

1
投稿者投稿内容
スープカレー
会議室デビュー日: 2005/11/28
投稿数: 5
投稿日時: 2005-12-13 11:52
こんにちは。初めて投稿します。

オブジェクトの初期化に関する質問なのですが、メンバを多数持つクラスのオブジェクトを生成・初期化するコードとして、サンプルなどで以下のようものがよく見られるかと思います。

1.デフォルトコンストラクタのみ。初期値はプロパティで設定。
Hoge hoge = new Hoge();
hoge.Xxx = xxx;
hoge.Yyy = yyy;
hoge.Zzz = zzz;
...

2.デフォルトコンストラクタなし。引数を指定して生成と同時に初期化。
Hoge hoge = new Hoge(xxx, yyy, zzz, ...);

3.オーバーロードで1,2両方利用。

ここで思ったのですがクラス設計を行う際に初期化のインターフェースとして、みなさんはどのケースを多く使用しているのでしょうか?それぞれのメリット・デメリット、使い分け方、上記以外の手法による初期化などあわせてお聞かせいただけるとありがたいです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-13 12:01
引用:

スープカレーさんの書き込み (2005-12-13 11:52) より:

ここで思ったのですがクラス設計を行う際に初期化のインターフェースとして、みなさんはどのケースを多く使用しているのでしょうか?
それぞれのメリット・デメリット、使い分け方、上記以外の手法による初期化などあわせてお聞かせいただけるとありがたいです。


うーん、臨機応変になるのでしょうかね。
System.Data.SqlClient.SqlConnection クラスなどは、[3] になりますね。
(ところで "オーバーロード" ではないですよね)

あるプロパティを設定しないと使えないようなクラスの場合は、
コンストラクタで強制すべきだと個人的には思いますが、
どのみちテストで動かないので、両方用意しても問題はないとも思っています。

# データクラスなんかは用意してられませんが。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-12-13 12:11
私はコードの中でコンストラクタで1行で初期化したほうが見やすいときは、初期化用のコンストラクタを作成するリファクタリングをします。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-12-13 12:24
プロパティを使うにはいくつかの条件を満たす必要があります。「ひとつはその値だけを変更することが許されること」「設定する順番が任意であること」この二つの条件を満たせない場合にプロパティを使用すると、そのクラスの利用者は内部実装を常に意識してコーディングすることが求められます。これではカプセル化の原則に反します。

コンストラクタの引数に多数のパラメータを渡す時を想像してみて下さい。殆どのパラメータはデフォルトで滅多に指定する必要がないとします。これをコンストラクタの引数で地区位置指定するのは手間が増るだけで嬉しくないですよね。

また実際の初期化をどのタイミングで行うのかも問題となります。コンストラクタで初期化を行うのであれば、そのために必要なパラメータは必然的にコンストラクタで受けるしかありません。また逆にコンストラクタで引数をとらないのであれば、初期化を行うタイミングを別に考える必要があります。

この辺りを踏まえて考えてみれば、そのクラスにおいてどの様にするのがベターなのか、答えが見えてきませんか?
スープカレー
会議室デビュー日: 2005/11/28
投稿数: 5
投稿日時: 2005-12-13 13:47
早速のお返事ありがとうございます。

じゃんぬねっとさん:
>あるプロパティを設定しないと使えないようなクラスの場合は、
>コンストラクタで強制すべきだと個人的には思いますが、

 私もそう思いますが、強制ではなく推奨?のような形のプロパティではどうでしょうか?例えばJavaのLabelクラスではテキストを指定するものがありますが、.NETのLabelクラスではデフォルトコンストラクタのみです。テキストのないラベルに意味がないという判断から存在するのかこの辺りの基準が今ひとつわかりません。

>どのみちテストで動かないので、両方用意しても問題はないとも思っています。
 強制の場合だと最終的にはデフォルトコンストラクタを使用不可にしてしまうのでしょうか?

Anthyhimeさん:
 クラス作成当初は詳細な設計でも行わない限りそんな感じでいいものなのでしょうか。

甕星さん:
>プロパティを使うにはいくつかの条件を満たす必要があります。「ひとつはその値だけを
>変更することが許されること」「設定する順番が任意であること」この二つの条件を満た
>せない場合にプロパティを使用すると、そのクラスの利用者は内部実装を常に意識して
>コーディングすることが求められます。これではカプセル化の原則に反します。
 深いですね。ここまで考えて設計したこと無かったです。勉強になります。

>コンストラクタの引数に多数のパラメータを渡す時を想像してみて下さい。殆どのパラ
>メータはデフォルトで滅多に指定する必要がないとします。これをコンストラクタの引数
>で地区位置指定するのは手間が増るだけで嬉しくないですよね。
 確かに。でも、じゃんぬねっとさんのとこでも書きましたがこの辺りの基準ってやっぱり人それぞれなんでしょうか?どうもパラメータの必要性の判断が私には難しいようで...
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-13 14:21
引用:

スープカレーさんの書き込み (2005-12-13 13:47) より:

強制の場合だと最終的にはデフォルトコンストラクタを使用不可にしてしまうのでしょうか?


そうですね、たとえば入出力系のクラスはそういったことをします。
System.IO.StreamReader クラスもそうなってますよね。

そもそも、必須なパラメタがあまりに多い場合なんて普通はないですし。
(その時点で設計がおかしいことになりますから)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
1

スキルアップ/キャリアアップ(JOB@IT)