カプセル化は愚かな考え
■ このスレッドは過去ログ倉庫に格納されています
■危険性
かつて偏差値の低い学校向けの情報処理系教科書において「カプセル化は大変すばらしいものであり絶対に使うように」と大体的に宣伝された。
一方、カリフォルニア大学バークレー校の有識者を中心とした「インターネットを作った人たち」は「階層化の有害性(RFC 3439)」として「カプセル化は絶対にやめろ」としている。
大雑把にいうと、教科書の上では素晴らしく、開発を始めた最初のうちは良いが、将来的な改修の際に隠蔽されたデータにアクセスできないと解決できない問題が出てきて、非常に高確率でデスマーチに陥るというのである。
オブジェクト指向の発案者であるアラン・ケイもコーディング規約(頭文字にアンダースコアを付けるなどの命名規則)で縛る程度にすることを推奨しており、アラン・ケイが関わったオブジェクト指向プログラミング言語にはどれも「private」などという概念はない。
ソースコードが存在し改修が可能であればカプセル化しても問題ない。ソースコードがあってもライセンス的に改修できない場合や、そもそもバイナリのライブラリしかない場合などは絶望的である。
https://monobook.org/wiki/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0) >>90
素人が手を出したら
OOPの恩恵に預かるよりもむしろ糞の山を量産するからね
これは素人が悪いとか
あるいは誰かの力量を疑うようなことを言いたいんじゃなくて
クラス設計インタフェース設計の根本的な難しさを問題にしてる >>86
エラーハンドリングが必要だから現実のコードだと影響与えるような気がしないでもない
それは良いとしてこのコードを見るとJavaって大変だなぁって感じる
構造体がない
0~255を表現できる標準の型がない
オプショナルパラメータがない
オブジェクト指向への不満度の高さと使ってる主な言語には相関関係ありそう 現実問題としてオブジェクト指向は避けられない
ライブラリがオブジェクト指向前提なってるから…
数十個のメソッド継承したデブっちょクラスを前に
わけわかんねーってなる(←ポンコツですみません) >>94
ぶっちゃけ使うのはいいがお前は作るな!が言いたいことだよ。 このメソッドはこのクラスから継承と
書き出してみればわかると思うよ
たくさんのライブラリがあって
どのライブラリのどの関数を使うというのと
本質的に同じ問題だから >>88
んなの、オブジェクト指向以前の問題だろ。 staticおじさんを全面肯定するわけではないが擁護するわ
インスタンスを生成するタイプのクラスは
本当はかなり作るのが難しくて
高度な設計技術と計画性を要すると思う
そういう意味ではstaticおじさんは自分の力量を弁えていて
賢明だと思う
インスタンスを作るタイプのクラスをそうそう
乱発製造すべきではないと思う >>103
自分の力量?
同僚の力量も考慮に入れろよ オブジェクト指向の考え
オブジェクト内に状態(フィールド)を持ったり
オブジェクト内の状態を内部で操作するような
処理は外部から勝手に操作されると
不具合の元だから隠蔽しないといけない
(でも操作したくなることもあるから
ゲッターやセッターを作る)
しかし、オブジェクト指向の一番の問題点は
隠蔽さえすれば、状態をもつたり、
内部状態を操作する行為自体は許容してるという点。
staticおじさんや純粋関数型プログラミングの考え方
そもそもオブジェクト内に状態を持つこと、
内部状態を操作すること自体がシステムがめんどくさくなったり
不具合の原因なんだから、そんなこと自体極力やめた
方がいい。という考え方。
クラスにやたらめったらフィールドを定義するから
それらの管理が大変になるんでしょ?
じゃあそもそも不必要にフィールドをたくさん定義するのは
やめようってこと。 >>105
結局グローバル変数の弊害と変わらないってわけだ
イベント駆動プログラムにはオブジェクト指向が向くとされてるから
現在主流の言語はほぼオブジェクト指向になってしまった
オブジェクト指向を避けてイベント駆動を実現できればなあ… >>103
static変数を使わないつくりにすることがstatic変数使う場合に比べて難しいというのは
あんまり納得しないがな。
確かに既存コードがどこで変更が起こってるのか全く分からん場合には仕方ない時もあるが。
>>108
同じようなところもあるがさすがに数百万行のコードになってくると、グローバルとメンバ変数じゃ
負担はだいぶ違うよ。 staticなら何の問題も起きないのにバカがメンバに持つ カプセル化が不十分というだけ。
XNA は使い方を間違えている。 そもそも処理を仕方がない理由もなく
入力→処理→出力
で入力と出力でチェックできない形にしてしまうのは悪手 >>109
static変数なんてものももちろん使わない
staticおじさんへの批判が的外れになるのもこれが原因
「staticメソッドしか定義しない」 そもそもJavaScriptや
python使ってると
「あれ?クラスって必要なくね?」
って思うことが多いよ
(クラスというかフィールドやコンストラクタや
インスタンス化の必要性)
複数種のデータをセットで持ちたいなら
連想配列や辞書で持てばいい話で
クラス型なんて無名で言いじゃん。
JSONやローカルストレージやDBなど
格納方法には色々選択肢があるわけで
連想配列を引数に与えてやりとりすればいい
もちろんJavaだとMapのキーと値にも
型の宣言が必要で不便だから
JavaScriptやPyを使ったほうがいいね Hooks API来てから皆Function Component。誰もClass Componentつかわなくなった@React privateとかpublicじゃなくて775とかパーミッション設定したい。 >>114
もともとの議論知らんのならだまってりゃいいのに。
あきらかに元ネタはstatic変数を使ってシングルトンやることをマンセーしとるわ。
クラス使えばいいってもんじゃないが、結合時のバグを気にしすぎてテストしずらい構造つくってるってのが
この手の問題なわけよ。 別に論破はされてないなぁ
要するにデータをどう持つかの話で
データが必要なものはオブジェクトに持たせたほうがいいし
データが必要ない(引数程度)ならstaticにすると言うだけの話
この「引数」はシンプルな値型に限る。
いやだってstaticにするために引数にしてデータを持たないオブジェクトにしたのに
データを持つオブジェクトを渡すとか本末転倒やろ?w
ようはデータが有るかどうかって話で、ないならstaticでいいけど
あるなら普通にオブジェクトにしましょうってだけ
データが有るのに頑張ってstaticにするとか無駄 ケースバイケース、適材適所で設計すれば良いというだけの話なのにね。
教条主義、原理主義の奴らは必ず◯◯すべし!◯◯すべからず!と声高に叫んでるだけでまともな議論にはならないし、スルーするのが一番かと思われる。 >>123
お前が言ってるのはjavaのstaticの方な。
もともとのstaticおじさんはcの話をしてる。 >>125
staticおじさんはjavaのstaticな >>119
chmodとかで設定するパーミッションな。
↓こんなイメージ。
664: // 基底クラスと派生クラスが読み書き可能。その他はよむことだけOK。
int a;
640: // 基底クラス読み書き可能。派生クラス読み込み可能。その他はアクセス不能。
int b; >>127
純粋関数は並列性が高い。
GPUシェーダーとかもろに純粋関数だし。 そもそもフィールドで持つ必要がある
データってこのブログで紹介されてるような
キャラHP,MPや貯水量、現金残高
みたいな上下限をもった数値の増減みたいな
ものだけだと思う。
境界値バグに関係しうるパラメータね。
こればっかりはstaticおじさんはやりにくいと思うわ。
カプセル化とはなにか?超わかりやすく解説します!
https://jpazamu.com/encapsulation/
あと考えられるのは 装備品みたいな
魔法使いジョブには剣を装備させてはいけないなど
特有の細かなルールがあるときはカプセル化が必要か。
それ以外の人名とかIDとかメモリ内で変動しないような値を
わざわざフィールドを用意する必要もなければ
privateで保護する必要もないしstaticおじさんで
なんの問題もないよね。
基本的に「演算」がないデータだから
連想配列やJSONでまとめてやり取りすればいいと思う。
あとバグを引き起こすのは値の変更で
あって参照って無害なのでは? バカじゃね
最近のソシャゲなんて全部DBのテーブルに入れなきゃいけないのにクラスの階層構造なんてテーブルに格納するときやりにくくて死ぬだろ >>135
バカじゃね
最近のソシャゲなんてRDB使う方がレアなのにテーブルに格納する前提でコード書いてたらやりにくくて死ぬだろw その界隈はスケールアウト重視でRDBよりさらにフラットなのが主流だからな。
それこそ学校で教えるデータベース正規化の真逆、「逆正規化こそ正義」という世界だし。
「正規化は愚かな考え」というスレを立てようぜ 最近気が付いたんだけど。
STLならどうなるか?と考えるのも、一つの分析手法だな。 カプセル化が悪いんじゃなくて設計ミスってるだけじゃん
経験積んで未来予知の精度上げるしかないかな あとgetter、setterてカプセル化の思想とは関係なく、
便宜上の何かしらの理由(フレームワーク都合、トレースしやすい)で
慣用的に使われてるイメージある その未来予知や
設計ミスで後悔する要素とか
フレームワーク依存要素を排除したいから
純粋関数型で余計な状態を持たずに
機械的にプログラミングする方が
いいと言ってるじゃないか。 > 純粋関数型で余計な状態を持たずに
> 機械的にプログラミングする方が
> いいと言ってるじゃないか。
↑間違い
状態を持たないものは
純粋関数型で簡単に作れるが
世の中には状態を持っているものがたくさんある
純粋関数型は状態を持たないものは簡単に作れるが
状態を持つものは簡単に作れない
状態を排除することは不可能なので
結局状態を持つものを管理しやすい
オブジェクト指向を併用することになる 状態を多用する場面で純粋関数型は向かないってことかな? 純粋関数型言語を使えば状態を持たなくて良くなるわけじゃないんだよ
状態があるのとないのであれば、状態がない場合は
テストも簡単でシンプルに作れることが出来るだろう
しかし実際のシステムは状態があるんだよ
状態がないもの(つまり簡単なもの)を簡単に作れることを目指しても有り難みがない
状態があるもの(複雑なもの)を簡単に作れるもののほうがありがたい 関数型言語のエッセンス(イミュータビリティ)を部分的に取り入れると
いい感じだけど全部置き換えたら破綻するね 状態を持つ必要が有るとしても
極力少なめに厳選すべき
データベースのカラムは
全部オブジェクトのフィールドとして保持して
コンストラクタ経由で引数をフィールドに移し替えて
全部ゲッターセッター用意して
見ればわかるメソッドに全部Javadoc記述して
とかどう考えても馬鹿でしょ
personオブジェクトの
人名、年齢、身長、体重
とかがプログラムが動いてる短い期間に目まぐるしく
変動するんですか?
オブジェクト指向の教科書見るとそうやって教えてるんだぜ? >>147
別に破綻しないよ
状態が必要なら、状態ごと受け取って状態を含めた出力をするような関数を作る
データとそれを使う関数を1つの単位(クラス)にまとめたほうがいいのか
それともデータはデータ、関数は関数で分けて管理したほうがいいのかという違い
(関数型でも必要ならある種のデータ型とそれに密接に関係する関数群をモジュールとしてまとめる)
どちらかが常にいいというわけじゃなくトレードオフだから
それを理解してドメインに応じて使い分ければいい > 状態が必要なら、状態ごと受け取って状態を含めた出力をするような関数を作る
んで、その最終形態が
メモリの内容を全部渡して、書き換え済みのメモリを返す
それを永続化する。
つまりはグローバル変数と同じ状態になるわけだ 結局書き方の違いでしか無いんだよね
状態 = 関数(状態)にするか
状態.関数() にするかという書き方が違うだけ そして行き着く先は
状態 = 関数(状態)の形で
大規模なものを人間が統治管理できるのか?って話
人間がってのが重要な所
理論的には出来る。コンピュータにも出来る。
だが人間がそれをやれなきゃ意味がない
簡単な足し算でも、それが何万個もあれば人間はミスをする >>150
プログラミングモデルの話だからそういうのは関係ないんよね
言語が保証してくれるレイヤーから上でプログラムをどういうスタイルで書くかという話だから
>>144の最初の例ならCounterが状態
incはCounterとIntを受け取ってCounterを返す関数
inc :: Counter -> Int -> Counter
inc (MkCounter c) n = MkCounter (c + n) >>152
>状態 = 関数(状態)の形で
>大規模なものを人間が統治管理できるのか?って話
オブジェクト指向のコア概念メッセージングがなぜ提唱されたか察するに
このあたり関係ありそう 昔のC言語は状態なんか持たなくても動いてたよw
前提が間違ってるじゃん >ソースコードが存在し改修が可能であればカプセル化しても問題ない。
>ソースコードがあってもライセンス的に改修できない場合や、そもそもバイナリのライブラリしかない場合などは絶望的である。
ライブラリが担うべき要件でもないし他の探すか自分で作るか改修依頼するかしかないでしょ
なんでカプセル化が悪の権化みたいなことになってんのw 純粋でなければ、利点として宣伝されるものの多くが実現されなくなるからな。
もっとも、純粋であっても、現時点では実現されていないのだが。 その状態の管理方法がオブジェクト指向でも純粋関数型でもないだけで >>140
getter/setterはJavaBeansの仕様だからね
JavaBeansはGUIツールでポトペタで操作できるようにするためのもの
GUIのツールでプロパティ書き換えたりイベントリスナー書いたりするのが目的
だからJavaBeansの情報を取得するBeanInfoにはgetIconメソッドがあったりする
JavaBeansではプロパティに値をセットしたら値が変更されましたイベントを発火したりするから
getter/setter経由でアクセスすることは理に適っていた
それがいつの間にかオブジェクト指向のプログラムではgetter/setterを書くんだーになってしまった
JavaBeansのようなコンポネントの作法はライブラリ内部で使われるようなオブジェクトには必要ない
デスクトップアプリの開発が衰退したおかげかいまはだいぶその認識が広まってる 単にそのクラスに必要な操作のみ公開するという思想は良いと思うが
頭の硬いやつがいると理解出来ないからか文句を言ってくる >>162
結局入力と出力を
メンバ変数に入力や出力を内包されると単純に動作が把握し難いだけで
全くメリットがない
内包されたデータを見ないで修正してもいいのか?
お前の会社はそれでいいとは言わないだろう
だとしたら入力や出力を隠蔽するのは誰にとっても迷惑にしかならない そのクラスの責務(入力に対する出力の仕様)がわかっていれば
具体的な内部の動きを把握する必要がそもそもない
把握する必要ないから楽 >>163
システムの規模が大きくなった時
どう管理するかって話だからその理屈は全く関係ないんだよな
内包されたデータを見ないで修正してもいいか?
オブジェクト指向であれば、それがある単位で分割されているから
そこだけを見ればいい >>164
お前が作ったクラスの動作がおかしいときどうすればいいの?
中身みんでええの? >>165
お前が作ったクラスの動作がおかしいときどうすればいいの? >>166
お前が作った関数の動作がおかしいときどうすればいいの?
中身みんでええの?
どちらも中身を見るなら
管理しやすいオブジェクト指向の方が良い 適切な単位で分割されてると修正も楽
それこそ「そのクラスの責務(入力に対する出力の仕様)」だけ
満たすことを考えればいい 内部で関係する変数とかを閉じててくれないと
そのクラスに値を設定する部分を見て回らないといけなくなる クラスに値を設定する部分は、そのクラスを見るだけでいい
引数として独立していると、その引数を使ってる部分を全部調べなければいけなくなる
戻り値が変わると、その戻り値を使ってる部分全てだ >>170
中身を見るとどうやらメンバ変数statesの値がnoneにならないとメソッドの処理が最後まで流れない処理になってるみたいなんだけど
こういうときどうしたらいいの? メンバ変数statesがprivateだったらそのクラス内に閉じた問題だから
単純にそのクラスのメソッド内でstatesとnoneを比較するようなとこを
洗い出せばいいんじゃないの? >>170
その責務って奴が言葉だけは聞こえがいいが
現実論として関わるプログラマや関係者の間で
認識がバラバラになる最大のポイントなんだわ。
プログラムやコンピュータを計算機として見てないんだわ。
「この処理を果たしてこの場所で書いていいものか…」
なんて余計な事で頭を悩ます最大の原因なんだわ。
それよりももっとシンプルに、
任意の場所に、受け取った引数を使って
結果を返す関数を作って関数に要求させた演算を
投げて結果だけ受け取った方が生産的だよね?
関数を連鎖的に組み合わせればどんな複雑な演算も
成し遂げることが出来る。 それはチーム編成とか統制の問題では
レベルが低い集団だと統制とれずク○の山が積み上がって
収集つかなくなるんだろうな >>175
privateメンバ変数は見なくていいって話じゃなかったん? クラス外からは気にしなくていいけどクラスを修正するときは見なきゃだめでしょ
privateなら見るべき範囲はクラス内って絞ることができる まあ理解できもしないのに真似事みたいなことするのが一番迷惑だから
やりたいようにやりなさい そもそも>>173の質問がバカ丸出しなのに自覚ないとか >>161
プロパティって、どういうプロパティが存在するかを実行時にインスペクトできるというのも重要な性質だな。
BeansはJavaのリフレクションでそれを実現していたけど、単なるgette/setterではそういうのも忘れられている。 >>179
さらにpublic staticならグローバル変数不使用なら引数と戻り値(入力と出力)の確認だけじゃん
絶対こっちのがクラスより優秀だろ >>176
それって、ちゃんと考えて設計するの面倒だから全部グローバル変数でやります、生産性高いよね!といってるのと変わらないじゃないかw >>186
比較するものがグローバル変数使用のソースしか無くなった? >>185
> さらにpublic staticならグローバル変数不使用なら
どうせその前提だとそれはクラス内部に状態を持つ必要ない単なるUtilityクラス
内のメソッドだろ?
状態をどうやって管理するかの話だったのに、状態を排除した前提を持ち出してきて
何を認めさせたいの?反論することだけが目的? >>188
だからグローバル変数不使用のc言語と同じでいいよ
っていうかこれで完璧なんだよ 御託はいいからお前の書いたコード見てみたいわ
グローバル変数を使わないCコードが書けるんだろ?(失笑)
C言語ならグローバル変数はある程度使うべきなんだけどね ■ このスレッドは過去ログ倉庫に格納されています