自分が考える「プログラミング能力」についてのメモ。

ここに書かれていることは、中級者以上を対象にしていると思う。初級者はとにかくヨダレたらしながらコードを書きまくればいいよ。

◆名前の付け方

つまり

クラス名、フィールド名、プロパティ名、メソッド名、データベースのフィールド名、生成するファイルとかディレクトリの名前、プロジェクト名、名前空間

とかに対して適切な名前を設定する能力。
ここがまずいとコードの可読性が落ちる。転じて生産性、保守性が落ちる。
しかもそれらは後で直すのが辛い。というか怖い。

▼やらないでいただきたい例

・日本語のローマ字書きで名前を付ける

表記ゆれをいちいち確認する必要がある。
「コーヒー微糖」をローマ字にすることを考える。
Ⅰ.kohiBito
Ⅱ.koohiiBitou
Ⅲ.kouhiiBitou
Ⅳ.kohhiiBitoh
Ⅴ.coffeeBitou

五種類挙げたけど五種類で済むわけもないし、こんなんが書かれたコード渡されたら、残念に思うでしょう。
しかも性質が悪いのが「間違ってはいない」ということ。

これを英語表記すると
lowSugarCoffeeで大体の人が納得する。ここで重要なのは「英語的に正しい」じゃなくて「読んだ人が即理解できる」ということと「表記の揺れようがない」ということ。
「ローシュガーコーヒー」で覚えてしまえば、コーディングするときに変数名を確認しに行く必要がなくなる。

・ググった翻訳結果をそのまま名前にしてしまう

全然違う意味の言葉が付く場合がある。せめて検索結果に出てくるであろうWeblio辞書をあたれば大体正解が見つかると思う。
完全に正確な英語でなくてもいい。名前は尾を引くから、5分くらい頑張って欲しい。
あと、やってれば慣れるよ。逆にやらないと慣れようがない。

・全く情報を持たない変数名を付ける

例えば、寿命が短い変数ならそれはもう頭文字一文字でもいい。でも、300行近くあるメソッド全体に関わってくる変数に「day」とかつけるのはおかしいだろ。何の日だよ。男の子にはちょっと言いづらい日なのか。
しかも「day2」とかいう変数が続けて出てくる。
そうするとまた、「このday2が意味する日付は何なんだ?」って確認しに行く必要がある。

・嘘の名前を付ける

名前の最後に「List」ってついたのなら、それは「List型」でなくてはならないし、「Date」ってついたのなら、それは「Date型」でなくてはならない。
「日付を表す文字列」ならば「DateString」にしたほうがいいと思う。
でも、変数の型を変数名に入れてしまうことはなるべくならやめたほうがいいよ。抽象度が下がるから。「Date」に関してはしょうがないけど。

あと、全然Factoryじゃない、それっぽい何かにFactoryって名前つけたりね。

ちょっと違うけど困惑したのが、「納入日と修理日」っていう項目に、納入日と修理日をごっちゃに入れていた例。データ行ごとに「納入日」だったり「修理日」だったりする。分けろ!

・勝手な省略をする

「Category」を省略したら「Cat」になるし、「Catalog」を省略したら「Cat」になるし、「Catenate」を省略したら「Cat」になるし、猫は英語で「Cat」だ。
理由がないのなら省略してはいけない。
でも「Information」は「Info」でいいと思うし、「Element」は「Elem」で良いと思う。

・無意味に冗長な名前を付ける

例えば「人間」には「名前」がある。「犬」にも「名前」がある。
それを例えば「Human.HumanName」「Dog.DogName」にしてしまうのはどうかと思う。
「Human.Name」「Dog.Name」が自然だろう。

また、「旅行の写真」フォルダと「家族の写真」フォルダに「旅行の写真_20171101_12151101.jpg」とか「家族の写真_20171021_19213214.jpg」が入っているのはおかしい。
「写真」フォルダの中に「旅行」「家族」フォルダがあって、それぞれに「20171101_12151101.jpg」だの「20171021_19213214.jpg」だのが入っている方が望ましい。

