書籍概要

WEB+DB PRESS plus

良いコードを書く技術
― 読みやすく保守しやすいプログラミング作法

著者
発売日
更新日

概要

読みやすく保守しやすい「良いコード」の書き方を解説した入門書です。『WEB+DB PRESS』で断トツ人気だった連載を加筆・修正して書籍化しました。

本書を読むと,良いコードを書くための習慣から名前の付け方,コードの分割や集約を行う方法,抽象化の作法,計算量とアルゴリズム,ユニットテストやメタプログラミングまで,プログラマとして長く役立つ基本が身につきます。

こんな方におすすめ

  • 良いコードを書きたいけれども、何から手を付けていいかわからない方々
  • 読みやすく保守しやすいコードを書きたい方々
  • 良い仕事をしたい普通のプログラマの方々
  • 達人プログラマを目指す中級プログラマの方々
  • 新人に良いコードとは何かを知ってほしい先輩・上司・達人プログラマの方々

本書に関するお知らせ

本書の公式タグはgoodcodeです。

本書に関連する記事を公開しております。

目次

  • はじめに
  • 謝辞
  • コード例について
  • サポートページ
  • 公式タグ

第1章 良いコードとは何か

  • 1.1 良いコードの定義と価値
  • 1.2 良いコードの定義
    • 保守性が高い
    • すばやく効率的に動作する
    • 正確に動作する
    • 無駄な部分がない
  • 1.3 良いコードの価値
    • プロジェクトを強力に推し進める
    • プログラマとしての評価が高まる
    • 仕事に満足感や自信が持てるようになる
  • 1.4 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 1.5 まとめ

第2章 良いコードを書くための5つの習慣

  • 2.1 良いコードは1日にしてならず
  • 2.2 習慣その1 読む──コードを読んで読んで,読みまくれ!
    • Column:コード検索サービスでコードの海を泳ぐ
  • 2.3 習慣その2 書く──とにかくコードを書きましょう
    • Column:1人でプログラムを書けますか?
  • 2.4 習慣その3 道具を磨く──使う道具は常に磨いておこう
    • エディタ/統合開発環境
    • 自動化
    • バージョン管理ツール
    • UNIX/Linux/Mac OS X
    • Column:良い道具に乗り換える
  • 2.5 習慣その4 知る──良い知識を得よう
    • 書籍──原典とHow To本の2冊買いがお勧め
    • リファレンスや仕様書などのドキュメント
    • Webサイト
  • 2.6 習慣その5 聞く──アウトプットと人からのフィードバックでさらなる成長を
    • コードレビューを受ける
    • ブログを書く
    • コミュニティや勉強会に参加する
    • 成果を発表する
  • 2.7 まとめ

第3章 名前付け

  • 3.1 良いコードは良い名前から生まれる
  • 3.2 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 3.3 良い名前の条件
    • 説明的で意味・意図を表している
    • 一貫性がある
    • 英語で付けられている
    • イディオムに従っている
    • コーディング標準に従っている
    • Column:名前の流行り廃り
  • 3.4 変数名
    • 基本は説明的な名前を付ける
    • グローバル変数,クラス変数,フィールド変数──意味を正しく表現する
    • Column:変数の種類
    • ローカル変数──スコープの長さで使い分け
    • メソッドの引数名──わかりやすく簡潔に
  • 3.5 メソッド名
    • Column:メソッドの種類
  • 3.6 クラス名
    • クラス名のボキャブラリは経験とともに高まる
  • 3.7 パッケージ/ネームスペース名
  • 3.8 プロジェクト名
  • 3.9 まとめ
    • Column:Cubbyのクラス名の変遷

第4章 スコープ

  • 4.1 スコープを意識していますか?
  • 4.2 スコープって何?
  • 4.3 スコープを小さくして覚えておくことを減らそう!
  • 4.4 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 4.5 変数のスコープ
    • ローカル変数
    • Column:JavaScriptの奇妙なスコープ
    • フィールド変数
    • クラス変数
  • 4.6 メソッドのスコープ
    • インスタンスメソッド
    • クラスメソッド
    • メソッドの引数の情報量
  • 4.7 クラスのスコープ
    • インナークラス
    • 無名クラス
  • 4.8 キャストを使用した可視性の制御
  • 4.9 より大きな粒度のスコープ
  • 4.10 まとめ

