本ページはプロモーションが含まれています

IT全般

良いコード/悪いコードで学ぶ設計入門の書評|低凝集・密結合が刺さり、分岐と名前の付け方を変えた

CATEGORY
REV.
DRAWN BY
TOM
SHEETS
8枚
良いコード/悪いコードで学ぶ設計入門(低凝集と密結合が刺さった)

トム

SESで約8年、環境を変えられないもどかしさの中にいました。32歳で自社開発企業に転職し、今はClaude Codeと自動化で、仕事も時間も組み直している途中です。
・Javaバックエンドエンジニア(Java歴12年以上)
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎
詳細なプロフィール

𝕏

設計の基本をちゃんと学びたい。そう思って読んだのが『良いコード/悪いコードで学ぶ設計入門』です。

結論から言うと、動くコードは書けるけれど、変更しやすいコードの書き方を体系的に知りたい人に合う1冊です。悪い構造の例から入り、低凝集・条件分岐・密結合といった型ごとに直し方を見ていく作りです。

私にいちばん役に立ったのは、低凝集と密結合の章でした。読んでから、条件分岐の書き方と、名前の付け方を変えています。説明用のJavaのコードで見せながら書きます。

良いコード/悪いコードで学ぶ設計入門はどんな本か

書名良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方
著者仙塲大也
出版社技術評論社
発売日初版:2022年4月/改訂新版:2024年12月25日
ページ数・定価初版:400ページ(A5判)・3,278円(税込)/改訂新版:408ページ(A5判)・3,520円(税込)
受賞ITエンジニア本大賞2023 技術書部門 大賞

書誌情報は技術評論社の初版の書籍ページと改訂新版の書籍ページによるものです。いま買うなら改訂新版です。私はKindleで読んだのですが、どちらの版だったかは覚えていません。この記事の章の名前は、初版の書籍ページの目次によるものです。

初版は全17章で、大きく3つのまとまりに分けられます(分け方は私の整理です)。

初版17章の3つのまとまり(悪いコードを知る → 型ごとに直す → 設計と向き合う)
1
第1〜4章悪いコードを知る・基本1 悪しき構造の弊害を知覚する/2 設計の初歩/3 クラス設計/4 不変の活用
2
第5〜13章悪いコードの型と直し方5 低凝集/6 条件分岐/7 コレクション/8 密結合/9 さまざまな悪魔たち/10 名前設計 ほか
3
第14〜17章設計との向き合い方14 リファクタリング/15 設計の意義/16 開発プロセスとの戦い/17 理解の深め方
NOTE章の見出しは技術評論社の書籍ページ(初版)の目次による。3つの分け方は筆者の整理

読んだきっかけ|設計の基本を学びたかった

LOG設計を学びたかったころ設計の基本を、体系的に知りたい

悩みがあったというより、設計の基本をきちんと学びたくて読みました。

役に立ったところ|低凝集と密結合

いちばん役に立ったのは、第5章「低凝集 ―バラバラになったモノたち―」と、第8章「密結合 ―絡まって解きほぐせない構造―」です。

低凝集と密結合(バラバラすぎても、絡まりすぎても、変更しにくい)
第5章 / バラバラ低凝集関係するデータとロジックが、バラバラの場所にある。例:データだけのクラスと、計算だけのUtilクラス
第8章 / 絡まる密結合別々の役割のものが、絡まって切り離せない。例:片方を直すと、関係ない機能まで壊れる
NOTE章の見出しは技術評論社の書籍ページ(初版)の目次による。説明は筆者の言い換え

低凝集:データとロジックが離れている

第5章には「staticメソッドの誤用」「初期化ロジックの分散」「共通処理クラス(Common・Util)」といった節があります。たとえば、注文のデータを持つクラスと、注文の計算をするUtilクラスが分かれている状態です(説明用の例)。

// 低凝集:データとロジックが別々の場所にある
public class OrderUtil {
    public static int calcTotal(Order order) { ... }
    public static boolean canCancel(Order order) { ... }
}

// Order はデータを持つだけ。どこで何が計算されるかは、Util を探さないと分からない
public class Order {
    public List<OrderItem> items;
    public OrderStatus status;
}

関係するデータとロジックを同じクラスにまとめると、注文について知りたいときは Order を見るだけで済みます。

// 凝集度が高い:関係するデータとロジックを同じクラスに置く
public class Order {
    private final List<OrderItem> items;
    private OrderStatus status;

    public Money total() { ... }
    public boolean canCancel() { ... }
}

密結合:別の役割が絡まっている

第8章には「密結合と責務」という節と、「共通化の罠」「継承」というコラムの見出しがあります。似ているからといって、役割の違う処理を1つのメソッドやクラスにまとめると、片方の仕様が変わったときに、もう片方まで巻き込んでしまいます。

似ているだけで共通化すると、絡まる
1
会員向けと法人向けの割引計算が似ている
2
1つの共通メソッドにまとめる
3
会員向けだけ割引のルールが変わる
4
NG / ハマり共通メソッドを直すと、法人向けまで変わってしまう
NOTE説明用の例。役割(責務)が違うなら、見た目が似ていても分けておく

読んでから変えたこと|条件分岐を減らす・名前を目的で付ける

