Togetter/min.tを安心してお使い頂くためのガイドラインを公開しました。
編集可能
2014年5月19日

単一責務原則(SRP)から始まるFPとOOP

まとめました。
13
uehaj @uehaj

単一責務の原則を疑いたい。ListにeachがあるのはSRP違反だ。で、なにがわるいのだ。クラスこなごなにして可読性理解性を悪化させる例も多い。

2014-05-16 22:37:17
uehaj @uehaj

"クラスに変更が起こる理由は、一つであるべき"の意味がわからん。未来に発生するであろう仕様変更の理由を、予測し、一個になるようにしろってこと?? いや機能拡張については無数だろ。変更理由が一つにだったように事後的にクラス分割せよ?

2014-05-16 22:48:13
uehaj @uehaj

変更があったとき、"変更理由が一つにだったように事後的にクラス分割せよ?"そうならその方針はむしろ酷く激しいクラス分割を不断に引き起こすような。単一クラスの範囲内でのみ変更が起きないこと、というのを重視するが分割は変更とみなさないのかな

2014-05-16 22:52:56
uehaj @uehaj

一般論的に、明確な債務がひとつであれというのは分かるし、直感的に正しい。しかし変更理由が一つというのは、分からんし、なんだかなと。よく引き合いに出されるモデムの例でも、コネクションの変更と送受の変更が別だからクラス分けろとある。

2014-05-16 22:58:02
uehaj @uehaj

純関数型スタイルが単一責務原則の極致なのは明らか。なにしろ状態の保持責任と、処理の責任が強制分離されるから。クラスがばらばらになって余分な名前やソースファイルが増えることなく徹底できる。

2014-05-17 08:41:18
uehaj @uehaj

まあ思うに、単一責務原則というのは、機能拡張や変更に対して、既存クラスを変更するのではなく、単調増加的な新規クラスの追加のみで目的が達成されるような作りになっていること、だの。

2014-05-17 08:57:00
uehaj @uehaj

言い直し。単一責務原則というのは機能拡張については新規クラス追加のみで、仕様変更に対してはその変更理由の階層的構成に対応するそれぞれのクラスの変更のみで目的が達成されるような作りになっていること、かね

2014-05-17 09:09:21
Kota Mizushima (on a diet) @kmizu

@uehaj 朝から唐突にすみません。「純関数型スタイルが単一責務原則の極地なのは明らか」というのがよく理解できなかったです。「純関数型スタイル」というのはテクニカルには副作用を一切利用しないプログラミングスタイルのことだと理解していますが、単一責務原則がどうつながるのか

2014-05-17 09:12:03
Kota Mizushima (on a diet) @kmizu

@uehaj それがよくわかりませんでした。

2014-05-17 09:12:13
uehaj @uehaj

@kmizu すみません、まず本来Srpはクラスという単位の分割粒度方針に関するものです

2014-05-17 09:16:24
uehaj @uehaj

@kmizu その前に、用語がおかしかったので訂正。状態更新を行わない、純粋関数のつもりでした。外界との更新がないことの意味ではないです

2014-05-17 09:20:09
Kota Mizushima (on a diet) @kmizu

@uehaj はい。SRPについての理解はたぶんそんなにずれていないと思います。

2014-05-17 09:23:51
Kota Mizushima (on a diet) @kmizu

@uehaj 次、こちらなのですが、状態更新は行わないが、外界との更新があるというのは、いわゆるファイルI/Oなどは行うが、プログラム状に陽に現れる変数の書き換えは行わないという意味でしょうか?

2014-05-17 09:24:50
uehaj @uehaj

説明のし方を変えますね。mutableなフィールドを持ち、メソッド呼び出しを通じて状態更新を行うクラスは、メソッドが行う処理を遂行するという債務に加えて、状態を保持・更新する責任を負います。少なくとも二つの債務がありSRPに反します

2014-05-17 09:40:57
uehaj @uehaj

そのようなクラスは状態の保持だけを行うデータクラスとそのクラスを引数とし、引数を変更した新しいデータクラスを返す関数に分離することで単一債務原則をより厳密に満たすようにすることができます。後者はいわゆる関数型の考えだと思います。非OOPという意味の"純粋"関数型というか

2014-05-17 09:47:39
uehaj @uehaj

引数データを破壊的に変更しても粒度の問題としては構わないですね。となると、メソッドをstaticにして、第一引数にthisを明示化するのと(vtableベース継承ができなくなることを除き)同じなので、メソッド置場だけの問題

2014-05-17 09:57:22
uehaj @uehaj

@kmizu SRPの徹底と、メソッドはデータに従属せよというOOPドグマはたぶん本質的には対立するのです。SRPのためにクラスという単位を際限なく細分化し、static多用するぐらいなら、関数型の方がスッキリできる。

2014-05-17 10:09:27
Kota Mizushima (on a diet) @kmizu

@uehaj うーんと、OOPのドグマ「メソッドはデータに従属せよ」にしたがったとして、引数を破壊的に変更せず、新しいオブジェクトを生成して返せば良いだけでは?そして、それは机上の空論ではないし、(特にScalaで)実際に行われてもいます。

2014-05-17 10:12:01
Kota Mizushima (on a diet) @kmizu

@uehaj そして、Scalaのセントラルドグマ「OOPとFPは対立しない」というのは、FPは単にデータの副作用が無いことをいっているのであって、OOPは単にメソッドはデータに従属せよということを言っているに過ぎないので、両者は直行しており組み合わせることは可能だと思います

2014-05-17 10:13:53
Kota Mizushima (on a diet) @kmizu

@uehaj こないだスライド出てましたけど、Oderskyの主張もそんな感じです。

2014-05-17 10:14:09
uehaj @uehaj

.@naka_aki_spl それはそうでふね。目的の記述粒度、もしくはその捉え方は恣意的です。相対的な話です。

2014-05-17 10:17:30
uehaj @uehaj

.@kmizu 並存はできるでしょうね。Java'の側から、状態更新とインスタンスメソッドは必要悪ぐらいなかんじを経由して、もっとぐいっとダイヤルひねるとscalazまでいける。でもそれは対立軸とも見ることもできる、ゼロサムゲームなのでは?

2014-05-17 10:27:19
Kota Mizushima (on a diet) @kmizu

@uehaj うむむ。何か認識にずれがあるような。インスタンスメソッドは必要悪ではなく、インスタンスメソッドは状態を変更する代わりに状態を変更した新しいオブジェクトを返すものだ(副作用がない)、というのがScalaの言っているOOP/FPだという話なのですが。

2014-05-17 10:31:49
Kota Mizushima (on a diet) @kmizu

@uehaj インスタンスメソッド=状態を変更するもの、とそもそも発想しないということです。で、実際、OOPを形式化するときはそういうか形の発想を行います。

2014-05-17 10:32:32
uehaj @uehaj

.@naka_aki_spl その話題は本来つ、closなのですが、selfやthisをあんまり特別視しない方が視野が広がる気がしています。Pythonえらい

2014-05-17 10:32:48
残りを読む(62)

コメント

Tsuyoshi CHO @tsuyoshi_cho 2014年5月20日
OOPであることと、実装での利便性での継承やポリモーフィズムやらはまた別な気がするが...
0