5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

美しいプログラムの定義とは?

1 :仕様書無しさん:2007/02/04(日) 20:12:15
美しいプログラムってどんなの?

2 :仕様書無しさん:2007/02/04(日) 20:40:46
簡潔かつ可読性が高く、それでいて要件を満たす様が
見るものに感動を与えるプログラム。

3 :仕様書無しさん:2007/02/04(日) 20:41:55
「いい仕事してますね〜」なプログラム

4 :仕様書無しさん:2007/02/04(日) 20:56:35
初めての人がみて「荒れまくり」のコーディングなんだけど
なぜか不思議と動きつづけてるプログラム

5 :先生:2007/02/04(日) 23:29:30
よし、俺が美しいプログラムがどんなものかレクチャーしてやるよ。

と、その前に汚いプログラムとはどんなものかを理解する必要がある。敵を
知らば百選なんとかとやらだ。
オブジェクト指向といえど、個々の処理をメソッド単位でみると、順処理
と分岐の羅列にすぎない。あとループとかあるがここではおいとく。

で、例えば、Aという処理をするのに、分岐が3箇所必要だとする。
 if(i == 0) {  ←(1)
   ....
 } else if(i == 1){   ←(2)
  ...
 } else {   ←(3)
  ...
 }
同じくBという処理をするのに、分岐が4箇所必要だとする。

そして、これらの処理が関連したものだとすると、お前らは、これら一連
の処理を無邪気にもだらだらと同じメソッドfuncAB()内に書いてしまうん
だな。


6 :先生:2007/02/04(日) 23:30:55
だけど、危機察知能力に優れた俺はそんなことはしない。
funcA()とfuncB()にそれぞれ分ける。そして、funcAB()からfuncA()とfuncB()
を呼ぶようにする。

なぜそうするかという理由は幾つかあるが、ひとつにはテストのしやすさ
がある。
funcA()とfuncB()に分けた場合、funcA()をテストするのにテストケースを
3種類。funcB()をテストするのにテストケースを4種類用意すればいいん
だが、funcAB()にごっちゃにした場合、最悪12種類(3×4)のテストケー
スを用意しなければならない。これは恐らく本来の要件でないケースが多い。
メソッドの粒度を細かくして、個々のテストを確実にした上で結合させた方
が理解のし易さ、効率、保守性等に優れるのは明らかだ。


7 :先生:2007/02/04(日) 23:32:07
もうひとつ、funcA()の処理が別の処理でも必要になったとする。関数分割
してあれば、単にそこで、funcA()を呼ぶだけだ。しかし、funcAB()にごっちゃ
にしてあったとするとそうはいかない。こういう時は無邪気なお前らはすぐ
にコードをコピペする。しかしこれはいただけない。汚いコードの典型だ。
仮にfuncA()の処理内容を変更しなければならなくなった時、お前らがキャッ
キャッキャッキャとコピペした箇所をぜ〜〜〜〜〜〜〜〜ぶっ修正してまわ
らなければならないのだ。これ最悪。善良な俺でも殺意が芽生えてくる。
気をつけるように。関数分割を面倒くさがるなよ。

今日は夜も遅いからここまで。じゃーな。復習しとけよ。


8 :仕様書無しさん:2007/02/04(日) 23:53:28
固定値の分岐ならswitchの方が高速みたいっすよ。

9 :仕様書無しさん:2007/02/04(日) 23:59:39
テスタビリティなら、関数分割じゃなくてステートパターンの方が高いみたいっすよ。

10 :仕様書無しさん:2007/02/05(月) 00:07:18
>>8-9
そおすっか、自分しらなかっす
体育会系、プッ

11 :仕様書無しさん:2007/02/05(月) 00:45:18


http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.intro.html

12 :仕様書無しさん:2007/02/05(月) 03:13:54
カタリーナビットとかミッシェルクワンだと言う奴もいるだろうが
おれはやっぱり真央タンだな。ショートプログラムなら今季のやつ。

13 :仕様書無しさん:2007/02/05(月) 13:29:23
>>5-7
分岐ごとに継承クラスを作ってfactoryパターンでブン回すってのはナシですか。

14 :仕様書無しさん:2007/02/05(月) 13:59:46
>>12 ジャネット・リンを落とすな!

15 :先生:2007/02/06(火) 00:38:36
>>13 すまん、意味がよくわらかん。その労力に見合うだけのメリットがあれば
そうすればいいと思うが。まぁデザパタについては別の機会に。

関数やメソッドを極力分割することの重要性については、昨日も述べた通りだ。
最低これだけは守って欲しい。これすらできていないソースは見られることを
恥だと思った方がいい。また、他の人にかなりの迷惑をかけることにもなる。

プログラミングというものは、便利な部品を用意して組み上げていくレゴブロッ
クのようなものだ。ところがお前らときたら、ブロックをこねこねと粘土のよう
にこねくりまわして大きな塊にしたがる。これではダメだ。

目の前に粘土があったら、その粘土から、まずはブロックを作って欲しい。
手を作り、足を作り、顔をつくり、それらを接合して生き物を完成させるんだ。
そして、これらの部品は極力粒度を細かくした方がいい。

16 :先生:2007/02/06(火) 00:39:11
で、今日は、関数の引数について述べてみたい。

例えば、いまfuncA()という関数を作っていて、その処理をするのに、a, b, c
3つの情報が必要だとする。(ここでの、a, b, c はintやlong等のプリミティブ
型、または、stringやdate等の基本型とする)