読んでから、2つのことを変えました。職場のコードは載せられないので、説明用のJavaのコードで見せます。

1. 条件分岐を減らした

第6章「条件分岐 ―迷宮化した分岐処理を解きほぐす技法―」には、「条件分岐のネストによる可読性低下」「switch文の重複」「interfaceの使いこなしが中級者への第一歩」といった節があります。ネストした if や、あちこちに同じ switch が出てくるコードは、読むのも直すのも大変です。

// ネストとswitchで分岐している
public int shippingFee(Member member, int price) {
    if (member != null) {
        if (price < 3000) {
            switch (member.rank()) {
                case GOLD:   return 0;
                case SILVER: return 300;
                default:     return 500;
            }
        }
        return 0;
    }
    return 500;
}

まず、早期returnで条件を先に片付けて、ネストをなくします。

// 早期returnで、ネストをなくす
public int shippingFee(Member member, int price) {
    if (member == null) return 500;
    if (price >= 3000) return 0;
    return member.rank().shippingFee();
}

会員ランクごとの違いは、ランクの側に持たせます。新しいランクが増えても、switch を探して回る必要がなくなります。ここではenumで書いていますが、ランクごとの処理が大きくなるなら、interface にして実装を分ける形にします。

// 会員ランクごとの違いは、ランク側に持たせる(switchの重複をなくす)
public enum Rank {
    GOLD(0), SILVER(300), REGULAR(500);

    private final int shippingFee;

    Rank(int shippingFee) {
        this.shippingFee = shippingFee;
    }

    public int shippingFee() {
        return shippingFee;
    }
}

interfaceと抽象クラスの使い分けはJavaの抽象クラスとはにまとめています。

2. 名前を目的で付けるようにした

第10章「名前設計 ―あるべき構造を見破る名前―」には「目的駆動名前設計」という節と、「Managerクラス」というコラムの見出しがあります。Manager・Util・Common のような名前は何でも入れられるので、気づくと1つのクラスに役割が集まってしまいます。

// 何でも入る名前
class ProductManager { ... }
class CommonUtil { ... }

// 目的で付けた名前(何をするためのものかで分ける)
class StockReservation { ... }   // 在庫を引き当てる
class PurchaseOrder { ... }      // 仕入れ先に発注する
class ShippingFee { ... }        // 送料を計算する

「何をするためのものか」で名前を付けると、そのクラスに入れてよいもの・いけないものが名前から決まります。名前を考えることが、そのままクラスの分け方を考えることになります。

今のレベル別の読み方

目次を見る限り、悪いコードの型ごとに章が分かれているので、気になる章から読み始められます。

今の自分読む章ねらい
設計を意識してコードを書いたことがない第1章 → 第2章 → 第3章悪い構造の例と、クラス設計の基本を押さえる
動くコードは書けるが、変更しにくいと感じる第5章 → 第6章 → 第8章 → 第10章低凝集・条件分岐・密結合・名前の型を知る
チームや既存コードの設計を良くしたい第14章 → 第15章 → 第16章リファクタリングの進め方と、設計を妨げる開発プロセスへの向き合い方を知る

向いている人・向いていない人

  • 向いている人:設計の基本を体系的に学びたい人。動くけれど変更しにくいコードを、どう直せばいいか知りたい人
  • 向いていない人:特定のフレームワークやライブラリの使い方を知りたい人。この本はクラスやメソッドの設計の本です

出版社の紹介でも、対象読者は「コードの設計スキルに興味がある人」「悪いコードと向き合い、改善したい人」とされています。

あわせて読みたい

読んだ本はほかにも、トムの本棚に並べています。

よくある質問

Q. 初版と改訂新版、どちらを買えばいいですか?

いま買うなら改訂新版です。技術評論社の書籍ページでも、初版のページに新版が出ていると案内されています。この記事の章の名前は初版の目次なので、改訂新版では章の構成が変わっている可能性があります。

Q. Java以外の言語でも役に立ちますか?

初版の目次には「種類の異なる言語と本書のノウハウ」というコラムや、C#・Railsに触れたコラムの見出しがあり、ほかの言語で使うことも意識された作りです。

Q. 電子版はありますか?

改訂新版は電子版もあります(技術評論社の電子版ページがあります)。私もKindleで読みました。

REVISIONS / 改訂履歴
REV.DATE内容
22026-10-16図解を描き直し(図面のデザインにそろえた)
12026-10-12初版
NEXT STEP
今のプロジェクトで、名前に Util・Common・Manager が付くクラスを1つ探してみてください。

中のメソッドを「何のためのものか」で分けてみると、本来いるべきクラスが見えてきます。

NEXT READ本棚から1本

AIで開発を組み直すなら、まずこの5冊から

入門・実践・設計まで、Claude Codeの本をレベル別に5冊選んで比べました。

→ おすすめ5冊を見る

  • この記事を書いた人
  • 最新記事

トム

SESで約8年、環境を変えられないもどかしさの中にいました。32歳で自社開発企業に転職し、今はClaude Codeと自動化で、仕事も時間も組み直している途中です。
・Javaバックエンドエンジニア(Java歴12年以上)
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎
詳細なプロフィール

𝕏

IT全般 ・