いいコードとは、悪くないコードのことを指すと考えています。
そして、悪くないコードを目指していくには、Code Smellsに注目すると改善できます。
今回の記事では、Code SmellsのなかのPrimitive Obsession(基本データ型の執着)に注目します。
Primitive Obsession(基本データ型の執着)とは
用意されているデータ型しか使わないことを指します。Javaだとintやlong等をプリミティブ型と言いますが、そのプリミティブ型とは異なります。
用意されているデータ型だけだと、どんなデータが入りうるかわかりません。ですので、自分たちが作成した型を用意することで、より表現力を高めることができます。
具体的な例
例えば、本にはISBNという全世界共通で本を一意に特定できるIDがあります。ですので、Book型にはString型でISBN型を持たせるとします。
public Book{ private String isbn; }
この時、ISBNはどんなデータが入りうるでしょうか。全世界共通で本を一意に特定できるIDということで、採番ルールやどんなデータ型なのかも定められています。しかし、現状のコードはString型であることしか語ってくれません。まずは、ラップしただけのISBN型を作りましょう。
public Book{ private Isbn isbn; } public Isbn{ private String value; }
これでISBN型というものが表現できました。しかし、現状ではあまり価値はありません。なぜなら、データが表現しきれていないからです。
詳しい制約は省きますが、ISBN型は10桁、13桁以外はありえません。ですので、10桁や13桁以外のデータでISBNを生成しようとしたらエラーとなるようにし ましょう。
public Isbn { private String value; Isbn(String value){ if (!(code.length() == 10 || code.length() == 13)) { throw new RuntimeException("ISBNの桁数が正しくない"); } this.value = value; } }
このように、言語が用意した基本型ではなく、自分たちが用意したデータ型を使用することで、どんなデータが入りうるかが表現できるようになります。
型があることで、表現の幅が広がります。動的型付言語であればわかりませんが、静的型付言語であれば型で表現するメリットは大きいので、ぜひ利用してください。
コレクション型もラップする(FCC, First Collection Class)
ListやMap等もラップした型を作ったほうが伝えやすいです。このコレクション型をラップする方法はFCC(First Collection Class)とも言われています。
例えば、カードゲームのUNOをListのまま表現するとこうなります。
public class UnoGame{ List<Card> cardList1; List<Card> cardList2; List<Card> cardList3; }
自分の番の時、「カードリスト1」から「カードリスト3」に重ねられるカードがあるとき、「カードリスト1」から1枚を選んで「カードリスト3」に重ねます。 もし、「カードリスト3」に重ねられないとき、「カードリスト2」から1枚を「カードリスト1」に加えます。
こちらは分かりやすいでしょうか。カードリスト1とか3とか、非常にわかりづらいですね。変数名をわかりやすくしても、変数名は噓をつくこともできるので、限界があります。
ですので、カードリスト1等々をラップした型を作成します。
public class UnoGame{ 手札 cardList1; 山札 cardList2; 場札 cardList3; } public class 手札{ List<Card> list; } public class 山札{ List<Card> list; } public class 場札{ List<Card> list; }
自分の番の時、「手札」から「場札」に重ねられるカードがあるとき、「手札」から1枚を選んで「場札」に重ねます。 もし、「場札」に重ねられないとき、「山札」から1枚を「手札」に加えます。
非常にわかりやすくなっているのではないでしょうか。このように表現できると、「カードリストを捨てる」といった表現では気づけなかったことに気づけます。「山札を捨てる」「手札を捨てる」「場札を捨てる」と表現をしたときに、「手札を捨てる」以外の表現に違和感を感じられるのではないでしょうか。コーディングやリーディングでのヒントを与えられるのは大きいです。
ソースコード
ISBN.java github.com
終わりに
コードが仕様を伝えられるようになると、可読性が上がるので非常に強いです。
まぁ、余計なコードを管理しなければならないので、嫌いな人は嫌いかもしれませんが…。
型を意識的に作ろうと思わないと絶対に作らないので、ぜひ覚えていってほしいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考
Primitive Obsession refactoring.guru