そして、このうち、bとc の値は D というクラスのインスタンスから取得でき
る(D.getB()、D.getC()等)とする。しかし、funcAの引数をfuncA(a, D)として
はいけない。いや絶対ダメというわけではないし、状況にもよるが、やはりこ
こは極力 funcA(a, b, c) としてほしい。

17 :先生:2007/02/06(火) 00:40:13
なぜ、funcA(a, D)は望ましくないのか。それは、この関数とクラスDとの結び
付きを断つためだ。funcA(a, D) としてしまうと、例えば別の処理でこの関数
を呼びたい時にも、クラスDのインスタンスが必要になってしまう。つまり、
この関数がクラスDに依存してしまうことになってしまう。それはあまりレゴの
ブロックとしてはよろしくない。顔にしか使えないブロック(まぁそれが便利な
時もあるが)よりも、足でも手でも使えるようなブロックを用意した方がいい。
(つまり汎用化を意識しようということだ。) ・・・今日はここまで。


18 :仕様書無しさん:2007/02/06(火) 01:07:27
構造化とは複雑さをブロックによって制御する方法であり
オブジェクト指向とは複雑さを多層化により制御する方法である

19 :仕様書無しさん:2007/02/06(火) 01:07:46
>>17
場合にもよるがそういう際は
funcAをD内の関数にすればいいことが多いんじゃないの。

aだけ外部の変数として、その関数を外部から使うときはD.funcA(a) などという形のものする。
そうすればそもそもb,cを引数にしなくてよくなったりする。

20 :仕様書無しさん:2007/02/06(火) 01:14:00
はいはい転載転載

ttp://www.atmarkit.co.jp/im/carc/serial/redge51/redge51.html

21 :仕様書無しさん:2007/02/06(火) 02:32:57
このソフトウェアのこの部分のソースが美しいと見せればいいのにな
>>16では前提があいまいすぎると思われ

22 :仕様書無しさん:2007/02/06(火) 04:34:31
>>5-21
スレタイよめ。
誰が具体例を挙げろと


23 :仕様書無しさん:2007/02/06(火) 09:01:06
まったりとしていて、それでいてしつこくないプログラム

24 :仕様書無しさん:2007/02/06(火) 11:12:53
定義なぞ無い。

ある人が美しいと思えばそのプログラムはその人にとって美しい

だいたい定義ってなんだよ。
定義とは未定義用語の上に積み重ねられるものだろ?
「美しい」は未定義用語なのだが。

25 :仕様書無しさん:2007/02/06(火) 11:22:29
コメントが全て英語とか。

26 :仕様書無しさん:2007/02/06(火) 13:30:58
>>16-17
依存したくないのならインターフェースを挟めばいいじゃない。
将来funcA(a, b, c)がfuncA(a, b, c, d, e, f, g)とかになったらどーすんの。


27 :仕様書無しさん:2007/02/06(火) 16:48:04
// ∩___∩   /)
// |ノ      ヽ ( i ))
// /  ●   ● | / /
// |    ( _●_) |ノ / checkpoint! HAHAHA
//彡、   |∪|   ,/
///   ヽノ   /

28 :先生:2007/02/06(火) 22:38:53
>>26
>>将来funcA(a, b, c)がfuncA(a, b, c, d, e, f, g)とかになったらどーすんの。

それをいうと、funcA(a, D)でも、funcA(a, D, E, f, G...)とかになってしまう
可能性はあるわけで、その場合は、もう別物として、funcB(a, b, c, d, e, f, g)
を定義し、そのfuncBの中で、funcA(a, b, c) を利用できないかを考えてみた方がいい。

昨日も書いたように、funcA(a, D)を全面的に否定するつもりはない。メソッドの
変数が多くて見にくくなってしまうのを嫌って寧ろ積極的につかう場合もある。
 d = new D();
 d.setA(a);
 d.setB(b);
 d.setC(c);
 funcA(d);
しかし、この場合は、funcA()がDクラスに依存することが前提なのだ。はじめから
そういう関数なのである。funcA自体がDのための関数なのである。>>19 が書いている
ように、この場合はもう、Dのメンバ関数にしてしまった方がいい場合が多いだろう。


29 :先生:2007/02/06(火) 22:39:52
しかし、最初の例の場合は、説明不足だったが、もう少し全般的な関数を意識して
いる。こういった関数でどうしても引数を変更する必要がでてきた場合は、グローバル
な変数やフラグを使って無理をするより、後々を考えると、もう素直にシグニチャを
変更する道を選んだ方がいい。
それでなくともコードというものは細かい無理が積み重なって、図らずも次第に汚く
なっていくものだ。

今はいろんなツールのおかげでリファクタリングも大分やり易くなった。勇気をもって
リファクタリングして欲しい。ただそのためには、いつでも簡単にテストできる環境を
作っておくことが必要だ。え?分かってるって? すまん。

今日はこの辺で。

30 :仕様書無しさん:2007/02/06(火) 22:56:32
そんだけ汎用化したいのなら、そもそも引数じゃなくてプロパティ設定したほうが早いと思うが。

31 :仕様書無しさん:2007/02/06(火) 23:17:57
プロパティ使っちゃうと値の受け渡しが不明瞭になっちゃわない?

32 :仕様書無しさん:2007/02/06(火) 23:50:08
作成者コメントの名前が女

