昔と違ってマシンリソースを節約するために奮闘する必要はなくなったが、可読性を高めて保守しやすい状態にしておくことは今でも必須なのでコーディング作法はとても大切。
コーディングにおいて1番重要なことは、手段を目的にしないこと。あくまでも目的を起点に逆算してコードの最適化を目指す。手段を起点に最適化を目指すと検定試験やパズルみたいになる。
「backup2.sh」みたいに、わざわざコメントを書かなくても、やりたいことが一目で分かる「説明的コード」にする。「難解パズル問題コード」じゃなくて。説明的コードにする方ためなら多少の効率は犠牲にする。
手続き型 vs OOP
- 手続き型は軽量で速い。OOPは重量で遅い
- 手続き型は「脚本」的なまとめ方。OOPは「擬人化」的なまとめ方
- OOPコード(プログラム)は擬人化のために余計な記述をしなくちゃいけない
- ただ手続き型も OOP 的なまとめ方はできるはず。ディレクトリ構造とか
- 手続き型は「脚本的」になりがち。ゆえにスパゲッティ化に流れがち
- OOP は「擬人化」ゆえのディレクトリやコードの整理をいい意味で強制される
- OOPの醍醐味は「擬人化」ゆえの感情移入、把握、管理のしやすさ
要はトレードオフ。軽さと速さを犠牲にしてでもOOPの「再利用/拡張/保守性」の高さが欲しいならOOP。OOPでスピードも求めるなら、それなりの工夫や技術が必要になってくる。
ChatGPT で OOP
- まずファイル構成や命名をしっかり練る。GPT に伝える
- それぞれのクラスたちにやらせたい動きや連携関係をしっかり把握
- それぞれのファイルにコメントで具体的な動き(処理を記述)
- ChatGPTに「コメントを参考にしてOOPで書いて」と言う
- まず手続き型でコメント付きのコードを書いてもらう。そのコメントを再利用する感じ
- Instanceの使い回し、SQLクエリの節約、キャッシュ利用など、工夫したい旨も伝える
これで、うまくいった。
要約
- オブジェクト指向の真髄:コードの徹底した重複排除+クラスの擬人化
- 似てる箇所がある → 整合整理できる。もっとまとめて再利用できる
- ただ、少し冗長でもコードの意図や分かりやすさも大切なのでバランスをとる
- 沢山のエラーが発生してカオスにならないように最小単位ずつ進める
- 全て英語。シンプルで美しく脳に正しいイメージを伝える英語を使う
- ロジックを1文ずつしっかり読み、流れ全体を完全に理解していればエラーは必ず直せる
- toString で節目節目の流れを確認しながら進めていけばエラーの原因は特定できる
クラスの整理
ファイル
- フォルダ1 (SuperClass) -> フォルダ2 (SuperClass) -> SubClassファイル群と階層整理ができる
- 階層整理をすると各クラス群の役割状況、ポリモやメソッド等の使い回し状況などがtreeで俯瞰できる
メンバ
- 静的メンバ → フィールド → コンストラクタ → メソッド → 定石オーバーライド/ゲッタセッタ
命名規則
- 後になってからの変数名の変更はとても面倒なので一番最初に「永久に決定」されるものとする
- クラスには体を表す命名を。フィールドには属性を表す名詞を、メソッドには動きを表す動詞を付ける
- メソッドはpublicで外部利用。privateで内部利用。オーバーライドを希望する時はabstractを付ける
- インスタンス変数名は宣言されてる型の方のクラスのイニシャルを利用(PreparedStatement: ps)
- イニシャルだと変数名が1文字になってしまう場合に限り子音3文字にする(Connect: cnc)
- 2体目のインスタンスから変数名の後に数字をつけ始める(ps2)
- 自作クラスのインスタンス名は先頭3文字にする(Monster: mon)
- 配列変数名は複数形(s)にする。配列には複数のデータが格納されているので
- その他の変数名は格納データの内容を適切に表すものにする
- プリミティブ型の変数名は1文字(String: s, int: i)
- データ格納変数名は名詞。動詞はメソッドのためにある
- Mapを格納する変数名は「tableBunch」のように内部データが分かるものにする
オーバーライド
- toString:自作クラスのカスタマイズ情報を手軽に参照できるようになる
- equals:自作クラスをコレクションに格納するときはオーバーライド
- hashCode:HashSetなどが上手く動作しない時にはオーバーライド
- compareTo:Comparable を実装すると、Collections.sort が使える
- clone:Cloneble を実装すると、インスタンスを複製できるようになる
*オーバーライドの定石はObjectを参照
外部リソース
- ファイルを読み書きするときはバッファリングを併用
チェックリスト
- 等価判定される自作クラスのequalsは全てオーバーライドされているか?