「static修羅道」Step05:ユーティリティクラスを構築せよ

0005_static修羅道-step05 learn

まずは問題を見ろ

javadrill.tech で出題された問題を見る(Step05)


問題のポイント

  • 状態を持たず「処理だけ」を提供するクラスは、すべてstaticにすべき
  • newせずに使える = staticメソッドだけで構成される「ユーティリティクラス」
  • Java標準の MathCollections がその代表例

まず、日本語で考えろ

  • 「nullや空文字か?」を判定する関数を、あちこちで使いたい
  • 「先頭1文字を大文字にする」関数もほしい
  • それらは状態を持たない共通処理 → 毎回newして使うようなものじゃない
  • → だったら、staticメソッドとしてクラスにまとめておけ

コメントを書け

// StringUtil クラスを定義
// isNullOrEmpty(String str) → nullまたは""ならtrue
// capitalize(String str) → 先頭を大文字に変換
// すべてstaticメソッドとして定義
// クラスはインスタンス化禁止(privateコンストラクタ)

コメントに従って、コードを書け

public class StringUtil {

  public static boolean isNullOrEmpty(String str) {
    return str == null || str.isEmpty();
  }

  public static String capitalize(String str) {
    if (str == null || str.isEmpty()) return str;
    return str.substring(0, 1).toUpperCase() + str.substring(1);
  }

  private StringUtil() {
    // 工具箱にnewは要らん
  }
}
public class Main {
  public static void main(String[] args) {
    System.out.println("isNullOrEmpty(null): " + StringUtil.isNullOrEmpty(null));
    System.out.println("isNullOrEmpty(\"\"): " + StringUtil.isNullOrEmpty(""));
    System.out.println("isNullOrEmpty(\"hello\"): " + StringUtil.isNullOrEmpty("hello"));
    System.out.println("capitalize(\"hello\"): " + StringUtil.capitalize("hello"));
    System.out.println("capitalize(\"\"): " + StringUtil.capitalize(""));
  }
}

コードの解説

  • ユーティリティクラスは 「インスタンス化させない」設計思想 に基づいている
  • 状態を持たない → newする意味がない
  • だからメソッドはすべて static、クラス自体は private コンストラクタでロック

つまづきやすいポイント

  • 「newして使っても動くじゃん」→ 動くけど設計としてダメ
  • 工具箱を毎回newしてたら不自然
  • Javaの世界では、状態を持たないものはstaticにするのが常識

// tesh:
// 「使うたびに new するのが正しいんでしょ?」って?──いやいや、それは設計を知らんヤツのセリフや。
// 
// おまえが今作ってる StringUtil みたいなやつはな、“状態を持たず、処理だけ提供する” という、はっきりした役割がある。
// 言い換えりゃ、道具箱や。
// 
// ハサミを使うたびに「ハサミクラス new して…」ってやってたら現場回らんやろ?
// 道具箱は一個あればええ。それが staticメソッドだけで構成されたユーティリティクラス や。
// 
// Javaの世界で、Math.abs() や Collections.sort() を new して使ってるヤツ、おらんやろ?
// それは「道具箱として提供された」static設計だからや。
// 
// だからオレたちも、自分でよく使う処理は「共有工具箱」としてまとめるんや。
// isNullOrEmpty() とか capitalize() とか、使いまくる処理ほど static化しとけ。
// 
// で、重要なのが private コンストラクタ。
// 「工具箱なのに new できる」ってのは、現場でネジ落とすようなもんや。使い方をコードで制限する、それが設計。
// 
// コードは「動けばいい」じゃない。「意図を持って、破らせない」までやって初めてプロの仕事や。
// 
// staticメソッドは“便利だから”じゃなく、“newする必要がないから”。
// その逆算の発想を持て。
// 
// 工具箱の設計もできんやつに、現場は任せられんで。

static修羅道(ステップ一覧)へ戻る