33 :仕様書無しさん:2007/02/07(水) 00:10:20
>>24
定義がないって意味わかんね。定義すりゃ「定義」なんじゃないの?
だいたい、「ある人が美しいと思えばそのプログラムはその人にとって美しい」
この文章自体がお前にとっての「美しさ」の定義なんじゃないの?

34 :仕様書無しさん:2007/02/07(水) 00:10:45
仕様書が美しければ、おのずとプログラムも美しくなる。

>>32
女のコードはきたねーけどな。

35 :仕様書無しさん:2007/02/07(水) 00:13:32
>>34
よくそういうレス見るけど、そんなにプログラムに近いレベルで仕様書書かれてるのか?

36 :仕様書無しさん:2007/02/07(水) 00:18:53
お客様からいただいたメルヘンチックな仕様書のことじゃないよ。

37 :仕様書無しさん:2007/02/07(水) 01:10:11
ファンタジックといいたまえ

38 :先生:2007/02/07(水) 21:21:46
>>30
ん〜、状況説明ができてなかったな。

例えば、給与計算システムのボーナス計算の処理を作っているとする。
ボーナスの計算に必要なものは、会社の売上利益、計算係数と、社員毎の勤続年数、役職、
考課結果だとする。

ここで、わざわざBonusCalculator クラスをつくって、

 BonusCalculator bonusCalculator = new BonusCalculator();
 bonusCalculator.setSeniority(year);     // 勤続年数
 bonusCalculator.setSeniority(factor);    // 計算係数
 bonusCalculator.setPosition(position);    // 役職
   :
 long bonus = bonusCalculator.calculate();  // ボーナス計算


39 :先生:2007/02/07(水) 21:22:25
...等といった使い方の設計は俺はあまりしない。なぜなら、計算に必要な情報は、すでに今作ろ
うとしているメソッドが属している、PayrollManager(給与管理)クラスなり、Staff(社員)クラスな
りに(当然)揃っているわけで、それらの情報をただパック(多量のメソッドの引数を嫌って)する
ためだけにクラスを作成するのは面倒だ(労力のわりにメリットが少ない)からだ。確かにメソッド
自体は短くなったが、その前準備のために行数が増えている。BonusCalculatorのコンストラクタ
に与えるという手もあるが、それでは本末転倒(コンストラクタの引数が多くなる)だ。
ただし、BonusCaluculatroに別の役目も与える意図があるとか、抽象クラス(インターフェース)化
して計算ロジックを切り替えるなどといった意図があればこれもありだろう。

しかし、まぁ普通はボーナス計算の処理は、PayrollManager.caluculateAllBonus() とか、
Staff.caluculateBonus()とかで実装することになる。


40 :先生:2007/02/07(水) 21:23:12
ここでは、StaffクラスにcaluculateBonus()を実装するとしたとしよう。
ボーナス計算に必要な、勤続年数、役職、考課結果は、Staffクラスのメンバ変数として既に
揃っている。しかし、売上利益と計算係数については、会社に関する(ここでは仮にそうする)属性
なので別途このメソッドに与えなければならない。そうすると、メソッドのシグニチャは、

void calculateBonus(long sales, float factor)

などとなる。繰り返しになるが、売上利益と計算係数を与えるために

void calculateBonus(Company company)

とはしない。必要なのは売上利益と計算係数だけで、会社に関する他の属性は使わないのに、
これでは大げさすぎるし、メソッド内でcompanyの属性を誤って弄ってしまう(バグを生み出す)危険
性もある。 なによりも汎用性を欠く(このメソッドの利用に常に、Companuクラスが必要になってしま
う)ことになるからだ。

んー、やっぱり、ちょっと分かりにくいし、否定していた「だらだら」感いっぱいだな。
簡潔で要領を得た説明って難しいな。すまん。


41 :仕様書無しさん:2007/02/07(水) 23:33:13
PayrollManager(給与管理)クラスが
会社の情報なり社員の情報なりを持っていても別にかまわんと思うが。
むしろ年末調整なんかの処理に拡張されたときに社員の情報(保険の額とか)を取れて便利な気がするが。

42 :仕様書無しさん:2007/02/07(水) 23:34:26
ていうか先生の言っていることはクラス設計の時点で解決しそうな気がするが。

43 :仕様書無しさん:2007/02/08(木) 00:44:30
抽象的な構造化の概念の説明からオブジェクト指向に
ジャンプするから話がこじれる。

まずfuncAが汎用である必要があるのか理解してるかどうかが重要であろうよ。

44 :仕様書無しさん:2007/02/08(木) 01:02:42
>>41
同意。
つか引数でCompanyを渡すんじゃなくて、インジェクションしとけばいいし。

45 :仕様書無しさん:2007/02/08(木) 01:03:26
>>38の例だとあきらかにDIP違反なんだけど、この先生PayrollManagerも
いちいちnewして使ってたりしないかな。

46 :先生:2007/02/08(木) 22:29:42
あー、どうも意図が伝わらないな。文章って難しいな。

上で言いたかったのは、メソッドの定義のし方(特に引数)にフォーカスした考えであって、
OOPやAOPやクラス設計とかの全体的な考え方についてはとりあえず、おいといて欲しい。
また、俺が述べている考え方も人それぞれ好みの分かれる所ではあるだろうから、別に強制
するわけではない。ま強制できないしね。

