コース一覧
コンピューターサイエンス入門:理論編
疎結合と密結合 — 依存性注入で設計を変える

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
0. 2進数から10進数への変換5分
1. 10進数から2進数への変換5分
2. ビットAND演算でフラグ判定5分
3. OR / XOR でフラグを操作する5分
4. popcount で 1 のビット数を数える5分
5. シフト演算で 2 倍 / 半分5分
6. 16 進数から 10 進数への変換5分
7. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
0. 文字 → ASCII コード5分
1. コード → 文字5分
2. UTF-8 のバイト長を返す5分
3. AND / OR の真理値表5分
4. NOT / XOR の真理値表5分
5. 含意 (→) を AND/OR/NOT で表現5分
6. ド・モルガンの法則5分
7. 第2章まとめクイズ5分
3
計算量とBig-O
0. forループの実行回数を返す5分
1. 入れ子ループの実行回数5分
2. 線形探索 (O(n))5分
3. 二分探索 (O(log n))5分
4. バブルソート5分
5. 配列の最大と最小5分
6. 累積和で範囲合計5分
7. 第3章まとめクイズ5分
4
データ構造 (基本)
0. スタック (push/pop) を実装する5分
1. キュー (enqueue / dequeue) を実装する5分
2. カッコのバランス判定 (スタック応用)5分
3. set で重複を除去する5分
4. map で出現回数を数える5分
5. 二数の和 (map で O(n))5分
6. アナグラム判定5分
7. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
0. バイト → KB 変換5分
1. ディスクサイズフォーマット5分
2. キャッシュヒット率5分
3. LRU 簡易シミュレーション5分
4. エンディアンの入れ替え (uint32)5分
5. バッファ範囲チェック5分
6. 第5章まとめクイズ5分
6
ネットワークと符号化
0. Base64 エンコード後の長さ計算5分
1. URL エンコード対象文字数5分
2. IPv4 アドレスを 32bit 整数に変換5分
3. 32bit 整数を IPv4 アドレスに変換5分
4. CIDR プレフィックスからネットマスクを作る5分
5. 単純チェックサム5分
6. 第6章まとめクイズ5分
7
設計と DB 基礎
0. 重複データを 1NF に変換 (フラットなリスト化)5分
1. キーで join (map 利用)5分
2. 残高転送のトランザクション風処理5分
3. CAP の availability 模擬5分
4. URL ルーティング5分
5. 疎結合と密結合 — 依存性注入で設計を変える12分
6. コース総まとめクイズ5分

コンピューターサイエンス入門:理論編

012進数から10進数への変換
0210進数から2進数への変換
03ビットAND演算でフラグ判定
04OR / XOR でフラグを操作する
05popcount で 1 のビット数を数える
06シフト演算で 2 倍 / 半分
0716 進数から 10 進数への変換
08第 1 章まとめクイズ
09文字 → ASCII コード
10コード → 文字
11UTF-8 のバイト長を返す
12AND / OR の真理値表
13NOT / XOR の真理値表
14含意 (→) を AND/OR/NOT で表現
15ド・モルガンの法則
16第2章まとめクイズ
17forループの実行回数を返す
18入れ子ループの実行回数
19線形探索 (O(n))
20二分探索 (O(log n))
21バブルソート
22配列の最大と最小
23累積和で範囲合計
24第3章まとめクイズ
25スタック (push/pop) を実装する
26キュー (enqueue / dequeue) を実装する
27カッコのバランス判定 (スタック応用)
28set で重複を除去する
29map で出現回数を数える
30二数の和 (map で O(n))
31アナグラム判定
32第 4 章クイズ — データ構造 (基本)
33バイト → KB 変換
34ディスクサイズフォーマット
35キャッシュヒット率
36LRU 簡易シミュレーション
37エンディアンの入れ替え (uint32)
38バッファ範囲チェック
39第5章まとめクイズ
40Base64 エンコード後の長さ計算
41URL エンコード対象文字数
42IPv4 アドレスを 32bit 整数に変換
4332bit 整数を IPv4 アドレスに変換
44CIDR プレフィックスからネットマスクを作る
45単純チェックサム
46第6章まとめクイズ
47重複データを 1NF に変換 (フラットなリスト化)
48キーで join (map 利用)
49残高転送のトランザクション風処理
50CAP の availability 模擬
51URL ルーティング
52疎結合と密結合 — 依存性注入で設計を変える
53コース総まとめクイズ

