何から実装すればいいのかわからない人へ
- Viewは後回しにすべし
- いきなりコードは書かず、まず設計(=ロジック/アーキテクチャ)から考える。登場人物(=オブジェクト)は何かを紙などに列挙していく。
- それら(=オブジェクトら)がどんなメンバ変数、メソッドを持っているかを考える。publicなメソッドはCRUDしかないと心得る。
- さいごにコードを書く
クラス設計においてやり勝ちなミス
- 依存したコードを、気づいたら書いてる。そのオブジェクトに関することのみ書くべし。
- 一見、そのオブジェクトに関することを書いていて依存していなくても、ArrayクラスやNumberクラスのほうに書いて(=拡張)あげるとそのロジックが他でも使い回せるケースもあるので注意する。
実際にあった例
要件:
- バカラというゲームを行う
- 複数のプレイヤーがおり、それぞれ独立したamount(=財布)をもっている
- モンテ・カルロ法など◯◯法をimportしてその通りにベットしていく
ここでの登場人物は以下である:
※publicなメソッドのみ記す。
class Baccarat
play(betValue, betPosition) {
return {
payout: number,
results: { PLAYER: true, BANKER: false,,, }
}
}
...
class MonteCarloTeacher
getBetInfo(amountsHistory) {
return { betValue, betPosition }
}
...
// INFO:
// MonteCarloTeacher(モンテ・カルロ法で教えてくれる先生)が資金管理してるので、
// ぱっと簡単なものを作るならPlayerクラスは不要。
// class Player
// INFO: トランプ。
class PlayingCards // 切り出しておくと使い回せる
...
// INFO: 配列のシャッフル。PlayingCardsクラスなどで使われる
Array.extends.shuffle = ([...array]) => {
for (let i = array.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// INFO: Baccaratクラスなどで使われる
Number.extends.get1thDigit(n) {
return Math.floor(n / 1) % 10 // 一桁めをとる
// Math.floor(n / 10) % 10 // 二桁めをとる
}
初心者あるあるミス
- 複数なのに複数形じゃない (x: playingCard)
- 関数やメソッドは動詞。変数はプロパティは名詞。というルールを知らない。
- オブジェクト指向に慣れてないのでif文やネストがやたらと多い。
- 関数の中に関数を書いてしまう。
- グローバル汚染を積極的に行い、しかも気づいていない。
- 関数型プログラミングを知らない。もしくは知ったばかりで使いすぎる。
- 三項演算子を知ったばかりで使いすぎる。(ネストは厳禁)
- markdown記法という革命的かつどこでも使える記法を知らない。(ほぼすべてのメモアプリに搭載されている機能というのに)
- "DRYの法則"、"車輪の再発明"、"MVCモデル"、"CRUD" という基本原則を知らない。
JavaScriptの落とし穴
- dataがArrayのときdata.map()はdataが書き換えられるので注意
- プリミティブではないデータ型(ArrayやObjectなど)は参照渡しなので、代入先を変更すると代入元も変更される。これを避けるにはディープコピーやシャドウコピーをする必要がある
JSON.parse(JSON.stringify(dataTable))
Reactの落とし穴
useStateでprivateにしてるようで
jsはmapなど参照渡しで代入する前から変数が書き換えられているから、privateの意味なし!!!
コメントに使うと便利な接頭辞
// TODO: このようにコロン+半角スペースで接頭辞をつけておくと検索がらく。
alert()
// INFO: 情報やメモ用の接頭辞。複数行のコードについて述べたい場合は
alert()
// INFO: コロンとセミコロンを用いて範囲を示しておくとわかりやすい:
while (false) {
alert()
}
// ;
// INFO: あとがき
// コメントの対象が、単数行と複数行で見分けがつかない
// もしくは範囲を示したいケースがあったのではなかろうか?
// そういった場合に便利である。
短いコードに変えていくことよりも可読性を重視すべし
以下は関数型プログラミング、三項演算子、さらにアロー関数に変えていった例である。
.reduce(function(p, v) {
if (v.isWin)
p += 1
else
p -= 1
return p
}, 0)
.reduce(function(p, v) {
return v.isWin ? p++ : p--
}, 0)
.reduce((p, v) => v.isWin ? p++ : p--, 0)
ただ関数型プログラミング、三項演算子、さらにアロー関数は知っておくべし。
実用的な考え方
- main側で可読性を意識して書く。("個体に関する情報だけ持たせるべき"を知っていれば変なメソッドを書くことはないだろう)
- なるべくreturnで返却していって低レイヤーで終わらす。
- さもなくば処理を内包してブラックボックス化していくと
- 可読性が悪い
- 汎用性が損なわれる
- ブラックボックス化はクラス(オブジェクト)に対して行うべし。
- さもなくば処理を内包してブラックボックス化していくと
- 思いつく限りの全ての条件をカバーできる処理を書いておくと
- 新しい条件がでた時にいちいち考えなくて良くなる
- 汎用性が高い
- バグの侵入がない
- グローバルに一時的な変数をおかない。参照しない。
- 最小限の情報を引数で渡すと、考えることが少なく済む(可読性がよくなる)
GitHub Pages
- githubにreactをbuildする方法: https://web-begginer-log.com/create-react-app-gh-pages/