>>41の言うように、将来こんな情報も使うかもしれないなという、その時点で明確でない考えを
メソッド定義に盛り込む(得てしてその意図は忘れ去られる)よりは、実装する機能を必要最低
限なものに絞り込んで、そのメソッドの目的を明確でシンプル(細粒度)なものにするべきだと
思っている。そのためにはメソッドの引数は極力必要なものだけにした方がいい。仮に将来、
別の情報が必要な事態になったら、素直に引数を追加するなり、オーバーロードバージョン
を作るなり、その目的にそった別関数を作るなりした方がいい。


47 :先生:2007/02/08(木) 22:30:27
俺が
void calculateBonus(Company company)
より、
void calculateBonus(long sales, float factor)
の方を好む理由には、既に述べた汎用性、安全性、テスト容易性の他に、可読性に因る所
が大きい。

両者のメソッドのシグニチャをぱっと見た時に、後者の方が、そのメソッドの意図を掴み易い。
メソッド内で使われるであろう変数が想像つき易い。おそらく引数とローカル変数の他には
メンバ変数とかせいぜいその他のグローバルな変数が使われる可能性があるが、それでも
コードを読むにあたってのその想像のつき易さは大事だと俺は思っている。

前者の方は、形だけをみると引数が少ない(この場合1つ)ので、一見シンプルにみえるが、
与える情報が前者の方が多いので、メソッドで行われるであろう処理を考えると複雑になる
可能性を秘めていることが分かる。メソッド内で使われるであろう変数についての想像が深く
なりすぎる。メソッドの中身を一通り追いかけてみなければ、いったいCompanyのどの情報が
使われるのか判らない。全部なのか?、一部なのか? 仮にCompanyのプロパティなり、メソッ
ドの数が数十にもなれば、読むにあたってのストレスの度合いも増してくる。それぐらい、メソッド
のシグニチャとは、自己文書化の性質を備えたものだと思っている。(コメントやアノテーション
の利用は別問題。)


48 :先生:2007/02/08(木) 22:31:16
確かに柔軟性で見た場合、前者の方が将来の漠然とした可能性に対して柔軟かもしれない。
また、規律が緩い分、余計な配慮がいらずお手軽ではある。しかし、それでもCompanyの管轄
外の情報が将来必要になる可能性はどちらにしても残る。そして俺はそういったメソッドの曖昧
で無責任な柔軟性より、可読性やシンプルさを重んじる。メソッドに必要以上の情報を与えない
ことが、将来に渡ってメソッドの中身が徒らに長くなったり、だらだらと書かれるのを防ぐための
一つの実践だと思っている。同じ目的を達成するなら、一つの長いメソッドより、役割の明確な
コンパクトなメソッドの組み合わせの方がいい。過渡な情報は混沌を生みやすい。混沌とした世
界に秩序をもたらし統率するのは全能たるプログラマ(or 設計者)の責任だ。

ただし、もちろん状況や設計方針でこの辺は変わってくる。例えば、イベントハンドラを定義する
場合、イベントの処理内容は実装者にオーバーライドされることが前提なので、ハンドリングのた
めの十分な情報を与えてやる必要がある。その場合は、bonusCalculatingEvent(Company, ...) な
どといった形での引数が妥当になるケースも多い。他にもこういうケースはある。が、これらは設
計目的の異なるケースであって、俺が設計やコーディングする上で基本的に念頭に置いている
のは、上で述べているような考えだ。あくまでメソッド(関数)定義と引数の話ね。

人によってはこういった話って当たり前すぎる話なんだけど、まぁそうでないソースもよくみかける。
長文、すまん。


49 :仕様書無しさん:2007/02/08(木) 23:49:21
>>48
つか、メソッドの引数としてわたすものはなんつーか「スレッド固有の情報」に限定すべきじゃなかろうか。
だから、PayrollManagerがボーナスの計算をする際にCompanyの情報が必要になったからといって
calculateBonusメソッドの引数にCompanyを追加するのは誤りだと思う。

50 :仕様書無しさん:2007/02/09(金) 01:37:16
それは
結合度を低く保て
という一般原則の適用と何処が違う?

51 :仕様書無しさん:2007/02/09(金) 18:02:56
だめだなー

美しくなるっていったらやっぱお化粧だろ?
ちゃんとディスプレイにファンデーションを塗って・・・

52 :仕様書無しさん:2007/02/10(土) 13:23:25
なにこの長文先生
まるでおじゃばだな

53 :仕様書無しさん:2007/02/10(土) 13:30:08

短文ばか

54 :仕様書無しさん:2007/02/10(土) 13:32:49
俺ルールの説明に冗長な長文を必要とする馬鹿よりは
短文馬鹿のが2chでは好まれるという現実

55 :仕様書無しさん:2007/02/10(土) 13:44:51
短文も積もり積もって長文になるわけだし、嫌なら読まなきゃいいじゃん。

