実装者を信じてはいけない
本文の状態
日本語全文を表示中
詳細モードで約6分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Algomatic Tech Blog
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
こんにちは、Algomatic の菊池です。
Algomatic 初夏のアドベントカレンダー8日目、6本目の投稿となります。(土日はお休みです)
前日分は小笠原さんによる「ハーネスエンジニアリングを、コンサル/PMO の業務に翻訳する」です。生成 AI における概念を人間活動のメタファーで捉えることで見えてくる視点、おもしろいですよね。
さて、今日の記事では、あまり AI 関係ない話をします。実装の話です。
AI の書いた筋の悪いコードに辟易としていませんか。コードレビューで何度同じ指摘を繰り返しているのか...と嘆いている方も多いと思います。でもこれ、AI 固有の問題ではありません。
人間によるチーム開発であっても「コードの質」は常々問題になります。
実装前の設計レビューをする、コードレビューによる指摘で実装者の成長を促す、などなど色々な手段はありますが、わたしが最も重要かつ効果が高いと考えるのは「実装者の能力に依存しないコードベース」です。
この記事では、「実装者の能力に依存せず、筋の悪いコードを書けないようにする」ためのいくつかの考え方と例を示します。
実装者の注意力に依存してはいけない
あなたのソースコード、「A したら B もするようにしましょう」といった「気をつけて守らないといけない手順」ありませんか。
たとえば、ある業務操作(ここでは「注文」という行為とします)を実行するときに、データの作成、保存、監査ログの記録が必要だとしましょう。
こんなコードに見覚えありませんか。
const record = Order.create(input)
await orderRepository.save(record)
await auditLogRepository.record(record)
「注文を作成したら、監査ログに書き込むのを忘れないようにしてね」というコードです。
このコードが 1 箇所だけであればいいのですが、異なる処理からも注文を作成する必要が出てきた場合においても、この手続きを守る必要があります。
この手続きのうち 1 行でも抜けると、「注文は存在するのに監査ログがない」という不完全な状態ができてしまいます。どうあるべきか。
たとえば次のように業務操作として名前を付けて、それを使うようにする、などでしょうか。それに加えて、placeOrder の内部処理が直接外部モジュールから呼び出せないようになっていると良いですね。
export async function placeOrder(input: PlaceOrderInput) {
const order = createOrder(input)
await saveOrder(order)
await recordOrderAuditLog(order)
return order
}
function createOrder(input: PlaceOrderInput) {
return Order.create(input)
}
async function saveOrder(order: Order) {
await orderRepository.save(order)
}
async function recordOrderAuditLog(order: Order) {
await auditLogRepository.record(order)
}
利用側は、個別の手順を知らなくてよい。
await placeOrder({
customerId,
items,
requestedBy,
})
あるいは、注文作成処理において「注文が作成された」というイベントを発生するようにし、そのイベントハンドラで監査ログを発行するというイベント駆動型のアプローチもあり得ますね。
具体の解き方は文脈によって変わるものではありますが、大事にすべきなのは保存において監査ログの保存が必要であるというルールを、呼び出し側 (=実装者) が毎回気をつける必要がないことです。これが「実装者を信じない」ということの一例です。
「ありえない組み合わせ」を作れてはいけない
筆が乗ってきたのでもう一例出してみましょう。対応関係のある値を、呼び出し側が自由に組み合わせられる形は避けましょう。
sendNotification({
channel: "email",
phoneNumber: "+819012345678",
body: "..."
})
email 通知なのに phoneNumber を渡せてしまうように、「業務上ありえない組み合わせ」をコード上では作れてしまうこと、ありませんか。
型が { channel: string; email?: string; phoneNumber?: string; deviceToken?: string } なら、明らかにおかしい組み合わせでも通ってしまう。よくないですよね。
sendNotification(emailNotification({
to: emailAddress,
subject,
body,
}))
sendNotification(smsNotification({
to: phoneNumber,
body,
}))
一案としては、通知チャネルと宛先の対応関係は、呼び出し側の注意ではなく型や factory に持たせることも有効です。このようにして、不正な組み合わせを「レビューで見つける」のではなく、「そもそも作れない(ビルドが通らない)」状態にすることが大事です。
同じ話は、イベント名とイベント種別、外部サービスと認証方式、状態と許可される操作のような関係にも当てはまります。
値同士の関係を、設計で守りましょう。「気をつけてね」は設計ではないのです。
AI コーディングでこそ、この原則が有効
繰り返しになりますが、この話は人間がコードを書いていた頃から変わりません。人は..というか、少なくとも私は人一倍に注意力がない人間なので、これまでも「型で縛る」、「不正な状態を作れないようにする」、という設計は非常に重要でしたし、助けられてきました。
そしてこの AI コーディング時代、この原則はより大事になってきています。
レビューする/しない論争も記憶に新しいですが、AI も人間も関係なく、「信用できない実装者」と仕事をするときには「間違えようがない設計」が重要なのです。
一方で、AI には人間より強いところもあります。「言われた通りにやりきる」力です。
人間なら面倒で崩してしまうような設計原則も、AI は疲れずに、文句言わずに徹底してくれます。
例示したような「厳密なルールに守られた設計」は、安全ではあるものの「めんどくさい」コードベースになりがちです。でも、AI はめんどくさがらずにコードを書いてくれる。だから、ルールを徹底できます。
AI は間違えます。だから、間違えようがない設計にしましょう。
しかし、AI は徹底できます。だから、徹底的に設計を研ぎ澄ませましょう。
明日もよろしくお願いいたします。
新体制 Algomatic、採用強化中です。ぜひカジュアル面談お申し込みくださいませ!
原文を表示
こんにちは、Algomaticの菊池です。
Algomatic 初夏のアドベントカレンダー8日目、6本目の投稿となります。(土日はお休みです)
前日分は小笠原さんによる「ハーネスエンジニアリングを、コンサル/PMOの業務に翻訳する」です。生成AIにおける概念を人間活動のメタファーで捉えることで見えてくる視点、おもしろいですよね。
さて、今日の記事では、あまりAI関係ない話をします。実装の話です。
AIの書いた筋の悪いコードに辟易としていませんか。コードレビューで何度同じ指摘を繰り返しているのか...と嘆いている方も多いと思います。でもこれ、AI固有の問題ではありません。
人間によるチーム開発であっても「コードの質」は常々問題になります。
実装前の設計レビューをする、コードレビューによる指摘で実装者の成長を促す、などなど色々な手段はありますが、わたしが最も重要かつ効果が高いと考えるのは「実装者の能力に依存しないコードベース」です。
この記事では、「実装者の能力に依存せず、筋の悪いコードを書けないようにする」ためのいくつかの考え方と例を示します。
実装者の注意力に依存してはいけない
あなたのソースコード、「AしたらBもするようにしましょう」といった「気をつけて守らないといけない手順」ありませんか。
たとえば、ある業務操作(ここでは「注文」という行為とします)を実行するときに、データの作成、保存、監査ログの記録が必要だとしましょう。
こんなコードに見覚えありませんか。
const record = Order.create(input)
await orderRepository.save(record)
await auditLogRepository.record(record)
「注文を作成したら、監査ログに書き込むのを忘れないようにしてね」というコードです。
このコードが1箇所だけであればいいのですが、異なる処理からも注文を作成する必要が出てきた場合においても、この手続きを守る必要があります。
この手続きのうち1行でも抜けると、「注文は存在するのに監査ログがない」という不完全な状態ができてしまいます。どうあるべきか。
たとえば次のように業務操作として名前を付けて、それを使うようにする、などでしょうか。それに加えて、placeOrderの内部処理が直接外部モジュールから呼び出せないようになっていると良いですね。
export async function placeOrder(input: PlaceOrderInput) {
const order = createOrder(input)
await saveOrder(order)
await recordOrderAuditLog(order)
return order
}
function createOrder(input: PlaceOrderInput) {
return Order.create(input)
}
async function saveOrder(order: Order) {
await orderRepository.save(order)
}
async function recordOrderAuditLog(order: Order) {
await auditLogRepository.record(order)
}
利用側は、個別の手順を知らなくてよい。
await placeOrder({
customerId,
items,
requestedBy,
})
あるいは、注文作成処理において「注文が作成された」というイベントを発生するようにし、そのイベントハンドラで監査ログを発行するというイベント駆動型のアプローチもあり得ますね。
具体の解き方は文脈によって変わるものではありますが、大事にすべきなのは保存において監査ログの保存が必要であるというルールを、呼び出し側(=実装者)が毎回気をつける必要がないことです。これが「実装者を信じない」ということの一例です。
「ありえない組み合わせ」を作れてはいけない
筆が乗ってきたのでもう一例出してみましょう。対応関係のある値を、呼び出し側が自由に組み合わせられる形は避けましょう。
sendNotification({
channel: "email",
phoneNumber: "+819012345678",
body: "..."
})
email 通知なのに phoneNumber を渡せてしまうように、「業務上ありえない組み合わせ」をコード上では作れてしまうこと、ありませんか。
型が { channel: string; email?: string; phoneNumber?: string; deviceToken?: string } なら、明らかにおかしい組み合わせでも通ってしまう。よくないですよね。
sendNotification(emailNotification({
to: emailAddress,
subject,
body,
}))
sendNotification(smsNotification({
to: phoneNumber,
body,
}))
一案としては、通知チャネルと宛先の対応関係は、呼び出し側の注意ではなく型や factory に持たせることも有効です。このようにして、不正な組み合わせを「レビューで見つける」のではなく、「そもそも作れない(ビルドが通らない)」状態にすることが大事です。
同じ話は、イベント名とイベント種別、外部サービスと認証方式、状態と許可される操作のような関係にも当てはまります。
値同士の関係を、設計で守りましょう。「気をつけてね」は設計ではないのです。
AIコーディングでこそ、この原則が有効
繰り返しになりますが、この話は人間がコードを書いていた頃から変わりません。人は..というか、少なくとも私は人一倍に注意力がない人間なので、これまでも「型で縛る」、「不正な状態を作れないようにする」、という設計は非常に重要でしたし、助けられてきました。
そしてこのAIコーディング時代、この原則はより大事になってきています。
レビューする/しない論争も記憶に新しいですが、AIも人間も関係なく、「信用できない実装者」と仕事をするときには「間違えようがない設計」が重要なのです。
一方で、AIには人間より強いところもあります。「言われた通りにやりきる」力です。
人間なら面倒で崩してしまうような設計原則も、AIは疲れずに、文句言わずに徹底してくれます。
例示したような「厳密なルールに守られた設計」は、安全ではあるものの「めんどくさい」コードベースになりがちです。でも、AIはめんどくさがらずにコードを書いてくれる。だから、ルールを徹底できます。
AIは間違えます。だから、間違えようがない設計にしましょう。
しかし、AIは徹底できます。だから、徹底的に設計を研ぎ澄ませましょう。
明日もよろしくお願いいたします。
新体制Algomatic、採用強化中です。ぜひカジュアル面談お申し込みくださいませ!
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み