「システム設計の原則」覚え書き - チャプター1, 2
はじめに
現場で役立つシステム設計の原則を読んだ。
(リンク先は技術評論社のHP)
この記事は、読んだ本について書き残すことを目的としている。つまり・・
- 覚えておきたい要点を書き残す
- 周辺知識へのリンクも貼っておく
- 本書はJavaで書かれているので、C#で書いたときの文法メモ
書いているうちに長くなったので、チャプター2までを対象とする
※ あくまで自分なりの解釈であり、著者の意図を完全トレースしているわけではない。
要点だけ知りたい
著者のスライドがアップされているので、右矢印連打するとよいです。
チャプター1
キーワードは★閉じ込める★
要点
- 名前を省略してはいけない
- 段落を使って、コードに意味を持たせる
- 変数を使いまわすな(再代入するな)
- 関心ごとをクラスに閉じ込める
- 単位を扱うクラスをつくる
-
int
をそのまま使わずに、Price
など独自の型をつくる - 型にはロジックも閉じ込める(×データだけのクラス ×インスタンス変数を使わないメソッド)
-
- コレクションを扱うクラスをつくる;ファーストクラスコレクション
- 受け取ったコレクションとは別のコレクションを作って返す
- Qiita記事1->引数の型を何でも List にしちゃう奴にそろそろ一言いっておくか
- Qiita記事2-> .NET のコレクションついて再確認する
最後のファーストクラスコレクションについては、奥が深く理解しきれていない。
不変な性質
「この変数はもう変わらないんだな」とわかるとうれしい。
いわゆる脳内メモリの消費が少なくて済む。
せっかくなら用意されている修飾子(final
やreadonly
)を余すところなく使いたい
Qiita記事->読みやすいコードを書くためのTips
// java
class A
{
static final int MIN = 1;
}
// c#
class A
{
static readonly int MIN = 1;
}
プライベート変数はアンダースコア派?それともthis派?
C#はアンダースコア_
を変数の頭につけることが多い。
本書ではプライベート変数にthis
をつけている。
それがJavaの決まりなのか慣例なのかは知らない。
言いたいことは、自分はアンスコ派だったけど、this
もいいなあ、と。
this
のほうが、インテリセンスが的を射ている気がする。
Case1: アンダースコアを使った場合...Not good enough
ifやregionとかプリプロセッサが示唆される
this
を使った場合...Good!!
Case2: 関係ありそうなメソッドあるいは変数が表示される
破壊的代入の例
変数の値はなるべく変わらないほうがいい。
変えたくなったら別の変数を用意してみるといいかも。
javascriptなんかでは、なるべくconst
で値を宣言しましょう、と言われる。
最近流行りのRustも用意されているのはイミュータブルな変数が基本。
最近みつけたマイクロソフトさんのサンプルコードに、破壊的代入とも呼べるコードがあったので、リンクする。
このくらいの規模感だと、下手に変数たくさん用意されるほうが何か深い意図を勘ぐってしまうので、
マイクロソフトさんはこのくらいラフにやってくれたほうがこちらも安心する。
破壊的代入の例?→TcpListener クラス
変数data
を使いまわしている。
値オブジェクト
またの名をバリューオブジェクト
クソコード爆殺隊のミノ駆動様の記事にすべて書かれている
Qiita記事->設計要件をギッチギチに詰めたValueObjectで低凝集クラスを爆殺する
チャプター2
要点
- elseは使わない
- 早期リターン
- インターフェイスと多態を使う
- そのクラスを使う側が"知っておくべきこと"は少ないほうがいい
- これもキーワード★閉じ込める★に通じるものがある
- 列挙型を使い倒そう
-
Java
の強力な列挙型が紹介されている。C#
では同じことができない・・(?)
-
列挙型
本書ではいろいろ便利なことが書かれているけど、残念ながらC#
では真似できない
(ラッパーやら拡張メソッドやらで似せることはできるけど?)
Qiita記事->C# と Java の列挙型の違い
Qiita記事->【C#】Enumを使う際のTips
Java
のMap
は、C#
のDictionary
でいいのだろうか。
細かい違いはあるようだけれども・・JavaプログラマーがC#でプログラムを書いて引っかかったところ その1
Enumを使った状態遷移
P65 状態Aから状態Bに遷移できるか判定するプログラムをC#
で無理やり書いてみる
3つの状態をenum
で定義する。待機と準備と動作中みたいなやつ。
internal enum State
{
Wait,
Move,
Ready,
}
Enumの拡張メソッドクラスをつくる
internal static class EnumExtend
{
// JavaのMapは、C#のDictionaryで代用する
static Dictionary<State, HashSet<State>> allowd;
static EnumExtend()
{
allowd = new();
// ある状態をKeyとして、遷移先の状態をValueとする。Valueは複数あってもよい。
allowd.Add(State.Wait, new() { State.Ready });
allowd.Add(State.Ready, new() { State.Wait, State.Move });
allowd.Add(State.Move, new() { State.Wait });
}
// 状態遷移可能であればTrue
public static bool CanTransit(this State from, State to)
=> allowd[from].Contains(to);
}
使う側
var state = State.Move;
var b = state.CanTransit(State.Wait);
// b: True
おわり
気が向いたらチャプター3以降も書く
Discussion