- PR -

引数について

投稿者投稿内容
ひで720
会議室デビュー日: 2002/12/16
投稿数: 9
投稿日時: 2003-06-30 08:45
いつも大変参考にさせていただいております。ひで720です。
Java初心者ですが宜しくお願いします。
他クラスのメソッドへの引数の渡し方について疑問があります。
引数が1項目しかない場合は、問題ないのですが、多項目あった場合
(それが問題なのかもしれませんが)すべてを引数にして渡すのが
良いのでしょうか。それともセッター・ゲッター方式にしてやりとり
するのが良いのでしょうか。極端ですが、10項目を別クラスの
メソッドへ渡してそれをDB更新したいような場合とか。
どのようなときは引数で渡して、どのようなときはセッター・
ゲッター方式にするのかよくわかりません。
非常に低レベルな質問ですが、ご教授お願いします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-06-30 09:36
unibon です。こんにちわ。

引用:

ひで720さんの書き込み (2003-06-30 08:45) より:
引数が1項目しかない場合は、問題ないのですが、多項目あった場合
(それが問題なのかもしれませんが)すべてを引数にして渡すのが
良いのでしょうか。それともセッター・ゲッター方式にしてやりとり
するのが良いのでしょうか。極端ですが、10項目を別クラスの
メソッドへ渡してそれをDB更新したいような場合とか。


以前のご投稿の「新人SEのためのJava講座についての質問」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3038&forum=12
とも関連する話題だと思います。
「すべてを引数にして渡す」ことができるということは、
クラスメソッド(static なメソッド)を呼べるということになります。
static メソッドで足りるということは、すなわち、状態を持たなくて良いということです。
このような場面で、もし、クラスメソッドではなく、セッタ/ゲッタメソッドを使ったとしても、
このようなことは Java に限ったことではなく、種々の言語でも一般的に遭遇しますが、
そのようなセッタ/ゲッタメソッドが対象となるインスタンスは短命なので(スコープが狭いので)、
結局は、表記(仔細なコーディング)の違いだけであり、実質的にはさほど差がないと思います。
そして、どちらを使うかは、好みも入ってくるのではないでしょうか。
管理するクラスを単純に少なくしたいなら、引数で引き渡すことが多くなるし、
ある程度メソッドが複雑になったり、戻り値も複数個を返すことになると、
引数ではなくセッタ/ゲッタメソッドのやりかたになることが多いでしょう。

#以下、あとで追加。

すみません。ご質問を読み直してみると、
別にすべての情報を引数に渡すというわけではないようですね。
ちょっと以前のご投稿に引っ張られてしまいました。
static は別にして単に引数かセッタ・ゲッタかならば、
対象となるインスタンスの状態を恒久的に変えるのか一時的なものなのかで
分ければよいと思います。
すなわち、恒久的に状態が変わるならばセッタ・ゲッタ方式ですし、
単にメソッドを呼んだ瞬間だけ必要な情報であり、
その情報があとに残らない(残さないほうが良い)場合は、引数が良いです。

なお、ひとつのメソッドで、セッタ・ゲッタの機能と、処理の機能を兼用するのは、
ややこしくなるのでやめたほうが良いかもしれません。

[ メッセージ編集済み 編集者: unibon 編集日時 2003-06-30 09:44 ]
ひで720
会議室デビュー日: 2002/12/16
投稿数: 9
投稿日時: 2003-06-30 13:15
unibonさん、ご教授ありがとうございました。

引用:

unibonさんの書き込み (2003-06-30 09:36) より:
static は別にして単に引数かセッタ・ゲッタかならば、
対象となるインスタンスの状態を恒久的に変えるのか一時的なものなのかで
分ければよいと思います。
すなわち、恒久的に状態が変わるならばセッタ・ゲッタ方式ですし、
単にメソッドを呼んだ瞬間だけ必要な情報であり、
その情報があとに残らない(残さないほうが良い)場合は、引数が良いです。


