メインコンテンツまでスキップ

練習課題

概要

本課題では、図形描画処理においてユーザーの操作履歴を保持せず、
「取り消し(Undo)」や「やり直し(Redo)」といった操作ができない構造に対して、
状態の保存と巻き戻しを可能にする設計改善を検討する。

課題コード

以下は、DrawService がキャンバス上に図形(circle, square など)を描画する処理である。
操作内容や状態の履歴は保持しておらず、ユーザー操作を巻き戻したり再実行することができない。

class DrawService {
private canvas: string[] = [];

draw(shape: string) {
this.canvas.push(shape);
console.log(`描画: ${shape}`);
}

showCanvas() {
console.log("現在のキャンバス:", this.canvas.join(", "));
}
}

// 利用例
const drawer = new DrawService();
drawer.draw("circle");
drawer.draw("square");
drawer.showCanvas(); // circle, square

設問 1:このコードが抱えている設計上の問題点を挙げよ

以下の観点を参考に、具体的に列挙すること:

  • 状態が積み上がる一方で、過去の状態に戻れない
  • 操作履歴が記録されておらず、巻き戻しや再実行の仕組みが存在しない
  • UI/UX 要件として一般的な「Undo/Redo」機能に対応できない
  • ユーザー操作の追跡や検証が困難

設問 2:この処理を履歴管理可能な構造に改善するにはどうすべきか

以下の観点を含めて改善案を整理すること:

  • 各操作(描画など)を履歴として保持するにはどのような構造にすべきか
  • 状態を記録・復元するためのアプローチ(オブジェクト/スナップショット)をどう設計するか
  • 操作を記録・巻き戻しできるパターンの活用方法

例:適用候補となるパターン

パターン名主な目的と効果
Command各操作(命令)をオブジェクトとして記録・実行・取り消し可能にする
Mementoオブジェクトの状態スナップショットを保存し、元に戻せるようにする
Prototype状態を複製可能にし、履歴のためのクローン生成を容易にする
State(補助)現在の状態をオブジェクト化して、遷移制御や状態の可視化を支援

発展課題(任意)

  • 操作履歴に加えて、操作の「やり直し」も可能にするにはどのような構造が必要か
  • 履歴の最大保持数やユーザーごとの履歴など、実運用で必要な制限・拡張機能に備えるには?

提出フォーマット(レビュー・勉強会用)

  • 構造上の問題点(3 点以上)
  • 改善方針とパターンの選定理由
  • 改善後の構成概要(履歴の保存・復元の流れ、操作の抽象化方針など)