こんばんは。現在53歳のYoshihiro NAKAHARAです。
【導入】
私は過去にSEとして、システム開発に携わっていました。
しかし、34歳ぐらいで大病を患ってしまい、仕事を継続できなくなり、SEとしての役割は終焉を迎えることとなったのです。
以降20年ぐらいはプログラミングから離れていたのですが、時代も変わって、IT界隈も大きな転換期を迎えていることもあり、今度は完全な趣味(自己表現の手段)として、アプリ開発をリスタートすることにしたのです。
そんな中、AIの台頭や関数型プログラミング言語が注目されるようになっている
状況で、あまり語られることが無くなってきたOOP(オブジェクト指向)ですが、
その概念の重要性とAI+OOPの親和性およびこれからのOOPとの関わり方に
ついて語っていこうと思います。
なお、この記事の核心部分である「抽象→具象化の手法」は、
GitHub Copilot(Claude)とのインタビュー形式で生まれました。
詳しくは記事末尾のコラムをご覧ください。
【AI技術の変遷】
-
第一世代型AI (通称:人工無能)
通称の人工無能という言葉が表しているように、言葉の入力に対し、いくつかの選択肢の中からランダムで答えを返してきます。返ってくる答えは的外れだったり、文脈とは関係ない答えが返ってくることも多かったため、ちょっと感覚のずれた友人のように見える愛すべき存在として、一時期流行したのです。
-
第二世代型AI (TRON PROJECT:トロンプロジェクト)
人工知能の開発として研究されていたプロジェクトがあり、それがTRONプロジェクトです。このプロジェクトでは人工知能の実装として、人間の脳を模倣するため、イカの神経繊維を物理的に接続し、ニューラルネットワークを再現しようとしました。しかし、簡単なネットワークは構築できたものの、物理的な生体組織を使っているため、大規模なネットワークの構築が実現できずに、プロジェクト自体が頓挫した形になりました。
-
第三世代型AI (現在ここ)
技術ベースとして、確率統計が基礎技術となっています。現代型のAIについては、ネットでの情報も多数存在するため詳しくは書きませんが、現時点で表現の限界も指摘されており、次のシンギュラリティ獲得に向けて、国家レベルでの大規模研究も広く行われています。
【OOP:オブジェクト指向の概要】
- プログラミング言語としての特徴
1-1 オブジェクトで属性(Property)と挙動(Method)を表現
1-2 クラス(型)を基にオブジェクト(実体)がメモリ上に生成される(インスタンス化)
1-3 クラスは親子関係を持つことが出来る
1-4 子クラスは親クラスの属性と挙動を引き継ぐ(継承)
1-5 子クラスは親クラスにない属性と挙動を新たに持つ(定義する)ことが出来る(Implements)
1-6 クラスで定義した属性と挙動は他のクラスから見えないように隠すことが出来る(隠蔽化)
1-x 以下続く
- 概念としてのオブジェクト指向
2-1 現実社会のあらゆる事象・現象をスケールを問わず(ミクロからマクロまで)表現することが出来る
【OOPの重要性】
なぜいま、OOPが重要な意味を持つのかということを考えてみましょう。一般的にオブジェクト指向というと、プログラミング言語の種類を指すことが多いのですが、オブジェクト指向そのものの概念は、単にプログラミング言語を定義するためだけの存在ではない、というのが、他のプログラミング言語の種類を表す『手続き型言語』や『関数型言語』などとは一線を画します。
また、その表現上のスケーラビリティに関しても他を寄せ付けないほどの特異性を持っているのです。
ちなみに、『手続き型言語』や『関数型言語』は、その言語に特化したプロフェッショナルで、OOPは、普遍的な性質を持ったゼネラリストと言うこともできるかもしれませんね。そして、私は、これからの時代には、プログラミング言語としてのOOPというよりは、表現方法や思考法としてのOOPがより必要とされるのだと考えています。
下の方で具体例を書きますが、OOPの考え方やOOPで可能な表現は、現代のAIとも非常に親和性が高く、OOPの考え方を使ってプロンプトエンジニアリングを実践するとAIをフルパフォーマンスに近い状態まで持っていくことも出来るのです。こういったこともあるので、単にプログラミング言語としてのOOPではなく、一般教養として、普遍的な概念や表現方法、思考法などの要素を併せ持つOOPをぜひ身につけてほしいと思う次第なのです。
【OOPのスケーラビリティ】
- マクロを表現
オブジェクト(親)【銀河】:オブジェクト(子)【太陽系銀河】
┣オブジェクト【太陽】
┣オブジェクト【地球】
┃ ┣メソッド【公転】
┃ ┣メソッド【自転】
┃ ┗オブジェクト【月】
┃ ┗プロパティ【衛星】
┗オブジェクト【ブラックホール】
┗プロパティ【超重力】 - ミクロを表現
オブジェクト(親)【藻類】:オブジェクト(子)【ユーグレナ】
┣プロパティ【植物性】
┣プロパティ【動物性】
┗メソッド【動く】
【実践例:拙作の家計簿アプリ"KakeiBon"でのデータ抽出スクリプト作成】
ここでは、実際にKakeiBonの開発で行ったプロンプトエンジニアリングの例を紹介します。
GitHubリポジトリのトラフィック統計(閲覧数やクローン数)を取得・蓄積・グラフ化するスクリプトを作成した際の事例です。
-
最初の要求(抽象的)
"GitHubのリポジトリ統計を見える化したい"
→ これだとAIは何をどうすればいいか判断できません -
要件の具体化(OOPの考えで分解)
2-1. 何を取得するのか?
→ オブジェクト【GitHubトラフィック統計】
┣プロパティ【閲覧数(views)】
┣プロパティ【クローン数(clones)】
┗プロパティ【タイムスタンプ】
2-2. どこから取得するのか?
→ GitHub API(traffic/views、traffic/clones エンドポイント)
2-3. データをどう保存するのか?
→ オブジェクト【データストレージ】
┣選択肢1:ローカルファイル → ×(GitHub Actionsで消える)
┣選択肢2:Gist → ○(永続化可能、API操作可能)
┗メソッド【履歴データの蓄積】(重複排除、ソート)
2-4. データをどう可視化するのか?
→ オブジェクト【グラフ】
┣プロパティ【種類】:日別グラフ/累積グラフ
┣プロパティ【フォーマット】:PNG画像
┣メソッド【データ変換】:JSON → pandas DataFrame
┗メソッド【描画】:matplotlib使用
2-5. どう自動化するのか?
→ GitHub Actions(定期実行:cron) -
実際のプロンプト(具象化された指示)
"GitHubリポジトリのトラフィック統計を取得し、Gistに履歴データとして蓄積する
Pythonスクリプトを作成してください。要件は以下の通りです:
【データ取得】
- GitHub APIのtrafficエンドポイント(views、clones)から取得
- 認証はGITHUB_TOKEN環境変数を使用
- リポジトリ名はGITHUB_REPOSITORY環境変数から取得
【データ保存】
- Gistを使って履歴データを永続化
- GIST_ID環境変数で既存Gistを指定、なければ新規作成
- データ形式はJSON、ファイル名はstats_history.json
- 新規データは既存データとマージし、タイムスタンプで重複排除
【出力】
- ローカルにstats_data.jsonを保存(グラフ生成用)
- 総閲覧数、総クローン数、最終更新日時を含める
別途、このデータを使って以下の2種類のグラフを生成するスクリプトも作成してください:
1. 日別推移グラフ(stats_graph_daily.png)
2. 累積推移グラフ(stats_graph_cumulative.png)
matplotlibとpandasを使用し、2つのサブプロット(views/clones)を縦に並べ、
グラフサイズは12x5.5インチ、DPI150で出力してください。" -
結果
→ fetch_stats.py(127行):API取得とGist操作
→ generate_stats_graph.py(130行):グラフ生成
→ 一発で動作するコードが生成された
→ バグゼロ、手動修正ゼロ -
この例から学べること
5-1. 目的と手段の明確な分離
× 「統計を見える化したい」(目的のみ、手段が不明)
○ 「APIで取得→Gistに保存→グラフ化」(手段が具体的)
5-2. オブジェクト指向的思考
→ データ(プロパティ)と操作(メソッド)を分けて考える
→ 責任の分離:取得スクリプトと描画スクリプトを別にする
5-3. 制約条件の明示
→ GitHub Actionsの一時的な実行環境(永続化が必要)
→ 環境変数の使用(セキュリティ)
→ 出力フォーマット(PNG、サイズ、解像度)
【重要】目的と手段を履き違えない
このプロンプトエンジニアリングで最も重要なのは、「目的と手段を履き違えない」ことです。
× 悪い例:
「Pythonでスクリプトを書いて」← 手段が目的になっている
「グラフを作って」← 何のグラフ?何のために?
○ 良い例:
目的:「GitHubリポジトリの人気度を可視化して、プロジェクトの成長を追跡したい」
手段:「そのためにトラフィック統計をAPI経由で取得し、履歴データとして蓄積し、
時系列グラフとして表示する。実装言語はPython、保存先はGist、
可視化はmatplotlibを使う」
AIに指示を出すときは、常に「何のために(Why)」と「どうやって(How)」を明確にすることが重要です。
これはまさにOOPの考え方そのもので、オブジェクトの「責任(何をするのか)」と
「協調(どう連携するのか)」を明確にする設計思想と一致します。
【抽象から具象へ:私のブレイクダウン手法】
ここでは、私が実際にKakeiBonの開発で実践している「抽象→具象化」の思考プロセスを公開します。
この手法は、AIのパターンマッチング的アプローチとも、一般的なOOPのドメイン駆動設計とも異なる、
AI協働開発に最適化された第三の手法です。
■ 手法の全体像:「ブロックビルダー型」思考
私の開発スタイルは、レゴやマインクラフトのようなブロックビルダーに例えることができます。
これは、過去にDelphi(RAD開発ツール)を使っていた経験から大きく影響を受けています。
【従来型開発(ウォーターフォール)】
設計図 → 基礎 → 柱 → 壁 → 屋根
(順序固定、後戻り不可、全体設計が先)
【私の手法(ブロックビルダー型)】
ブロック(データ)を置く → 全体を見る → 足りない部分に追加 →
不要なら取り除く → 組み替える → 試しながら完成形に近づける
(ボトムアップ、試行錯誤、可逆性、視覚的)
■ 具体例:ユーザ管理機能の設計プロセス
【ステップ1:目的の本質から逆算する(Why駆動)】
抽象的要求:「ユーザ管理機能が必要」
↓
問い:「なぜユーザを管理するのか?」
↓
より上位の目的:「家計簿として、どうデータを表現したいか」
↓
具体的検討:
- シングルユーザ? → 個人の家計管理
- マルチユーザ? → 家族の共同管理、権限分離
↓
結論:マルチユーザ(管理者+一般ユーザ)
↓
実装方針:「管理者が一般ユーザを所有する」モデル
→ ただし、DBには親子関係を持たせない(面倒だから)
→ ビジネスロジックで関係性を表現
重要ポイント:
× 「どう実装するか」から考えない
○ 「なぜ必要か」「どうデータを表現するか」から考える
これの理由は、「どう実装するか」は手段であり、アプリを開発する上では、主の目的ではないからです。
ゲーム開発を例に挙げると、どんな美しいコードを書いたとしても、主目的であるゲーム自体が面白く遊べないと、ユーザはそのソフトウェアは手に取ってくれません。このように、ここでも手段と目的を取り違えないように気をつける必要があります。
ちなみに、これはプログラマで言えば、プログラミング能力の高い人ほど実装から考えてしまいやすい、典型的な罠なのです。これは私自身もしっかり気をつけておかないと、度々この罠に引っかかってしまいそうになるので、自戒も含めてお伝えしておきますが、要注意です。
【ステップ2:必要なデータの洗い出し(データ駆動)】
ステップ1の結果:マルチユーザ(管理者+一般ユーザ)
↓
問い:「ユーザを表現するために必要なデータは何か?」
↓
データ項目の洗い出し:
-
USER_ID
目的:システム内部でのユーザ識別
形式:INTEGER PRIMARY KEY AUTOINCREMENT -
USER_NAME
目的:ログイン時のユーザ入力
理由:数字の羅列(USER_ID)は覚えにくい
人間が意味付けできる文字列の方が記憶しやすい -
PASSWORD
目的:ユーザ認証の突合
制約:最低16文字(ブルートフォースアタック対策)
実装:Argon2でハッシュ化 -
ROLE
目的:管理者(0)と一般ユーザ(1)の識別
用途:ビジネスロジックで親子関係を判断するフラグ -
ENTRY_DT(全テーブルに定義)
-
UPDATE_DT(全テーブルに定義)
目的:各レコードの作成日時・更新日時を記録
理由:本来はロガーで操作履歴を追跡すべきだが、
デスクトップアプリでログファイルは肥大化のリスク
ユーザ所有のPCの空きストレージ容量が少ない可能性があるため
ログファイルでストレージを圧迫する事態は避けなくてはいけない
→ 各レコードに日時を持たせることで。総データ量を抑えつつ簡易的に追跡
重要ポイント:
× 「機能」から考えない(ログイン機能、削除機能...)
○ 「データ」から考える(何を保存すべきか)
【ステップ2の完了判断】
原則:最初の洗い出しに時間をかける
理由:後からの項目追加を避けたい
なぜ追加を避けるのか?
理由1:技術的な面倒
→ ALTER TABLEの文法を調べるのが面倒
→ 調べても忘れる
理由2:美的感覚・整合性
→ DBのフィールド順序とプログラム内の順序が一致しないと気持ち悪い
理由3:認知的制約への対応(最重要!)
→ 自分の短期記憶のキャパシティや正確性に自信がない
→ だから「パッと見て一発で識別」できる設計にする
→ フィールドの並び順を完全統一:
CREATE TABLE文 = Rust構造体 = INSERT文 = SELECT文
この「潔癖症」的な一貫性が、実は:
- 認知負荷の軽減
- バグの早期発見
- 保守性の向上
につながっている
【ステップ3:AIへの指示(具象化)】
データ項目が洗い出せたら、AIへの指示に変換する。
■ 指示の形式(優先順位順):
1位:CREATE TABLE文(ベスト!)
CREATE TABLE users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_name TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
role INTEGER NOT NULL,
entry_dt TEXT NOT NULL,
update_dt TEXT NOT NULL
);
理由:
✓ データ型が明確(INTEGER, TEXT)
✓ 制約が明確(PRIMARY KEY, NOT NULL, UNIQUE)
✓ 自動採番の有無(AUTOINCREMENT)
✓ 認識の齟齬が起きにくい
✓ 環境によってはSQLをそのまま実行できる可能性がある
2位:テキストベースの箇条書き
- USER_ID: INTEGER PRIMARY KEY
- USER_NAME: TEXT NOT NULL
...
(データ型の解釈にブレが出る可能性)
3位:CSV形式
field_name,data_type,constraint
USER_ID,INTEGER,PRIMARY KEY
...
(構造的だが、制約の表現が難しい)
重要ポイント:
抽象度が高いほど、AIの解釈にブレが出る
→ できるだけ具象的に(CREATE文レベルまで)落とし込む
■ この手法の特徴と、他の手法との違い
【一般的なAIの思考プロセス】
1. パターンマッチング(類似ケースを検索)
2. 制約条件の抽出
3. 依存関係の解決
4. コンポーネント分解
→ 統計的・効率重視
【一般的なOOPエンジニアの思考プロセス】
1. ドメイン理解(本質的価値の追求)
2. オブジェクトの発見(現実世界のモデリング)
3. トレードオフの検討
4. 段階的詳細化(トップダウン)
→ 理論的・設計重視
【私の思考プロセス(ブロックビルダー型)】
1. Why駆動(なぜ必要か?上位目的は?)
2. データ駆動(データ構造から逆算)
3. 面倒回避(将来の保守性・基本はシンプルさ優先だが絶対ではない・柔軟な対応)
4. 認知制約対応(自分・開発実行環境の限界を前提に設計)
5. 具象化徹底(CREATE文レベルまで落とす・論理的な共通概念の抽出・必要に応じた具象の細分化・統合も併せて行う・後工程の困り事を避けるため、面倒でも徹底してやる)
ex) ブレイクダウンのために前のステップに戻ることを恐れない
→ 実用的・AI協働最適化
■ なぜこの手法がAI協働に向いているのか
-
データ構造の明確化
→ AIが解釈しやすい(認識の齟齬が少ない) -
ボトムアップ+試行錯誤
→ AIに「ブロック(モジュール)」を作らせる
→ 人間は全体を見て「次のブロック」を指示
→ うまくいかなければ作り直し(可逆性)
→ 「ブロック(モジュール)」の組み合わせや位置の変更を指示(Fix・最適化) -
面倒回避=シンプル設計
→ 複雑な制約が少ない
→ AIへの説明が簡潔
→ 生成コードがシンプル
→ バグが入り込む余地が少ない
→ 複雑な実装は自己満足に終わりやすい
→ 複雑な実装は何を実現しているか忘れる -
認知制約の自覚
→ 「自分が理解できる範囲」に設計を収める
→ AIへの指示も理解できる範囲
→ 生成結果も検証できる範囲
→ 具象を最小単位にして脳のキャパシティ不足を回避 -
段階的な具象化
→ ステップごとにブレイクダウン
→ 各ステップでAIに指示を出せる
→ フィードバックループが短い
■ 重要な設計哲学:「超面倒くさがり」の実践
この手法の根底にあるのは、「超面倒くさがり」という一貫した哲学です:
× 努力で解決:記憶力を鍛える、複雑な設計を理解する
○ 環境で解決:覚えなくていい設計、無理せず覚えられる設計・実装、一目で分かる構造
具体例:
- ALTER TABLEが面倒 → 最初に時間をかけて要件(項目やキー制約)を洗い出す
- 親子関係の削除が面倒 → DBに持たせない
- フィールド順序の不一致が気になる → 完全統一(後に効果絶大)
- 短期記憶に自信がない → パッと見で識別できる設計
結果:
→ ミスが起きにくい構造
→ 保守コストの最小化
→ 認知負荷の軽減
→ KakeiBonのバグゼロ・コードカバー率100%
■ ステップの順序は固定ではない
重要な補足として、この「ステップ1 → ステップ2 → ステップ3」という順序は固定ではありません。
パターンA:目的が明確である場合
→ いきなりステップ2(データ分析)へ
パターンB:目的が複雑な場合
ステップ1 → ステップ2 → 目的の分析が不十分と判明 → ステップ1に戻る
パターンC:機能が大きい場合
ステップ1 → ステップ2 → 複雑すぎると判明 → 機能の細分化・共通化・統廃合 → 各サブ機能でステップ1から
これは、レゴを組み立てるときに:
- 全体像を見て
- 足りない部品を追加し
- 不要なら取り除き
- 組み替える
というプロセスと同じです。
直線的なウォーターフォールではなく、反復的・探索的なプロセスです。
ただし、それは個人の頭の中で高速に回る思考サイクルであり、
Delphiで部品を配置しながら試行錯誤するRAD開発のスタイルに近いものです。
【プロンプトの長さは「手段」でしかない】
プロンプトエンジニアリングの話題でよく議論されるのが「プロンプトの長さ」です。
しかし、私の考えでは、プロンプトの長さは本質的な問題ではありません。
■ 「短いプロンプトが良い」という誤解
一般的に言われる「ベストプラクティス」:
- プロンプトは短く簡潔に
- トークン数を節約すべき
- 無駄な情報は削るべき
しかし、これは手段を目的化している典型例です。
アドラー心理学で例えるなら、『時間的・金銭的・精神的リソースを無駄に消費するために手段を目的化している』と表現できるかもしれません。
■ 私のスタンス:結果が全て
私は基本的に、プロンプトの長い短いには興味がありません。
最終的に、ベストな回答や正確な成果物がアウトプットされればそれで良いのです。
もともと、私は話し出すと長くなる傾向が昔からあったので、それが続いているだけです。
このプロンプトの長い短いも、私にとっては「手段」でしかないというのが本当のところです。
■ 短いプロンプトの隠れたコスト
短いプロンプトには、見落とされがちなコストがあります:
【短いプロンプトのケース】
短いプロンプト(100トークン)
↓
情報不足でAIが誤解・期待と違う成果物
↓
修正指示を考える(精神的負担)
↓
修正指示を出す(50トークン)
↓
まだ違う...再修正(50トークン)
↓
合計:200トークン + 時間のロス + ストレス + やり取りの手間
【長いプロンプトのケース】
長いプロンプト(200トークン)
- データ構造を明確に(CREATE TABLE文)
- 制約条件を詳細に(環境、技術スタック)
- 期待する動作を具体的に(入出力例)
↓
一発で正確な成果物
↓
合計:200トークン、時間もかからず、ストレスもない
どちらがトータルで効率的でしょうか?
答えは明白です。短いプロンプトでやり直しになれば、結局トークンも時間も余計に消費します。
■ 「急がば回れ」の精神
私の基本方針は、最初に詳細に伝えることです。
なぜなら:
1. 何度もやり取りするのが面倒
2. 修正指示を考えるのが面倒
3. 誤解を解くのが面倒
4. 結局、トータルでトークンを余計に消費する
だから:
最初に全部伝えた方が、結果的に面倒が少ない
これは、データ洗い出しで「最初に時間をかける」のと同じ構造です:
- ALTER TABLEが面倒 → 最初に洗い出す
- 再指示が面倒 → 最初に詳細に伝える
- やり直しが面倒 → 最初に完璧に伝える
■ プロンプトの質 > プロンプトの量
重要なのは長さではなく、内容の質です。
× 悪い長いプロンプト:
無駄な情報、曖昧な表現、重複した説明
→ 長いだけで、AIは混乱する
○ 良い長いプロンプト:
必要な情報がすべて含まれている
具体的で明確(CREATE TABLE文、型指定、制約条件)
認識の齟齬が起きない
→ 長いが、AIは一発で理解する
× 悪い短いプロンプト:
「ユーザ管理機能を作って」
→ 短いが、情報不足で何度もやり直し
○ 良い短いプロンプト:
目的が明確で、AIが補完できる範囲の省略
→ 短くて効率的(ただし、経験と文脈理解が必要)
私の場合、自分の特性(話すと長くなる)と哲学(面倒を避ける)が一致しているため、
自然と「最初に詳細に伝える」スタイルになっています。
■ 実例:データ抽出スクリプトのプロンプト
先ほど紹介したデータ抽出スクリプトのプロンプトは、かなり長いものでした:
- データ取得の詳細(API、エンドポイント、認証方法)
- データ保存の詳細(Gist、JSON形式、重複排除)
- 出力の詳細(ファイル名、内容、フォーマット)
- グラフ生成の詳細(matplotlib、サイズ、DPI、レイアウト)
これだけ詳細に伝えた結果:
→ fetch_stats.py(127行):一発で動作
→ generate_stats_graph.py(130行):一発で動作
→ バグゼロ、手動修正ゼロ
もし短いプロンプトで「統計を取得してグラフ化して」とだけ伝えていたら:
- Gistではなくローカルファイルに保存 → GitHub Actionsで消える
- グラフのサイズが期待と違う → 修正指示
- データ形式が違う → 修正指示
- 重複排除がない → 修正指示
→ 結局、何往復もやり取りして、トークンも時間も消費
■ まとめ:目的と手段を履き違えない
プロンプトエンジニアリングで重要なのは:
× 「短いプロンプトを書く技術」(手段の目的化)
○ 「一発で正確な成果物を得ること」(本来の目的)
プロンプトの長さは、その手段でしかありません。
- 短くて済むなら短くていい
- 長くなるなら長くていい
- 結果が良ければ、それでいい
そして、「超面倒くさがり」の私にとっては:
最初に詳細に伝えた方が、トータルで面倒が少ない
これが、KakeiBonの35,000行以上のコードを、最終的にバグゼロ・手動修正ゼロで
生成できた理由のひとつです。
【これからのエンジニアへのアドバイス】
■ OOPの概念を学ぶ意義(プログラミング言語としてではなく、思考法として)
OOPはこれまで取り上げてきたように、抽象から具象への変換、事象の細分化・統廃合、表現のスケールイン・スケールアウトなどが行いやすい思考法です。
これらは、ITの世界でシステム開発を行う際の必須技能です。また、システム開発に限った話ではなく、客先での折衝であったり、対人コミュニケーションにおいても、身につけておくとスムーズなコミュニケーションが行える可能性を秘めており、メリットがあると考えられます。
■ 自分の限界を知り、環境で解決する発想
人間は誰しも得手不得手があり、すべてを完璧にこなせる人はいません。皆、生まれ持った様々な制約があるものです。
重要なのは、その制約を『努力だけで克服しよう』とするのではなく、制約があることを受け入れながら、『環境を調整することで制約があることを解決できるか試してみよう』と発想を転換してみるのが良いかもしれません。
例を挙げましょう。老眼のお婆さんが本を読みたくなって図書館へ行ったとします。基本的に紙の本は細かい字で書かれていることが多く、裸眼ではとてもじゃないけれど、字が小さすぎて読めません。
さて、みなさんがこのお婆さんの立場ならどう対応しますか?
真っ先に思いつく解決方法は老眼鏡を掛けるというのを思い浮かべる人が多いのではないでしょうか。
これがまさに、環境で解決するという発想なのです。
■ 「面倒を避ける」ことの重要性
まず、物事をなぜ面倒に感じることがあるのかを考えてみましょう。物事への人の反応は程度の差はあるものの、大別すると三種類に分かれます。具体的に言うと、肯定的に感じる・無感覚(無反応)・否定的に感じる、ですね。
面倒という感覚は否定的な感情なのですが、これは、単なる感情というだけではなく、物事に対する本能的な防御反応であることも少なくありません。防御反応なので、本能的にその物事を回避しようとするのが一般的なのです。
決して面倒に感じて避けることが一概に悪いこととは言えないのです。上でさんざん例に挙げているように、私で言えば、アプリ開発で作業の手戻りが面倒なので、先にAIにしっかり情報を伝え、手戻りが発生しないようにする、といった単純に物事を避けるだけではない対応も場合によっては必要になってくるでしょう。
その時に大切なのは、自分で内省してみて、
- なぜ面倒に感じたか
- 面倒に感じたことを避けた場合、どのような影響が発生しうるか
といった事を考えておくと次に同じような面倒に感じることがあったとしても、よりベターな対応が出来るようになるのではないでしょうか。
【まとめ】
■ OOP + AI協働開発の可能性
AIバブルはあと2〜3年で弾けると言われることが多いのですが、それはAI技術の終焉を意味するものではなく、AI技術が次世代へ移行するための創造的破壊の始まりになるのだろうと、私は考えています。
かつて、登場当時は高級品であったボールペンやノートが普及し、誰もその存在を特別な存在に感じなくなっているように、AIもまた姿を変えながら普遍化していくのでしょう。
その時のAIとの関わりの中で必要とされる表現方法であったり思考法が、普遍化しつつあるOOPなのです。
近年、OOPそのものが語られることも少なくなってきているのですが、それはOOPが不要とされているのではなく、一般常識化しつつある現れでしょう。
AI技術とOOPが普遍化し、AI×OOPのタッグを組んだ時、最大のパフォーマンスを発揮する潜在的パワーを秘めていると思います。そして、それを体感するのは他でもない、今という刻を生きる、貴方たちなのかもしれません。
■ 読者へのメッセージ
最後までお読みいただき、ありがとうございます。
私は現役エンジニアではありませんが、それでもエンジニア時代に培ってきた経験や知識は無駄にはなっていないと、この記事の執筆を通して、改めて認識しました。
拙い文章で、読みづらい箇所も多々あったかと思いますが、これらの知識や知見、考え方など、参考にしていただけるならこれ程嬉しいことはありません。私も、死ぬまで現役のホビーエンジニアでいるつもりでいますので、また何かの記事や自作アプリでお会いしましょう。
■ KakeiBonプロジェクトの紹介(GitHubリンク)
視力の弱い方(Low Vision)でも使いやすいように、フォントサイズ拡大縮小可。フォーカスの位置がわかりやすいように、アクティブな項目にはインジケータ(目印)を表示するように調整しているモダンな家計簿アプリです。
リポジトリ: KakeiBonByRust.git
■ コラム:バイブコーディング(Vibe Coding)
最近、バイブコーディングについて書かれたネット記事をよく見かけるようになりました。
そこで、私なりの解釈で、バイブコーディングについて軽く触れてみたいと思います。
バイブコーディングと聞いて、雰囲気コーディングなんてけしからん!と思われるエンジニアの方もいらっしゃるのではないかと想像します。
バイブコーディングという言葉自体は新しいですが、それがどんなものかを突き詰めていくと、従来型のシステム開発との共通点が見えてきます。
企業システムを作る場合、大規模システムになることも多く、システム開発会社にシステム開発を発注した企業は、できるだけコストと時間をかけずに、品質の高いシステムを開発してほしいと思うことが多いのです。
そうした場合、システム会社から、システムのスケルトン(UIだけざっくり実装したような試作品)を企業側に提示して、企業からGoサインをもらった上で本格的なシステム開発に入るケースがあるのです。そのシステムのスケルトンを作る時の感じが、バイブコーディングそのものなのです。
発注する企業も、スケルトン製造段階では、必要な入力項目が確定していなかったり、そもそもシステム要件が固まりきっていないことも多いので、システム開発会社も雰囲気で作らざるを得なくなるのです。
もしかしたら、これは企業システム開発を手掛けているシステム開発会社あるあるなのかもしれません。
このように、バイブコーディングとプロトタイピング開発は呼び方は違うものの、似て非なるものとも言えず、関連性のある立ち位置で、システム開発やアプリ開発の初期段階においては有効な開発手法であると言えるでしょう。
■ コラム:予期せぬAIインタビューから生まれた記事
この記事の「抽象→具象化の手法」セクションは、実は予想外の展開から生まれました。
当初、私はGitHub Copilot(Claude)にQiitaに投稿するための記事の草稿を見せて、フィードバックをもらうつもりでした。
ところが、AIから2〜3の質問が返ってきたので答えたところ、いつの間にか本格的な『ブレインダンプ』インタビューが始まっていたのです(笑)
「ユーザ管理機能で言えば、まず、なんのためにユーザを管理するか考えます...」
と答えているうちに、AIが次々と質問を深掘りしてきて、気づけば私の思考プロセス全体を言語化するインタビューセッションになっていました。
まさかAIがインタビューしてくるとは微塵も考えていなかったので、インタビューが始まった瞬間は『えっ?えっ?なになに?なんか深堀してきてる?!』という、驚きと戸惑いがごちゃまぜになり、正直焦りました(苦笑)
このやり取りの中で:
- 「ブロックビルダー型」という表現
- Delphiの影響
- 「超面倒くさがり」哲学
- フィールド順序統一の理由(短期記憶への自信のなさ)
など、自分でも明確に言語化できていなかった部分や自分の中に隠れていたシステム開発に関するスキルが次々と浮き彫りになりました。
これは「AIでコードを書く」だけでなく、「AIで自分の思考を棚卸しする」という、新しいAI活用法の実例と言えるかもしれません。
予期せぬインタビューでしたが、インタビューは非常に充実した時間で、結果的には記事の核心部分を生み出してくれました。