非常にわかりやすかったです。ポイントは一時的なのかどうかということですね。
いつも、引数かセッタ・ゲッタかで悩んでいました。最初は1項目の引数を
渡して、その引数を活用して別クラスのメソッドで処理をさせるのですが、
別の項目も必要になったりして項目が増えていくと、セッタ・ゲッタ方式に
変えてみたりと、一つのメソッドで、これは引数で取得・これはセッタ・ゲッタで
取得するソースとなり、後で見るとよくわからないことがしばしばありました。
クラス・メソッドの設計にも問題があるのかもしれません。unibonさんのご教授を
参考にがんばります。
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-07-01 09:36
メソッドの引数の数が多くなってきたと思ったら、典型的なリファクタリングのひとつの「引数オブジェクトの導入」を検討するとよいでしょう。
例えば、3つの整数フィールドと1つの文字列を持つ
DBレコードを追加するメソッドなら、
コード:
   insert( 1, 2, 3, "many parameters");


などとしていたところを、
コード:
   Record record = new Record( 1, 2, 3, "parameter object"));
   insert( record );


とします。こうすることにより、可読性や保守性が向上し、将来カラムが追加された場合の対応などもやりやすくなると思います。
Recordクラスにsetterを作ってもかまいません。
ひで720
会議室デビュー日: 2002/12/16
投稿数: 9
投稿日時: 2003-07-01 14:02
Wataさん、ご教授ありがとうござます。「引数オブジェクト」早速活用してみたいと
思います。これならDBへのレコード追加などでも使えます。大変勉強になりました。
今後は、リファクタリングを意識しながら開発したいと思います。
Shane
大ベテラン
会議室デビュー日: 2003/06/06
投稿数: 132
お住まい・勤務地: Vancouver, BC
投稿日時: 2003-07-01 14:25
疑問に思ったのですが教えてください。

> ------------------------------------------------------------------------------> --
>
> insert( 1, 2, 3, "many parameters");
>
>
> --------------------------------------------------------------------------------
>
>
> などとしていたところを、
> コード:
> --------------------------------------------------------------------------------
>
> Record record = new Record( 1, 2, 3, "parameter object"));
> insert( record );
>
>
> --------------------------------------------------------------------------------


としたとして、可読性が上がるのでしょうか?
結局オブジェクトのコンストラクタに多数の引数を渡していて
コードが増えているだけに思えるのですが。。。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2003-07-01 16:12
引用:

Shinさんの書き込み (2003-07-01 14:25) より:
疑問に思ったのですが教えてください。

> ------------------------------------------------------------------------------> --
>
> insert( 1, 2, 3, "many parameters");
>
>
> --------------------------------------------------------------------------------
>
>
> などとしていたところを、
> コード:
> --------------------------------------------------------------------------------
>
> Record record = new Record( 1, 2, 3, "parameter object"));
> insert( record );
>
>
> --------------------------------------------------------------------------------


としたとして、可読性が上がるのでしょうか?
結局オブジェクトのコンストラクタに多数の引数を渡していて
コードが増えているだけに思えるのですが。。。




こんにちわ。

僕も上記のような事をしばしばしますが

この場合、保守性とか可読性とかを意識したこはなく・・。
# すいません、ホントは何か良い点があるのでしょうけど

単に「かっこ良さ」「スマートさ」「設計の美しさ」
というかなり主観的な観点で修正したりします。

だめ?
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-07-01 19:27
引用:

Shinさんの書き込み (2003-07-01 14:25) より:

結局オブジェクトのコンストラクタに多数の引数を渡していて
コードが増えているだけに思えるのですが。。。



コンストラクタの引数が多くなるのならば、
Recordクラスにsetterをつけるとよいでしょう。
コード量が増えますが、より処理が明確になります。

コード:
Record record = new Record();
record.setFirstName("wa");
record.setLastName("ta");
record.setPhoneNumber("09012345678");
record.setSex(Record.MALE);
 :
insert(record);


また、リファクタリングにおいては全体のコード量が増えることは問題としません。
簡潔で自明なコードならば一目で理解できますから。

また、このような引数オブジェクトを導入するメリットは
このオブジェクトは他のコードでも使えるという事です。
たとえば、insertがあるならば、update(Record record)
もある可能性が高いでしょう。search(Record record)も
ありうるでしょう。

そのとき、Recordオブジェクトを使えは引数チェックなどを
まとめたり、insertとupdateで引数の順番が違ったりするのを
暗に回避したりすることができます。

可読性に関しては、引数の中にDBレコードの内容以外のものが
あるときなどはより効果的です。
コード:
public void insert(Record record, boolean autoCommit){...}


などです。

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