◆情報の正規化、「大きな問題」の分割

参考リンク:データベースの正規化
参考リンク:関係の正規化

クラス(オブジェクト)にも同じことがいえる。

つまり、どの情報がどの情報と関係しているのか?ということを考えて欲しい。

「人間」クラスに「年齢」というフィールドはいらない。なぜなら「年齢」は「生年月日」によって導出されるものだから。「Get年齢」というメソッド(あるいはプロパティ)に年齢を計算させる方がいい。
また、「住所」は「多田野数人」と一対一で紐づくわけでは無い。なぜなら、その「多田野数人」と「多田野数人の友達である大坊さん」は同じ住所に住んでいる可能性があるから。
個人に「住所」の項目を作ると、その「同じ住所」を表現することが難しくなる。

上に貼った正規化の説明リンクを見て理解してほしい。ほんのちょっとだけ難しいかもしれないけど。時間をかけて見て欲しい。じゃないと無駄にデータサイズが増えたり、仕様に変更があったときにえらい目に合う。
そのときは別の人がシステムの保守してるんだろうけどな(遠い目)

「大きな問題の分割」については、プログラミング初心者が最初に意識し始めることだと思う。大切なことだ。
一つのことを行い、またそれをうまくやるプログラムを書け。

◆抽象化能力

プログラマなら誰しも「ほぼ同じコードを何回も書く」ってことをやったことがあると思う。
その似たような処理は多分、処理するものの型が違っていたりしたんだろう。でも、本質的に同じことをしている。
そのあたりを抽象化できればコードの量は減る。つまり、不具合の発生位置の特定は早くなるし修正変更が容易になる。

例えば「黒い水筒」があって、「白い時計」があるとする。
このとき両者の色が互いに異なることを理解できるのは抽象化の力に他ならない。
プログラミングに置き換えると「色という性質をもったモノ」というグループに「水筒」と「時計」が属しているから、個別の「黒い水筒」と「白時計」の「色」を比較することができる。

何言ってるかわかる人には何言ってるかわかるはずだ。

分からない人はここを見たり見なかったりしろ。

Interfaceを使え。そのInterfaceを実装したクラスのインスタンスをListにぶっこんでLINQで一括処理しろ。

◆パラダイムについての知識

参考リンク:プログラミングパラダイム

1 :(‘A`):2006/10/26(木) 23:40:47 0
通常の人間は異性やセックスなしでは生きていけない。
恋人となる対象に依存しなければ精神の安定を保てない
喪男はその孤高の精神をどうやって手に入れたのか?

21 :(‘A`):2006/10/27(金) 00:16:04 0
だっておめぇ
とんかつ食ったこと無い人が
トンカツ無しじゃいきてけねぇよ
なんていわねぇだろう

例えばJavaScriptしか触ったことのない太郎君がいたとして、その太郎君に静的型付けが便利だと言ってもなかなか伝わらない。
それは、太郎君がIDEからの恩恵を受けたことがないからだし、オブジェクト指向について考えたことがないからだし、メソッドがどんな動作をするのかとかコードのエラーチェックをするときには必ず実行をして動作確認をするものだというパラダイムでしか生きてこなかったからに他ならない。

人間っていうのは自分の所属するものに対して不満を感じない時、「ここから動きたくない」「ここは他よりも優れている」と思うようになっている。危険だ。

プログラミングにおける快楽っていうのは「自分で作ったものが動く」っていうことが第一に挙げられる。でもホンモノの快楽は「算段し、漏れなく開発し、うまくやってやった」時に得ることができる。JavaScriptでは無理。もやもやが残ったまま静的なもろもろのチェックを経ないコードを実行する羽目になる。
だから、他の言語を触ってみないといけない。