第5章 コードの分割

  • 5.1 適切な長さにコードを分割する
  • 5.2 なぜコードを分割するのか
    • 可読性が向上する
    • 保守性が向上する
    • 再利用性が向上する
  • 5.3 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 5.4 2つの方向からの分割
    • トップダウン方式
    • ボトムアップ方式
  • 5.5 お題 クライアントにXMLを返すWeb APIの処理を分割
  • 5.6 ステップ1 ベタなコードで書いてみる
  • 5.7 ステップ2 共通処理をメソッドに抽出して分割する
    • 考察 どこまで共通化を行えばいいの?
  • 5.8 ステップ3 処理単位で分割する
    • 考察 制御構造と処理の分け方
  • 5.9 ステップ4 状態を持つ処理をクラスに抽出して分割する
    • 考察 インナークラスとして実装しているのはなぜ?
    • 考察 必要なデータをコンストラクタで渡しているのはなぜ?
    • 考察 フィールド変数として保持したほうがよいものは何?
    • 考察 さらにリファクタリングしてみる
  • 5.10 まとめ

第6章 コードの集約

  • 6.1 コードの重複は悪
  • 6.2 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 6.3 メソッドに抽出してまとめる
  • 6.4 継承でまとめる
    • 継承でのまとめ方には注意
  • 6.5 ユーティリティクラスにまとめる
    • Javaではstaticインポートと組み合わせると便利
    • ユーティリティクラスの名前付け
  • 6.6 サービス層にまとめる
  • 6.7 オブジェクトにまとめる
  • 6.8 定数にまとめる
  • 6.9 まとめ
    • Column:まとめ過ぎにご用心

第7章 コードのパフォーマンス

  • 7.1 パフォーマンスを意識していますか?
  • 7.2 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 7.3 パフォーマンスは計算量で決まる
    • アルゴリズムの選択で変わる
    • クラスの選択で変わる
    • ライブラリの使い方で変わる
  • 7.4 パフォーマンスチューニングの手順
    • (1)まずは測定する
    • (2)原因を特定する
    • (3)チューニングする
    • (4)チューニング結果を測定する
  • 7.5 アルゴリズムの選択以外のパフォーマンスチューニング
    • SQLやテーブル設計を変更する
    • キャッシュする
    • インフラを強化する
  • 7.6 パフォーマンスチューニングの指針
    • どのタイミングでチューニングするのがベストなの?
    • 適切な量のテストデータを用意しよう
    • 常にパフォーマンスを意識しよう
  • 7.7 まとめ

第8章 ユニットテスト

  • 8.1 テストはお好きですか?
  • 8.2 ユニットテストって何?
  • 8.3 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 8.4 ユニットテストの効能
    • 網羅的なテストを自動化できる
    • 回帰テストによりコードが壊れていないことを保証できる
    • 設計の改善につながる
  • 8.5 お題 Webアプリケーションのセキュリティテスト
  • 8.6 ステップ1 データベースにテストデータを登録する
  • 8.7 ステップ2 画面の実装
  • 8.8 ステップ3 画面のユニットテスト(正常系)
  • 8.9 ステップ4 画面のユニットテスト(異常系)
  • 8.10 ユニットテストの指針
    • テストのポリシーを決めておこう
    • テストしやすい部分はどこ?
    • テストしにくい部分はどうする?
  • 8.11 まとめ
    • Column:言語別のテスティングフレームワーク

第9章 抽象化

  • 9.1 抽象化がプログラミングのパワーを最大化する
  • 9.2 配列/コレクションって何?
  • 9.3 配列/コレクションを利用した抽象化とは?
  • 9.4 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 9.5 お題 画像ファイルの一覧を表示するWebアプリケーション
  • 9.6 ステップ1 ベタなコードで書いてみる
  • 9.7 ステップ2 可読性を高めるためのメソッド抽出
  • 9.8 ステップ3 関連するデータのデータ構造を整理
  • 9.9 ステップ4 配列/コレクション化して抽象化
  • 9.10 抽象化の指針
    • どのタイミングで抽象化するのがベストなの?
    • コードの重複をまとめるな!?
    • これって単なるループなんじゃない?
  • 9.11 まとめ

