Before:外部から内部を直接いじれる設計
// 悪い例: 内部状態を public で露出
class AiBillingService {
constructor() {
this.taxRate = 0.1; // 本来は隠したい内部ルール
this.subtotal = 0; // 外部が直接書き換え可能
this.workflowStep = 'init';// 手順の内部状態まで見えている
}
prepare(subtotal) {
this.subtotal = subtotal;
this.workflowStep = 'prepared';
}
applyTax() {
if (this.workflowStep !== 'prepared') throw new Error('step error');
this.subtotal = Math.floor(this.subtotal * (1 + this.taxRate));
this.workflowStep = 'taxed';
}
finalize() {
if (this.workflowStep !== 'taxed') throw new Error('step error');
return this.subtotal;
}
}
const billing = new AiBillingService();
// AIが短絡的に内部を直接変更しがちな箇所
billing.taxRate = 0.2; // 内部ルールを書き換える
billing.workflowStep = 'taxed'; // 手順を飛ばす
billing.subtotal = 1000; // 内部状態を外から改ざん
console.log(billing.finalize()); // たまたま動いても壊れやすい
何が壊れるか:内部状態・手順・計算ルールに外部が依存するため、
workflowStep の名前変更や内部フロー変更だけで呼び出し側が連鎖的に破綻します。