[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends] Re: [jfriends] Re: staticの使い方(メソッド)




前橋です。

西沢さん:
>> 実は dも参照していたり、a や bを破壊していたり、cに何の影響
>> も与えていなかったりしていない、ということを、コード上で保証
>> してくれていない、という心地悪さがあるのです。
>
>そのクラスが責任を持つという責任範囲が明確になっていれば、
>気にならないと思います。

クラス外に対しては、それで済むのですが、ひとつのクラスの中で、
副作用が気になる、というのもあるわけでして。

そりゃクラスが大き過ぎるよ、と言われるならば、その通りかも知
れません。

# でも、鳥頭なので、少なくともX上のMuleで1画面に収まらないプ
# ログラム間で相互に副作用があると、私の理解の範囲を超えます。

>> うーん、具体的な例がないかな、と考えていたのですが。
>> 
>> たとえば、「社員」オブジェクトの「給料」を再計算するとして、
...
>> そして、それぞれのメソッドの、入力と戻り値ははっきりしていま
>> す。だから、それを引数と戻り値にする方法が、やりたいことを最
>> も直接的に表現していると思うのです。
>
>算出するロジックから見た関数のイメージですね。

その通りです。

>もし、この「社員」クラスにサービスとして私があれば良いと思うのは
>
>1.属性のアクセッサメソッド(勤続年数、等級、勤務評価、残業時間)
>2.基本給を返すメソッド(算出ロジック)
>3.残業手当を返すメソッド(算出ロジック)
>4.最終的な給料を返すメソッド(算出ロジック)
>
>といった感じで、1で属性を定義し、2〜3は4が使い、そして
>実際は本人の最終的な給料だけ知りたいので4で結果を取り出す。
>属性の変更は行わない。
>という実装にでもなるのかなぁと思います。
>
>#雰囲気がつたわったか、ちょっと心配(^^;)

うーん、理解したつもりですが...

「算出ロジック」なら、やっぱり、「これとこれを与えると、これ
を返す」というロジックになっていると思うのですよ。

この場合、たとえば、publicにするのは最終的な給料を返すメソッ
ドだけで良いとして、4のメソッドを実現するときに、privateな
2, 3のメソッドを呼ぶわけですが、そいつらの作り方として 2案あ
りまして、

(1)引数なしのメソッドにする。プライベートメンバの勤続年数・等
  級などを参照する。
(2)引数として勤続年数・等級などを受け取るようにする。

(2)の方が、「算出ロジック」という趣旨に合致しているのではな
いかと。

>うーん、関数の感覚はJavaではあまり必要ないと私は思いますが
>他の皆さんはどうなんでしょう?

たとえば、sin() やcos() は、文句の付けようもない関数ですよね。

で、それが、Javaでは、Mathクラスのメソッドとして実現されてい
るわけですが、これはやっぱりstaticです。

関数といえば、引数を与えて、戻り値を返すモノであり、同じ引数
を与えれば必ず同じ値を返します(Cの関数はそうではないですが)。
関数が状態を持たないものであるなら、それはオブジェクトと結び
付いているべきではないだろう、と思うわけです。

Javaの sin()も staticでなくして、

  Math m = new Math();
  a = m.sin();

みたいな使い方を強要する、という手はあるかと思いますが(そう
いう言語もありますよね)、これは、タイピングするのが面倒臭く
て嫌だ、というだけでなく、sin()が副作用を持たない関数である
という事実がボケてしまう、という不満があります。

もちろん、staticメソッドでも、staticなデータメンバにはアクセ
スできるので、副作用がないということは保証できないわけですが...

sin()や cos()は、誰がどう見ても文句の付けようのない関数だと
思いますが、今回の「給与計算」みたいなのも、お客さんからもら
う仕様書には、たぶんしっかり計算式が書いてあると思うのです。

よって、それを「関数」だと見倣すのは、自然なことであるように、
私には思えます。

そういうタイプのアプリケーションは、Java(というかOOP言語)に
は向かないような気もしないでもないですが、配布が面倒なのでア
プレットにしたかったり、WindowsだとC++を使わなきゃいけなかっ
たり、といったように、設計上の向き不向き以前の問題で言語が決
定されることもあるわけでして。

>うー、破綻する場合が想像できませんでした。
>属性(インスタンス変数)で破綻するケースってどんな場合があるか
>想像力が貧困で浮かびませんでした。
>良かったら、もう少し詳しく教えてください。m(_ _)m

calcSalary()は、給料を返すだけかと思っていたら、データメンバ
のsalaryも上書きしてた、とか...

まあ、ここまでアホなメソッドは作らないと思いますが、インスタ
ンスメソッドからは、そのクラスのインスタンス変数は「まる見え」
なので、グローバル変数と同様の危険がないかなあ、ということです。

# 私自身、実際に(破壊して)はまったことがあるわけではないです
# が、プログラムの見通しが悪いんじゃないかなあ、と思うことは
# あります。

privateメンバだって、異なるクラスから隠蔽できるだけで、同一
クラスの中ではまる見えなんですよね。

あと、全然関係ないですが、Javaのprivateなインスタンス変数っ
て、クラスさえ一緒なら、インスタンスが違っても参照できちゃう
んですよね。ま、クラスの設計者はクラスの中身についてよく知っ
ているので、実用上は悪くないかなあ、という気はするんですが、
やっぱりどうも違和感が。

------------------------------------------------------------
  前橋 和弥                             maebashi@xxxxxxxxxx
  中部ソフトエンジニアリング(株)
    〒450 名古屋市中村区名駅4-10-25(名駅IMAIビル 5F)
    Tel:(052)583-4511(代) 内線 252 Fax:(052)583-4566
------------------------------------------------------------