いま俺はC#を一番にすこってるんだけど、それでも他の言語を触ったほうがいいと感じている。なぜなら、C#触る前はVBAが一番好きだったから。
VBAも楽しいよ。でも、C#はマジに正しい処理を「普通に」書くことができるし、C#を書けるようになってからVBAの書き方も背筋が伸びたようになった。
いま俺が触るべき言語は「純粋関数型」のHaskellだったり「自己言及、メタプログラミング」のLispだったりで、その言語を学ぶことによって、普段使いの言語をより豊かに書けるようになる。Lispは一行も書いたこと無いんですけどね。

逆に、「違うわ」と思う言語を触ることも良いことだ。
JavaScriptもPythonも「人生を豊かにする技術」じゃなくて「ごはん食べるために入手する技術」でしかない。Disってるわけでは無い。そういう言語も必要な場合がある。多様性があることは良いことだし、大抵の人にとってプログラミングなんて仕事の一環でしかない。しかもPythonは書いていて楽しい。「どの言語が一番か」とか喧嘩する意味もない。だって「どういうプログラムを書いて問題を解決するか」と「どうプログラミングと向き合うか」っていうのは土俵が違うんだから。
とか、色々と余計なことを考えてしまうような言語を触ったときには、「戻りたい」って強く思うようになる。「正しくて、誰が見ても伝わるコードを書きたい」と思うようになる。

◆言語の機能についての理解

ラムダ式だのデリゲートだのモナドだのデータバインディングだの匿名クラスだのイベントだのリストだのスレッドだのは、(多分)便利だから作られたものである。
だから知っておいた方がいい。

常に最新を追えとは言っていないけど、例えばコード上に見慣れない構文があったり、「こういう機能がありますよ」と人から言われたときは、学ぶべき。拒否反応を示すのはおかしい。
そして、その機能の目的を理解し、合致していたら(あるいはコードを簡潔に書けるようになるのなら)採用すればいいし、違うんなら使わなければいい。

◆メモリと参照についての理解

言語によるが、
そもそも「参照」って何?とか
変数にnewをぶち込んだら「元々入っていたオブジェクトの参照が切れる」とか
プリミティブ型が参照か参照じゃないかとか
Nullってつまり何?とか
Listってどうやってデータをメモリに乗せてるの?とか
stringってcharの配列なんだよね?とか
GC?あぁ、あの鈍器ね。とか

◆発生した問題の原因、解決方法をなんとなく察知する嗅覚

コードを沢山書こう。
パソコンにいっぱい触ろう。むしろパソコンを組み立てよう。
暗号とか通信とかデータベースとかサーバーとか触ろう。

うまくいかなかった時に「どこで問題が起きたか?」が何となくわかるようになると思うし、「解決するべき課題」をどういう方向性で処理するべきかがわかるようになる。

◆パターンを考える能力

作ったシステムにどんなデータが入るのかを想定する。
サンプルとして提示されたデータが、「本当に常にその形であり続けるのか」を想定する。
今作っているシステムに対して、のちにどんな変更が加わる可能性があるのかを想定する。

◆「美しく無さ」に対する嫌悪

今まで例に挙げてきた駄目な例とか、その他の色々に対して、「いやだなぁ」と思えるようになってほしい。
理路整然と、隙なく設計されたシステムを作っていただきたい。この記事を書いた俺もできてないんだけどな。
でも、変な実装には「変だ」「なぜなら~だから変だ」と言えるようになって欲しい。また、他人から「変だ」と言われたときに、グダグダ言ってねーでちゃんと向き合わなければいけない。

手近なところで言うと「グローバル変数ってどこからでも値変えられてヤバくね?」とか「GOTOって動き追えなくね?」とかだろう。

IT技術に限った話だけじゃなくて、ポケモンGOとかやった時は「頭の足りてない人間の屑が作ったんだなぁ」とちゃんと思って欲しい。

結論

すきにしろ