プログラムをやっていて以前から疑問に思っていたので教えて下さい。
アクセス修飾子でprivateやpublicなどがありますが権限を強化するprivate自体の意味は分かりますが、実際にpublicにすると発生するリスクがよく分かりません。
すべてpublicにしてアプリを作成した時に発生するであろう問題を具体的な例を出して教えて下さい。実際にあった例などありましたら有難いです。
カプセル化の定義は理解しているつもりです。
「カプセル化」とは、変数などにアクセス修飾子をつけることで、外部クラスやメソッドからのアクセスを遮断すること。
外部にみせたくないということは分かりますがでは、(根本的に)もし見ることが出来たり、(特に)アクセスできると例えばPlaystoreにアップしたら具体的にどういう問題が起きるのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/18 13:31 編集
回答5件
0
- オブジェクトの内部構造を知らずに呼び出すと整合性を壊してしまうようなメソッドであるなら、publicにしてしまうと知らずに使った利用者によって不整合を引き起こされかねません。
- ひとたびpublicにして公開したメソッドは、誰がどう呼び出しているともわからないので、もう仕様を変えるわけにいかなくなります。
追記 09/18
2項目挙げたうちの前者はカプセル化に関わることで、otnさんが詳しく述べてくれました。後者についてはraccyさんが実例を挙げて詳説してくれたのですが、これは「開放・閉鎖原則」と呼ばれるものです。調べるときのキーワードにどうぞ。
投稿2016/09/16 23:53
編集2016/09/18 13:03総合スコア5568
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
アクセス修飾子がないため、全てがpublicになるJavaScriptでの事例を見つけたので、紹介します。
発生した問題のPR: https://github.com/knockout/knockout/pull/796
jQueryを内部で使用しているKnockoutというJavaScriptライブラリで発生した問題です。
jQueryにはドキュメントに無い関数がいくつか存在します。これらは公開された関数の内部で使用することが目的であり、将来にわたっても維持するかは未定のものです。将来のバージョンでは廃止や動作の変更がされる可能性が高く、ライブラリ作成者側にとっては利用者には使わせたくはありません。しかし、JavaScriptにはprivateといったアクセス修飾子が無いため、jQuery側でそれらの関数を使わないようにさせることができません※。仕方が無いため、ドキュメントには書かないという消極的な手法をとるしかありませんでした。
※ 無理矢理privateもどきにする方法は一応あるのですが、ソースの可読性や実行速度、メモリ使用量などに影響があるため、積極的に使用したい物ではありません。
そのドキュメントに無い関数のうちの一つであるjQuery.clean()
という関数をKnockoutは使っていました。これが悲劇の始まりでした。jQuery 1.9から内部でjQuery.clean()
の使用を止め、この関数は削除されました。つまり、jQueryを1.9にアップデートするとKnockoutが動かないという問題が発生したのです。Knockout側はjQuery.clean()
を使わない方法でコードを修正し、jQuery 1.9にも対応できるようにしました。それが上のPRです。
これは誰が悪いのでしょうか?jQuery側はドキュメントに無い関数を勝手に使うのが悪いと主張するでしょう。それは正しいです。では、Knockout側はどう思うでしょうか?実際に動作確認を行うとき、jQueryのドキュメントに無い関数を使っているかどうかを自動的にチェックする方法はありません。ドキュメントに有ろうが無かろうが、関数は、実装されていれば正しく動くのです。どんなにテストを行ってもこの問題を事前に検知することは不可能だったでしょう。
もし、JavaScriptにpublicやprivateがあったとしたら?jQueryの開発者はこのような関数について全てprivateに設定していったでしょう。もし、privateによってjQuery.clean()
がjQueryの外側で使えないようになっていれば、Knockout側もテストですぐにわかって、そのようなコードが入り込むことは無かったでしょう。つまり、ドキュメントに書かないという消極的な方法では無く、エラーにするという積極的な方法によって、利用者に使ってはいけないことを確実に周知できたのです。後から削除や変更された場合も、今回のような無用な混乱は避けることができたのです。
どうでしたか?privateがあってよかったなーと思えましたか?
小規模な開発であればそれほどメリットがあるように思えないかも知れません。しかし、複数のライブラリ、モジュール、パッケージに別れ、それぞれが独立し、それぞれを作る人が異なるような大規模開発において、内部だけにしか使わない物を見せないと言うことはとても重要です。とくに、コンパイルを行うような言語ではコンパイル時に使ってはいけない関数がわかるというのはとても意味があることです。開発者側は、内部利用の関数について互換性を気にせずにいくらでも最適化できますし、利用者側は、何を使って良いのか明確になり、ドキュメントにあるかないかの確認をするなんて時間の無駄なことをする必要もなくなります。
規模が大きくなり、分散と疎結合が必要ななったとき、そのときこそ、privateの秘匿化が価値を持つのです。
投稿2016/09/17 04:07
総合スコア21733
0
ベストアンサー
カプセル化の言葉は知っているがメリットが理解できないと言うことですね。
(特に)アクセスできると例えばPlaystoreにアップしたら具体的にどういう問題が起きるのでしょうか?
直接にプログラムに脆弱性が生まれるか?という意味でなら、生まれません。
あくまで開発者の生産性の問題です。バグが生まれやすくなるため、テストで取り切れないと結果的に脆弱性が出来ることはあると思いますが。
2,アプリを開発している一個人
3,アプリを複数で開発している共同開発者の方々
これは、「一度頭に浮かんだことは絶対に忘れない」という人で無い限り2も3も同じです。
オブジェクト指向プログラミングするのにカプセル化を使わないと、オブジェクト指向のメリットが失われ、デメリットだけになり効率が低下します。
まあ、publicにしなくてもpublicなセッター・ゲッターを定義すればほぼ同じデメリットが生まれますが。
「カプセル化」の他、「疎結合」「モジュール結合度」などのキーワードで調べてみると良いかと思います。
投稿2016/09/17 01:47
編集2016/09/17 01:49総合スコア84421
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/17 02:16
退会済みユーザー
2016/09/17 03:42
0
こんにちは。
全てpublicでも本質的には問題ありません。
しかし、人はミスを犯しやすいです。そのミスの一部を防ぐためにprivateにするのは効果的です。
外部からアクセスする必要がないメンバをprivateにしておけば、間違って外部からアクセスすると言語処理系がエラーを検出してくれますので。
プログラムが大規模になる程、これらのミスが痛い(バグの原因を見つけにくい)のでより有用になります。
投稿2016/09/17 01:17
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/17 01:31
2016/09/17 01:37
0
問題と呼べるほどのものは無いです。
ただし、オブジェクト指向っぽくならないし、その利点の一つであるカプセル化がうまく働かなくなります。
ではカプセル化が無い状態とはどのような状態かというと、グローバル変数だけでプログラムを書く状態です。アセンブラやCOBOLでは基本的にこの状態です。つまり、かけないことは無いです。
私はCOBOLを書いていましたが、それぞれの変数がどのタイミングでどんな変更がされるかを意識しながら書かないといけませんでした。
キチンと管理できればバグのないプログラムになりますが、管理できなければ意図しない動作をし、プログラムが異常停止したポイントの状態をすべての変数を表示して確認する必要がありました。そして、意図せずに変数を変更した箇所(もしくは初期化などを忘れた箇所)を発見するのです。(最終的に私はプリフィックスでアクセスレベルを明示するようになりました。)
特にこの作業は、他人のコードやコーディングから3日以上経過すると調査がプログラム全体にかかることがあります。
初めから、プログラムのどこで変更されるのかを宣言し、コンパイラレベルでエラーになれば調査の手間が減るので、私は適切に(つまりできる限り小さく)権限を設定することを心がけています。
まあ、個人的なものや使い捨てコードなら、コーディングスタイルは自由なのでやってみるのもいいです。やってみなくては分からないものも多いし、質問者さんは案外、問題ないと感じるかもしれません。
投稿2016/09/17 00:59
編集2016/09/17 01:46総合スコア2883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。