『プリンシプル オブ プログラミング』を10問で学べるクイズサイト

コードレビュー道場 #2
密結合な設計を疎結合に変えよ!

公開日:
最終更新日:

このページでは、『プリンシプル オブ プログラミング』で登場する凝集度/結合度の考え方を、実際のコード断片を使ったコードレビュー形式の4択クイズで体験します。

クラス同士や関数同士がべったりつながった密結合な設計を見抜き、責務のまとまりを意識した高凝集・低結合な形へ近づけるための視点を鍛えていきましょう!

今すぐクイズに挑戦
(10問・約3分・解説つき)
プリンシプルオブプログラミング
1分で理解&101の原則総まとめ!

目次

  1. クイズに挑戦する(10問)

  1. プログラミング クイズ一覧へ
  2. コードレビュー道場 目次へ
  3. 次のクイズへ(落ちるコードを非機能要件で鍛え直せ!)
  4. 前のクイズへ(DRY/KISSで太りすぎた関数を救え!)
  5. 『プリンシプル オブ プログラミング』101の原理・原則総まとめ

  1. 参考文献・出典
  2. このページの著者
  3. シェア

コードレビュー道場 #2~密結合な設計を疎結合に変えよ!~

1. 次の関数は、1つのパラメータオブジェクトに大量の値を詰め込んでいます。凝集度の観点から、何が問題になりやすいでしょうか?

function createReport(params) {
  // params = {
  //   userId, userName, userAge,
  //   projectId, projectName,
  //   startDate, endDate,
  //   includePrivate, includeDeleted,
  //   ...
  // }
  // 複雑なレポート生成処理
}

2. 次のコードは、注文処理とメール送信を1つの関数にまとめています。凝集度/結合度の観点から、最も問題がある点はどれでしょうか?

function placeOrder(order, db, mailer) {
  // DBへ保存
  db.insert('orders', order);

  // ユーザーにメール送信
  const message = `ご注文ありがとうございます:${order.id}`;
  mailer.send(order.userEmail, message);

  // 画面用メッセージを返す
  return {
    message: '注文完了しました',
    orderId: order.id
  };
}

3. 次のクラスは、リポジトリとサービスが分かれていません。結合度/凝集度の観点から、改善ポイントはどこでしょうか?

class UserManager {
  constructor(db) {
    this.db = db;
  }

  async findById(id) {
    return this.db.query('SELECT * FROM users WHERE id = ?', [id]);
  }

  async changeEmail(id, newEmail) {
    const user = await this.findById(id);
    // ドメインルールのチェック(省略)
    await this.db.execute('UPDATE users SET email = ? WHERE id = ?', [newEmail, id]);
  }
}

4. 次のコードは、メール送信の方法が直接固定されています。結合度の観点から、どの改善が望ましいでしょうか?

function sendPasswordReset(user, token) {
  const url = `https://example.com/reset?token=${token}`;
  const message = `こちらからパスワードを再設定してください: ${url}`;
  SmtpClient.send(user.email, message);
}

5. 次のクラスは、ログ出力と業務ロジックが混ざっています。凝集度/結合度の観点から、どのような改善が望ましいでしょうか?

class PaymentService {
  constructor(http) {
    this.http = http;
  }

  async pay(order) {
    console.log('PAYMENT START', new Date(), order.id);

    const result = await this.http.post('/payments', { orderId: order.id });

    console.log('PAYMENT END', new Date(), order.id, result.status);

    return result;
  }
}

6. 次のコードは、1つのクラスが「設定の読み込み」と「業務ロジック」をまとめて行っています。凝集度の観点から、改善するべき点はどれでしょうか?

class ReportGenerator {
  generate() {
    const config = JSON.parse(localStorage.getItem('report-config') || '{}');
    // config をもとにレポートを生成
  }
}

7. 次のコードは、法則的には「デメテルの法則(LoD)」に違反しやすいパターンです。結合度の観点から、最も問題になりやすい点はどれでしょうか?

function getCustomerCity(order) {
  return order.customer.address.city;
}

8. 次のコードは、UI層からドメインロジックへアクセスする際の結合の仕方を示しています。結合度を下げるために、最も有効な改善はどれでしょうか?

function onClickSaveButton() {
  const user = collectFormData();

  // ドメインロジックを直接 new
  const service = new UserService();
  service.save(user);

  alert('保存しました');
}

9. 次のコードでは、テストしづらい結合が生まれています。結合度の観点から、どこが問題でしょうか?

function calculateDiscount(user, now = new Date()) {
  if (user.isPremium && now.getDay() === 5) {
    return 0.2;
  }
  return 0;
}

10. 次のクラスは、ユーザー情報の表示と更新の両方を担当しています。結合度/凝集度の観点から、最も適切な改善方針はどれでしょうか?

class UserProfileScreen {
  constructor(apiClient) {
    this.apiClient = apiClient;
  }

  async loadUser(userId) {
    const user = await this.apiClient.get(`/users/${userId}`);
    this.render(user);
  }

  async updateUser(user) {
    await this.apiClient.put(`/users/${user.id}`, user);
    this.render(user);
  }

  render(user) {
    // DOMを書き換えてプロフィール画面を描画
  }
}

密結合な設計を疎結合に変えよ!
採点結果

正答率:0%

-

-

参考文献・出典

  • プリンシプル オブ プログラミング ~3年目までに身につけたい一生役立つ101の原理原則~
  • 上田 勲(著)/秀和システム/第1版14刷/2025年/ISBN978-4-7980-4614-3

※本ページは学習支援を目的とした要約です。実務適用時は原典もご参照ください。

このページの著者

もちもちみかん(システムエンジニア)

社内SEとしてグループ企業向けの業務アプリを要件定義〜運用まで一気通貫で担当しています。

経験:Webアプリ/業務システム

得意:PHP・JavaScript・MySQL・CSS

個人実績:フォーム生成基盤クイズ学習プラットフォーム

詳しいプロフィールはこちら!  もちもちみかんのプロフィール

もちもちみかん0系くん
TOPへ

もちもちみかん.comとは


このサイトでは、コーディングがめんどうくさい人向けのお助けツールとして、フォームやCSSをノーコードで生成できる、
 もちもちみかん.forms
 もちもちみかん.css1
 もちもちみかん.css2
と言ったジェネレーターを用意してます。

また、このサイトを通じて、「もちもちみかん」のかわいさを普及したいとかんがえてます!