第10章 メタプログラミング

  • 10.1 プログラミングをプログラムする
  • 10.2 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 10.3 メタプログラミングって何?
    • コードの自動生成
    • DSL
    • Column:流れるようなインタフェースとstaticインポートによる内部DSL
  • 10.4 お題 Excelを使った外部DSL
    • Excelのメリットとデメリット
    • 固定長電文解析処理をDSLで処理する
  • 10.5 ステップ1 ベタなコードで書いてみる
    • 考察 インナークラスを使っているのはなぜ?
  • 10.6 ステップ2 メタデータをExcelに移動する
    • 考察 メタデータって何?
  • 10.7 ステップ3 リフレクションAPIで変換ルールを動的に適用する
    • Column:JavaのリフレクションAPI
    • ストラテジパターン
    • 考察 複数の変換パターンを適用したい場合は?
    • 考察 変換ルールに引数を追加したい場合は?
    • 考察 DSLの構文を改善するには?
    • 考察 DSLのテストはどうする?
    • 考察 DSLのデバッグはどうする?
    • 考察 これはフレームワーク? それともDSL?
  • 10.8 まとめ

第11章 フレームワークを作ろう

  • 11.1 フレームワークの動作原理を知る
  • 11.2 代表者の声
    • 良い仕事をしたい普通のプログラマ
    • 達人プログラマを目指す中級プログラマ
    • 達人プログラマ
  • 11.3 お題 Webアプリケーションフレームワークを作ろう
  • 11.4 ステップ1 素のサーブレットで書いてみる
  • 11.5 ステップ2 フロントコントローラとアクションクラスの導入
  • 11.6 ステップ3 ルーティング情報の外部ファイル化
  • 11.7 ステップ4 よく使う処理を簡単に実行できるように共通化する
    • 考察 これからさらにフレームワークを拡張するには?
  • 11.8 ステップ5 フレームワークをパッケージ化する
    • (1)フレームワークのコードとアプリケーションコードを分ける
    • (2)パッケージ化する
    • (3)バージョンを付けて管理する
  • 11.9 まとめ

付録A コードリーディングの方法

  • A.1 コードには動的な読み方と静的な読み方がある
  • A.2 お題 Apache Commons IOのコードを読む
  • A.3 ステップ1 対象のコードをダウンロード(チェックアウト)する
  • A.4 ステップ2 静的な方法でコードを読む
    • 検索コマンドを使う
    • Eclipseなど統合開発環境を使う
    • EmacsやVimでタグジャンプ機能を使う
  • A.5 ステップ3 動的な方法でコードを読む
    • デバッガで実行する
    • ユニットテストを実行する
    • コードを修正して実行する
    • 部分的なコードをコピーして使ってみる
  • A.6 まとめ

付録B 解説付き参考文献

サポート

ダウンロード

本書で使用しているサンプルコードを,ダウンロードとGitHubで公開しています。

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2020年10月28日最終更新)

P.69 「分割してみました !!」の後の9行目のコード

Map<String,Stirng params) {
Map<String,String> params) {

以下,第1刷から第2刷まで。第3刷以降および最新の電子版では修正済み
P.28 Column「変数の種類」のコード最終行

for (int i = 0; i < mail.length; i++) {
for (int i = 0; i < mails.length; i++) {

P.35 Column「メソッドの種類」のコード5行目

for (int i = 0; i < mail.length; i++) {
for (int i = 0; i < mails.length; i++) {

P.69 「分割してみました !!」の後の下から3行目のコード

Transport.send(message);
Transport.send(msg);

P.131 コラム「言語別のテスティングフレームワーク」の表8.a

Test::Simplehttp://search.cpan.org/dist/Test-Simple/
Test::Morehttp://search.cpan.org/dist/Test-Simple/lib/Test/More.pm

P.169 表10.3「Excelによる電文仕様書(変換ルールを追加」 の5行目

converter.IntegerConverte
converter.IntegerConverter

P.193 図 11.5 「ステップ4のクラス図」

ListActisn
ListAction

以下,第1刷まで。第2刷以降および最新の電子版では修正済み
P.35 Column「メソッドの種類」の最終行のコード

MailSender sender = sender.create();
MailSender sender = MailSender.create();

P. 45「ローカル変数」の2行目

JavaやRubyなどのローカル変数は、宣言された場所からスコープが始まり、宣言されたブロックが終わるとスコープが終了します。
Javaのローカル変数は、宣言された場所からスコープが始まり、宣言されたブロックが終わるとスコープが終了します。

P.135の15行目

List<String> names = new ArrayList();
List<String> names = new ArrayList<String>();

P.149「リスト9.6」の26行目

return new Files(path, files);
return new ImageFiles(path, files);

P.190「リスト11.12」の23行目

Class clazz = Class.forName(className);

Class<?> clazz = Class.forName(className);

商品一覧