56 :仕様書無しさん:2007/02/10(土) 14:02:00
( ´-`)=3

57 :仕様書無しさん:2007/02/10(土) 14:38:03
BeckとFowlerは著書『リファクタリング』の第3章
「コードの不吉な匂い 」の中で次のように述べているよ。

---------------
しかし、オブジェクトという考え方が導入されたことで、
状況は変わってきました。必要なデータは、オブジェクトに
問い合わせればいつでも手に入るようになったからです。
オブジェクト指向では、メソッドの実行に必要なデータを、
すべて引数にして渡したりはしません。オブジェクトを
そのまま渡し、メソッドがさまざまなデータをそこから
取り出せばいいのです。
---------------

ただ、そうはいっても、
>>47
>void calculateBonus(Company company)
の例だと、Companyクラスの粒度によっては、そのまま
オブジェクトを渡すことは、依存関係の観点から好ましくない
場合もあるかもしれない。

>void calculateBonus(long sales, float factor)
逆にこちらの例では、関数に渡す引数の数が増えてきたり、
別のメソッドでも同じようにsalesとfactorのペアを渡して
いたとしたら、sales、factorの情報を持つクラスを
新たに導出することを考えたほうがよさそう。

結局、どちらのやり方がいいかはケースバイケースなのでは。

58 :短文先生:2007/02/10(土) 19:46:27
どうも、先生改め短文先生です。
長文の反省と自戒の念をこめて短文先生と改名することにした。

>>57
そうね、まぁケースバイケースっちゃぁそうだが、仮に新たなクラスを導出するんだったら、
いっそのことその導出したクラスに、calculateBonus()メソッドも移しちまうかもしれないな。

おっと、今日はここまで。

59 :仕様書無しさん:2007/02/10(土) 19:58:50
短文て名乗って3行以上はありえんやろ
半年ROMれハゲ

60 :仕様書無しさん:2007/02/11(日) 00:15:07
何も書かない

61 :仕様書無しさん:2007/02/11(日) 02:11:27
http://www.amazon.co.jp/dp/489100455X/
Code Complete第2版〈上〉―完全なプログラミングを目指して
http://www.amazon.co.jp/dp/4891004568/
Code Complete第2版〈下〉―完全なプログラミングを目指して

プログラムのうまい書き方がキッチリと紹介されています。

個人的にはコメントの付け方がうまい人のコードは美しく見えると思います。
=読みやすくしてくれているからかな?

62 :仕様書無しさん:2007/02/11(日) 06:14:39
ソース読みやすいっていうのは開発者側から見ると美しい
プログラムという観点からすると処理速度とかメモリとかを気にして書いてるものが美しい
モバイル系とかだと容量削減にも気を遣いつつ処理速度も気にしてかいてあるものが美しい
という感じで各視点毎に美しいの定義は変わってくると思う
最近はマシンの性能も上がってることもあり何も考えないスパゲッティーソース書く奴が多くて将来不安だわ

63 :仕様書無しさん:2007/02/11(日) 12:52:04
>最近はマシンの性能も上がってることもあり何も考えないスパゲッティーソース書く奴が多くて将来不安だわ
×最近は
○かなり以前から

64 :仕様書無しさん:2007/02/11(日) 12:53:38
>>61
「マコネルにとってのうまい書き方」に過ぎない

65 :仕様書無しさん:2007/02/11(日) 13:15:29
ある程度万人向けとなると、自然と簡単なプログラムにならざるを得ない。

66 :仕様書無しさん:2007/02/11(日) 13:27:10
生産性を落としてまで万人向けに書く意味がわからない。
四則演算だけつかって使って説明すれば、小学生でも高度な数学の定理が理解できるかどうか
考えてみればわかるはず。

67 :仕様書無しさん:2007/02/11(日) 13:27:23
やっぱり読みやすいのが一番だろうね。

1.変数のネーミングが的確
2.関数の大きさが適量
3.ネストが深くない

68 :仕様書無しさん:2007/02/11(日) 13:33:25
>>64
ピッチャーで言えば、直球のコントロールは基本。
でなきゃ変化球投げてもストライク取れないよ。

オーソドックスな書き方ができない奴が、いきなり自分流にアレンジすると、他人には読みにくい汚いコードになるな。
俺は厚化粧のブスよりすっぴんの美人を選ぶ

69 :64:2007/02/11(日) 13:59:35
>>68
あの本は「マコネルが『これがオーソドックスだ』」と言っている本だろ。
貴方がマコネルの主張を支持するのは勝手だけど、
全員がその主張を受け入れるとは限らないだろ。

「マコネルがオーソドックス」という前提そのものが違うと言っているのだが。

70 :仕様書無しさん:2007/02/11(日) 16:28:52
>>69
>全員がその主張を受け入れるとは限らないだろ。
マコネルも本の中でそう言ってるよ。

とりあえず今のコーディングスタイルで苦労してないなら、押し付けはまっぴらゴメンだね。w
我流で行き詰まった時、他人のやり方を参考にしてみればいいかな?

何かおすすめありますか?特にない?
何かあったら紹介して

71 :64:2007/02/11(日) 17:11:14
>>70 具体的には自分で調べてください
カーニハン、クヌース、プローガ、マイヤー、ファウラー 等
もちろんマコネルもいるけど
#年齢がばれるかなorz

72 :短文先生:2007/02/11(日) 20:10:53
>>59 2行じゃ俺の文章力じゃきびしいな。ちょっと我慢してくれ。

俺は、日本で不当に扱われるプログラマの地位を向上させるためには、プログラマが
自分の仕事にもっと誇りと自信を持つ必要があると思っている。プログラミングとは本
来もっと楽しくやりがいのある作業であるはずで、上級職(といわれる職種や役職)から
敬遠されるような、雑多で面倒くさい力作業ではないはずだ。プログラマという職種に
プライドをとり戻すためには、多くのプログラマがきれいなコードを書く最低限のスキル
を身につける必要があると思っている。現状を招いた「動けばよい」という古き悪しき慣
習を払拭しなければならない。・・・と長くなるな。えーと、今日はちよっと趣向を変えて。


73 :短文先生:2007/02/11(日) 20:11:45
下のcheckErrorメソッドは引数のvalue値の妥当性(長さ)を検査し、結果を返すメソッド
だが、俺が好ましくないと思う点が3箇所ある。(言語はJava)

public class SomeClass {
 private String value;
 :
 public boolean checkError(String value) {
  if (value != null && value.length() <= 10) {
   this.value = value;
   return true;
  } else {
   return false;
  }
 }
}

続きは今度。中文先生にしとけばよかったか・・・

74 :仕様書無しさん:2007/02/11(日) 20:36:44
好ましくないというか

>   this.value = value;

なんて評価に値しないだろ

75 :仕様書無しさん:2007/02/11(日) 21:05:55
>>73
>中文先生
中国語でおk

76 :仕様書無しさん:2007/02/11(日) 23:52:23
だから、なんも書かなきゃいんだよ
短文先生が短文にできないように、プログラムもだらだらと長くなってしまうだろ?

77 :仕様書無しさん:2007/02/12(月) 01:38:03
64みたいな間抜けは失せろ。

78 :仕様書無しさん:2007/02/12(月) 01:46:33
>>73
誰か答えろってことなのかな?じゃあ…

(1)checkErrorという名前が悪い。
isValid とかにすれば戻り値の意味が分かりやすくなる。
(2)this.value への保存が変。
>>74も書いてるが。
そういう機能が必要だとしてもチェック用メソッドとは別にすべき。
(3)マジックナンバー10の意味が分からない。
変数名かなにかでわかりやすくすべき。

79 :仕様書無しさん:2007/02/12(月) 02:36:40
メンバと引数が同じ名前なのがダメと言ってほしいんでは。
同じだからthisつくわけで。

メンバにm_って全部つけるのはもう流行らないらしいが、いまどきは
どうしたもんなのかね。

80 :仕様書無しさん:2007/02/12(月) 02:49:18
this.value への代入がないとして。

if 文で判定した結果を return するのと、直接 return するのと、
どっちがいいんかね?

return value != null && value.length() <= 10;

みたいな感じで。

81 :仕様書無しさん:2007/02/12(月) 03:08:16
78も書いているけど・
チェック機能とSetterが同一メソッドであるのが気に入らないなぁ

82 :短文先生:2007/02/12(月) 22:20:56
>>78 ご名答! しかも簡潔で的を射た回答。すばらしい。弟子にしてほしいくらいだ。

改めて説明する必要はないかもしれないが、それでは俺の立場が無いので・・・
まず、前にも書いたがメソッドのシグニチャは自己説明的であるべきだと思っている。
その意味では、checkError という名前はその目的を明確には示していない。この類の
安易なネーミングはよくみかけるが、これでは結局コードをみないと、何の処理をし、何
を返すのか想像しにくい。 >>78の示したような名前付けが妥当だろう。ここではもう少し
説明的に、isValidLength としよう。


83 :短文先生:2007/02/12(月) 22:21:52
次に、このメソッドは本来、引数の妥当性を検査するものであるはずなのに、メンバ変数
への代入という他の役割も兼任させてしまっている。つまりコネコネと粘土状態になってい
るのだ。変数への代入は、void setValue(String value) という別のレゴブロック(まぁこの場
合は単なるセッターだけど)を用意するべきだ。そして、呼び出し側で、
if(someObject.isValidLength(value)) someObject.setValue(value);
と書くべきだ。
もしどうしても検査と代入を兼任させなければならない状況(望ましくはないが)が発生した
場合は、checkLengthValidationAndSet(String value) 等といったその目的に適した名前付け
(このネーミングセンスはともかく)のメソッドを用意し、その中で、
if(isValidLength(value)) setValue(value); を記述すればよい。

84 :短文先生:2007/02/12(月) 22:22:46
リテラル値については特に説明の必要はないだろう。
ということで、リファクタリングバージョンは以下のようになる。(コメントを省くなど意図的に端
折った書き方をしているが、もちろんコメントは書くべきだ。)

class SomeClass {
 public static final int MAX_LENGTH = 10;
 private String value;
 :
 public static boolean isValidLength(String value) {
  return (value != null && value.length() <= MAX_LENGTH);
 }
 public void setValue(String value) { this.value = value; }
 :
}

85 :短文先生:2007/02/12(月) 22:23:32
isValidLength()は、インスタンス変数との関連がなくなったのでクラスメソッドにしたが、この辺
の判断は、状況や設計方針、好みで変わってくるだろう。また、valueがnullの場合は、trueとす
る判断もあろうし、例外を投げるパターンもあろう。仕様によって変わってくる。そしてそういっ
たことはコメントで明記すべきだ。

ネーミングはコードの読み易さにかなり影響を与える。そういう意味ではプログラマにとって基
本的な英語能力は必須だといえる。まぁ俺の場合は都度辞書で調べていたりするんだが。
SomeClass というネーミングも本当はよくない。何故ならClassが冗長だから。
今日はここまで。というか、ちょっと仕事が忙しくなりそうなので気が向いたらまた書く。

86 :仕様書無しさん:2007/02/12(月) 22:29:35
短文の解説は読まなくても>>78を読めばOK

そういうことですね

87 :仕様書無しさん:2007/02/12(月) 22:38:04
もうちっとだけレベル上げていこうぜ。
>>85くらいのことが分からないのは、頭の良し悪しとかセンス以前に
単純にプログラミングそのものに興味がないってことだと思うから。

88 :仕様書無しさん:2007/02/12(月) 23:31:24
やっぱクラスとか関数同士の結合が小さいプログラムが
美しいかな。。。

89 :短文先生:2007/02/13(火) 00:26:58
みんな!先生とHしないか?

90 :短文先生:2007/02/13(火) 00:31:57
先生な。みんなの事、平等に好きだからなっ。

91 :仕様書無しさん:2007/02/13(火) 00:51:00
>>85
酉つけろ酉

92 :短文先生 ◆adhRKFl5jU :2007/02/13(火) 01:05:50
つけたお!

93 :おじゃわさま:2007/02/13(火) 08:12:10
ここレベル低いな
楽しいわい

94 :おじゃわさま:2007/02/13(火) 08:16:38
俺だったらisLengthというJNI外部関数作ってlenの戻り値がintだから
常に負の値を返してあげると楽しいな。unsignedが無いジャワならではの
楽しみ。

95 :64:2007/02/13(火) 14:47:08
>>71
把握した!
Thank you

96 :短文先生:2007/02/13(火) 21:12:01
先生、みんなと仲良くしたいんだ
だから、いつだって先生の胸に飛び込んでいいんだぞっ

97 :仕様書無しさん:2007/02/13(火) 21:36:00
うほっ

98 :仕様書無しさん:2007/02/13(火) 22:02:09
お尻の穴に飛び込んでもいいですか。><

99 :仕様書無しさん:2007/02/13(火) 22:14:24
学習塾のバイトはロリコン&ショタコンは禁止ですねw

100 :仕様書無しさん:2007/02/13(火) 23:46:06
俺、ここに書かれてる技術的なこと殆ど理解できないんだけど、
こういう事を語れるおまえらが羨ましい


101 :仕様書無しさん:2007/02/13(火) 23:52:21
>>100
俺らはお前と違って、プログラム書く以外に趣味持たないからな。

102 :仕様書無しさん:2007/02/13(火) 23:53:59
一緒にするなよw

103 :仕様書無しさん:2007/02/13(火) 23:56:40
つーかそんな人生はイヤだ

104 :仕様書無しさん:2007/02/14(水) 00:08:29
俺はプログラム書かないけど、この板にいる。

105 :仕様書無しさん:2007/02/14(水) 00:11:13
なんで?

106 :仕様書無しさん:2007/02/14(水) 00:13:02
別にいいじゃん。俺も数学のこと何にもわかんないけど数学板とかいくよ?

107 :仕様書無しさん:2007/02/14(水) 00:14:37
悪いなんて言ってないよ。何でなのか興味があるだけ。

108 :仕様書無しさん:2007/02/14(水) 00:28:53
何となく興味があるから。

109 :仕様書無しさん:2007/02/14(水) 02:09:39
マ板はいろいろ面白いからな。デスマーチの話とか。
ム板にいってプログラムしないとかなると嵐以外考えられんけど。

110 :仕様書無しさん:2007/02/14(水) 02:26:21
空気を読まないレスさえしなければ別に居てもいいと思うお^^

111 :仕様書無しさん:2007/02/14(水) 08:43:34
以前、プログラマーになろうと思っていたけど、友達からプログラマーだけはやめとけ
と言われたので、やめた。

だから一応、興味があって見ている。

112 :仕様書無しさん:2007/02/14(水) 10:18:27
じゃあプログラマだけど空気を読まないレスしかしない俺は?

113 :仕様書無しさん:2007/02/14(水) 20:51:55
マ板、ム板ってなんですか?

114 :仕様書無しさん:2007/02/14(水) 20:54:59
マ板 -> プログラマ板
ム板 -> プログラム板

115 :仕様書無しさん:2007/02/14(水) 22:33:56
つ 構造化

116 :短文先生:2007/02/15(木) 01:11:38
荒れてるな・・・。お前ら荒らすなよ。 >>89-90>>92>>96 は俺じゃねぇぞ。

今日はちょっと長文なので怒られないようにこそっと書く。

>>87 いや、俺はもともと初心者向けに説明したかったんで、これ以上レベルを上げる
つもりはない。(上げたくても俺の手に余るっつうのもあるが) 俺の話は恐らく上級者に
は退屈だろう。しかしそういう人でも、身近のソースをみると、1つのメソッドに役割を粘
土状に兼任させてしまっているケースというのは結構あるんじゃないかと思う。そしてこ
れこそが、きれいなソースと汚いソースを隔てる分水嶺なのだ。ここが改善されるだけで、
世に蔓延る汚いソースの多くが大分きれいになってくれるんじゃないかと思っている。

117 :短文先生:2007/02/15(木) 01:12:16
何故汚いコードが書かれるのか、何故適切にメソッド分割されないのか、その大きな原
因の一つとなっているのが、日本人にとっての英語なんじゃないかと俺は考えている。
その話はこの後するが、コードを書いていて、メソッド分割を躊躇させる要因として、以前
書いた引数の検討に加えて、ネーミングの煩わしさがある。既に手元に必要な情報が揃っ
ているのに、なぜわざわざわざ面倒な名前付けをしてメソッド分割しないといけないのか
と考える人が多いのだ。だらだら書くのは確かに楽なのだ。人は楽な方へ行きたがる。
特に納期に追われ気持ちに余裕が無い時は。

118 :短文先生:2007/02/15(木) 01:12:55
例えば、英語を母国語とする人達はメソッドを定義する時、恐らく我々日本人が、

買い物に行く(財布、買い物かご)

と書くぐらい(に近い)の気楽さで定義できるんじゃないかと思う。しかし我々がプログラミン
グする場合、このせっかくの思考を兎に角も英語(又はローマ字)に変換しなければならない。
goShopping ( ときて、えーと財布って英語でなんだっけ・・となる。結構面倒臭いのだ。これ
は我々にとっては大きなハンデだと思う。プログラミング言語が英語由来である以上(そして
実際、相性もいい)、仕方のないことではあるが、この英語という壁が、きれいなコードを書く
上で我々の前に立ちふさがる。メソッド定義を面倒なものにさせ、粘土細工に走らせる大き
な原因の一つとなっている。中には英語なんぞお構いなしに kaimonoNiIku(〜等とする兵も
いるが、それはそれでメソッド分割しないよりはよっぽどいいと思う。

119 :短文先生:2007/02/15(木) 01:13:35
ネーミングの際に感じる煩わしさについては、メソッド名に限らず、変数名、クラス名など
についても同じだ。そしてそのために、errorFlagとか、checkError等といういかにもなダサ
い無意味な名前が世を闊歩することになるのだ。しかし、ここを面倒臭がってはいけない。
プログラミングを続けていると次第に分かってくると思うが、例えばメソッド名は動詞、或い
は動詞と目的語の組み合わせで大概なんとかなる。そして普段メソッド名に使う動詞の種類
は実はそれほど多くはない。is, has, set, get, create, generate, make, cut, setup, calculate,
move, copy, read, load, find, search, write, save, add, remove, modify, insert, update, delete,
restore, show, view, retrieve, push, pop, put, collect, sort, send, receive, ・・・結構あるな。ま
だあるか、でもせいぜいそんなもんだ。基本的な動詞だけだ。あとは業務独特の動詞類とか
だろう。そしてあとはこれに目的語をつなげて、calculateBonusとか、findGirlとか、saveMoney
とかするだけだ。或いは応用して、findBeautifulGirlとかgetMoneyByForceとかするだけだ。

120 :短文先生:2007/02/15(木) 01:14:23
慣れてしまえば意外と簡単なものだ。もし分からない単語がでてきたら、辞書でひけばいい。
今は手軽にネットでもひける。言わばプログラミングとは無の世界に創造主たるプログラマー
が適切な言葉を創造しその言葉に意味を与えていく作業ともいえるのだ。
前回の例題の本当の狙いも実はそこにあった。メソッド分割の大切さを、とりあえずそこだけ
は理解して欲しいと俺は切に願う。メソッド分割をすることは慣れてくると楽しい作業でもある。
今まで述べた有益性はもちろん、将来も含めて自分の、或いはそのソースに関わるであろう
全ての人のための、ひいては全てのステークホルダーが幸せになるための作業なのだ。そし
てその結果は巡り巡って必ず自分に帰ってくる。おまけに英語の語彙力もつく。一石二鳥どこ
ろではない。目先の楽な道に走ってはいけないのだ。

121 :短文先生:2007/02/15(木) 01:17:41
・・・と、とりあえず俺が書いておきたかったことは大体書いたから、もう書かないかもしれな
い。気が向いたら書く。ひとまずお付き合いいただいた方には感謝。俺が偉そうに言えた義
理ではないけれど、美しいソースを書くのに必要なことは、プログラミングに関する好奇心と
向上心。そして他人への配慮だと思う。汚いソースというものは結構迷惑なものなのだ。俺は
犯罪に近いものだとさえ思っている。(汚い長文も・・・とつっこもうとしているお前。すまん、許
してくれ。)美しいプログラムとはバグのないプログラムのことではない。(いやそれも大事だ
が)また、殊更にテクニックに走ったプログラムのことでもない。仮にバグがあったとしてもその
原因を特定し易く、対処し易く、そして拡張し易いプログラムのことだ。

ということで、健闘を祈る。いやぜひ健闘してくれ。

122 :仕様書無しさん:2007/02/15(木) 01:24:10
違うテーマでも書いてみて欲しい。

123 :仕様書無しさん:2007/02/15(木) 02:55:46
・・・いや、言っていることは概ね同意なんだけど。
それはクラス単体という粒度水準以下のことしか
述べていないね。

124 :仕様書無しさん:2007/02/15(木) 14:12:00
適切なクラス分割も大切だな

125 :仕様書無しさん:2007/02/17(土) 12:08:16
こういうことって、誰かが教えりゃ簡単に理解できそうなもんだよな。
なのに、わかってる人はホントに少なくて、汚いソースが世にはびこる。
新人とかに教える側もこういうことわかってないから、教えられない。
その結果、ただ動くだけのコードしか書けないプログラマーの拡大再生産が進むわけだ。


126 :仕様書無しさん:2007/02/17(土) 19:07:03
マコネルの本に大半のプログラマは年に1冊もプログラムの本を
読まないって書いてたよ。
誰かが教えるために努力を無駄にしてるだけだろう。

127 :仕様書無しさん:2007/02/17(土) 20:03:21
はい、みなさん>>126に注目!
汚いコード書く人の見本ですwww

128 :仕様書無しさん:2007/02/17(土) 20:38:37
教えるための努力を大勢が無駄にしてるだったな。

129 :仕様書無しさん:2007/02/17(土) 23:42:08
>>126>>128の意味がよくわからない。

130 :仕様書無しさん:2007/02/18(日) 06:22:26
>>127に解説してもらったら?

40 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)