こんにちは、虎の穴ラボのH.Kです。
今回は『Software Design 2021年3月号』を読んだ感想と、オブジェクト指向についての個人的な考えを書きます。
虎の穴ラボでは、福利厚生として技術書の購入補助があり、その制度を利用し、購入いたしました。
はじめに
今回、紹介させていただく、『Software Design 2021年3月号』についてです。
Software Design 2021年3月号
書名 | Software Design 2021年3月号 |
---|---|
電子版発行日 | 2020 年 8 月18 日 初版 第1刷発行 |
発行所 | 株式会社技術評論社 |
紹介ページ | https://gihyo.jp/magazine/SD/archive/2021/202103 |
3月号では特集としてオブジェクト指向プログラミングについて取り上げられていたので、雰囲気で使っているオブジェクト指向を正しく理解するために読んで見ることにしました。
虎の穴開発室ブログで『Software Design』を取り上げさせていただくのは2回目となります。
🔻前回はこちら🔻
toranoana-lab.hatenablog.com
購入のモチベーション
私は文系の大学を卒業し、新卒でIT系企業に入り、初めてJavaを触った人間です。
Java歴は5年くらいですが、最近はRuby( on Rails)を書くことが多くなっています。
JavaもRubyもオブジェクト指向型の言語なので、オブジェクト指向への理解を深め、実際の開発に活かしていければと思い、購入しました。
特集:"Javaでもう一度学び直す オブジェクト指向プログラミング"の紹介
この特集は以下の5章に分かれています。
- 第1章:オブジェクト指向への再入門
- 第2章:Javaならではのオブジェクト指向とは
- 第3章:クラスを適切に設計して独自の型を表現する
- 第4章:型を基準に理解するインターフェースの使い方
- 第5章:継承疲れに効くコンポジション/列挙型のススメ
第1章と第2章ではオブジェクト指向とは何か、Javaで学ぶ動機というバックグラウンド的な説明がなされています。
これにより、「オブジェクト指向って名前は聞いたことあるけど中身は全然わからない」という方にも安心な内容になっています。
第3章からは具体的にオブジェクト指向の適用方法と、解決できる課題が示されていきます。
第1章をJavaチャンピオンである谷本心さん、第2章をJapan Scala Association代表理事を務められている水島宏太さん、第3章から第5章はドメイン駆動設計に造詣が深い増田亨さんが書かれています。
特集を読んだ感想
オブジェクト指向プログラミングの概要を把握し、やりがちな過ちについてガイドラインを示してくれます。
「本来はこうすべきだよな」と思いながら実践できていないようなところが、数多く書いてあり、少し耳が痛い部分もありました。
第1章ではジャンケンのプログラムを例にとって、オブジェクト指向の原則と学ぶ動機を示してくれます。
コラムとしてオブジェクト指向の説明に犬や猫を用いることの是非が書かれており、自分なら何で教えようかと考えるきっかけにもなりました。
第3章の「クラスを適切に設計して独自の型を表現する」はドメイン駆動開発での値オブジェクト(Value Object)のエッセンスを多分に含んだものになっています。
第3章以降を書いている増田亨さんの『現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法』を参照するとより詳しく理解できます。
この3章ではオブジェクト指向の考え方にあまり則していない(作ってはいけないクラスの)例として、java.lang.Math
クラスがあげられています。
docs.oracle.com
(先日Java 16がリリースされましたが、日本語のドキュメントにしたいのでJava 15のリンクです。)
Mathクラスはデータを内部(インスタンスの変数)に持たず、処理に必要なデータはすべて引数で受け取ります。
int a = 10; int b = 20; System.out.println(Math.max(a, b));// 20
このようなクラスが「作ってはいけない」となると結構大変そうです。
上記のようなクラスは、ユーティリティクラス(またはヘルパークラス)と呼ばれています。
例としてはSpringFrameworkのStringUtils
などが有名でしょうか?
では、ユーティリティクラスなしでどのようにすれば良いかという話になるかと思いますが、今回の特集記事には代わりにこうすれば良いという直接的な記載がありませんでした。
個人的な解釈ではユーティリティクラスに必要な処理に関しては値オブジェクトに役割を持たせるべきだと感じました。
従来Utilsを使った呼び出しではこのように実装されるものを
var familyName = user.getFamilyName(); var firstName = user.getFamilyName(); var fullName = familyName + familyName; if (!StringUtils.hasLength(fullName)) { fullName = "名無しの権兵衛"; }
値オブジェクトを使うとこのような形で記述できます。
値オブジェクト
public class Name { private String firstName; private String familyName; // コンストラクタ Name(String firstName, String familyName) { if (firstName == null || familyName == null) { throw new IllegalArgumentException("名字か名前が入力されていません。"); } this.firstName = firstName; this.familyName = familyName; } String getFullName() { return this.familyName + this.firstName; } boolean hasName() { return this.getFullName().length != 0; } }
実際の呼び出し部分
var userName = new Name(hoge, piyo); var fullName = userName.getFullName(); if (userName.hasName()) { fullName = "名無しの権兵衛"; }
比較するために"名無しの権兵衛"の設定を呼び出し側で実施しましたが、業務として「名前が設定されていなければ"名無しの権兵衛"をフルネームとする」と決まっているのであれば、値オブジェクト内に実装すべきです。
また、ユーティリティクラスを使うべきではないということについては、Yegor Bugayenkoさんがブログで詳しく語っているので、そちらを読むと理解の一助になります。
とはいえ、正直に言えばここまで実装していくのは大変なので、開発していく分にはユーティリティクラスを使いつつ、できる限りクラスの凝縮度をあげていく方向が良さそうです。
ここからは完全に個人の意見です。
オブジェクト指向は効率よく(開発中、そして開発後も)実装する手段であり、目的ではありません。
そのため必要以上にオブジェクト指向と厳密に向き合い、完璧なオブジェクト指向プログラミングを求めることは不要だと考えています。
手段と目的を見誤ることなく、適切にオブジェクト指向プログラミングを使っていきたいと感じました。
第5章では継承を使わず、コードを再利用するテクニックが書かれており、非常に勉強になりました。
また、この章では長いメソッドをprivateなメソッドに切り出していく、リファクタリング方法についても解説されています。
この方法は私も業務で似たようなやり方をしているので、効果的だったのだと実感しました。
おわりに
オブジェクト指向プログラミングの入門・再入門として、ここまでコンパクトにまとめてある書籍はなかなかないです。
この特集で説明されている原理・原則を知ることで幅広いプログラムにオブジェクト指向を適用していけるのではないかと思います。
また『Software Design』は今回の記事で取り上げた、オブジェクト指向プログラミングの特集以外にもWebAssemblyについての特集やGitコマンドの使い方など、幅広いエンジニアに向けて学ぶきっかけを与えてくれる、ありがたい雑誌です。 技術書の購入は、自分の知っている領域に偏りがちなので、"エンジニアの総合誌 "である『Software Design』を今後も読んでいこうと思いました。
P.S.
■採用情報
yumenosora.co.jp
■ToraLab.fmスタートしました!
メンバーによるPodcastを配信中!
是非スキマ時間に聞いて頂けると嬉しいです。
■Twitterもフォローしてくださいね!
ツイッターでも随時情報発信をしています
twitter.com