コンピューターサイエンス入門:理論編

疎結合と密結合 — 依存性注入で設計を変える

テストを流したら、本物のメールが飛んだ

注文を保存してお礼メールを送る処理を書いたとします。テストを 1 回走らせるたびに、テスト用の宛先ではなく実在するアドレスへメールが飛びます。CI が 1 日 30 回まわれば 30 通です。データベースのほうも同じで、テストのたびに本番と同じ MySQL につなぎに行きます。

原因はテストの書き方ではありません。呼ばれている側にあります。

Python

class OrderService: def __init__(self): self.repo = MySQLRepo() # ここで相手を決め打ちしている self.sender = SmtpSender() # ここも def place(self, order): self.repo.save(order) self.sender.send(order.email, "ご注文ありがとうございます")

使う側から見れば OrderService() と書くだけの部品ですが、その 1 行の裏で MySQL と SMTP への接続先が確定します。差し込む隙間がありません。この「相手の実物を自分で名指ししている」状態が密結合です。

実物を作る責任が、差し替えを塞いでいる

困るのはテストだけではありません。データベースを PostgreSQL に替えるとき、メール送信を外部サービスの API に替えるとき、そのたびに OrderService の中を開くことになります。注文処理そのものは 1 文字も変わっていないのにです。

塞いでいるのは MySQLRepo() という 1 行、つまり実物を作る責任を自分で持ってしまっていることです。この責任だけを外に出します。

Python

class OrderService: def __init__(self, repo, sender): # 作らずに、受け取る self.repo = repo self.sender = sender def place(self, order): self.repo.save(order) self.sender.send(order.email, "ご注文ありがとうございます")

place の中身は 1 行も変わっていません。変えたのは、誰が実物を用意するかだけです。

Python

service = OrderService(MySQLRepo(), SmtpSender()) # 本番 service = OrderService(InMemoryRepo(), FakeSender()) # テスト

これでテストは、FakeSender に「誰に何通送ろうとしたか」を記録させるだけで済みます。メールは 1 通も飛びません。この「実物を外から渡す」やり方を依存性注入(DI)と呼びます。専用のフレームワークが要ると思われがちですが、引数で渡すだけで成立します。

interface を切っただけでは、何も変わらない

ここでよくある取り違えがあります。repo の型を interface にすれば疎結合になった、という思い込みです。OrderService の中で MySQLRepo() と書いてあれば、その型が interface だろうと差し替えられないままです。効いているのは interface ではなく、作る場所を外に出したことのほうです。

そして、外に出すことにもコストがあります。OrderService のコードを読んでも repo の正体が分からず、組み立てている場所まで辿らないと実際に何が動くのか見えません。

決め打ち外から渡す
テスト本物につながる差し替えられる
読みやすさその場で分かる渡す場所を辿る
書く量少ない組み立てる場所が要る

判断の目安は、その相手が外の世界に触れるかどうかです。データベース、メール、外部 API、ファイル、そして現在時刻。これらはテストのたびに本物を動かしたくないものなので、外から渡す価値があります。逆に、受け取った数値を計算して返すだけの関数まで包むと、読みにくくなるだけで何も得られません。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • テストバグを見つける工程
  • 処理計算や代入を表す長方形
  • データベースデータを構造化して保存する仕組み
  • MySQL広く使われるオープンソースのRDBMS
  • PostgreSQL機能が豊富なオープンソースのRDBMS
  • エンドポイント「この URL を叩くとこの機能が動く」入口の住所
  • APIアプリ間でデータをやり取りする窓口
  • 引数位置引数=順番で渡す。
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • コース総まとめクイズ

    cs-theory コース全 7 章の応用問題。2 進数からビット演算、計算量、データ構造、ネットワーク、DB 設計まで横断的に振り返ります。

  • URL ルーティング

    URL パスを `Controller#action` の文字列に振り分けるルーティングを実装し、MVC の「Controller の入口」を体感します。

  • CAP の availability 模擬

    CAP 定理の Availability(可用性)を、複数ノード上の最新値を多数決で返す関数として実装します。

  • 残高転送のトランザクション風処理

    口座間の残高転送を、ACID の Atomicity(原子性)を満たすように実装します。残高不足ならロールバックして変更しません。

分からないところは Tap (AI先生) に質問できます

24 時間いつでも、あなたのレベルに合わせて日本語で答えます。