l

o

a

d

i

n

g

.

.

.

GoF以外のプログラミング・デザインパターン #23 Command Palette Pattern

2025/12/14

プログラミング 学習

t f B! P L
eyecatch 「Command Palette Pattern」は、最近の開発ツール(VSCodeやFigmaなど)にも多く採用されている、 ユーザー操作を「コマンド」として抽象化し、検索・実行できるUI設計パターンです。 このデザインパターンの目的は、 ユーザーが「やりたいこと」を直接検索して実行できるようにすることです。 メニュー階層やボタンをたどらなくても、コマンド単位でアクセスできるようにするのが特徴ですね。 SPAなどのツールやアプリの開発に役に立つでしょう。

構成要素

役割 説明
Command(コマンド) 実行可能なアクションをオブジェクトとして定義する(例:ファイルを開く、保存する)
Palette(パレット) コマンドの一覧を管理し、検索・選択UIを提供する
Invoker(実行者) 選ばれたコマンドを実行する(Undoなどをサポートする場合もある)
Receiver(受信者) 実際の処理対象(例:エディタ、キャンバス、ドキュメント)

サンプルコード

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <style> body { font-family: sans-serif; padding: 40px; } #palette { border: 1px solid #ccc; width: 300px; padding: 10px; display: none; position: absolute; top: 50px; background: #fff; } #palette input { width: 100%; padding: 5px; } #list { margin-top: 10px; } .item { padding: 5px; cursor: pointer; } .item:hover { background: #eee; } </style> </head> <body> <h2>Command Palette Pattern</h2> <button id="open">Open Palette</button> <div id="palette"> <input type="text" id="search" placeholder="Type a command..." /> <div id="list"></div> </div> <script> // === Command 定義 === const commands = [ { name: 'Open File', execute: () => alert('File opened!') }, { name: 'Save File', execute: () => alert('File saved!') }, { name: 'Close File', execute: () => alert('File closed!') }, ]; // === Palette管理 === const palette = document.getElementById('palette'); const list = document.getElementById('list'); const search = document.getElementById('search'); function renderList(filter = '') { list.innerHTML = ''; commands .filter(c => c.name.toLowerCase().includes(filter.toLowerCase())) .forEach(cmd => { const item = document.createElement('div'); item.className = 'item'; item.textContent = cmd.name; item.onclick = () => { cmd.execute(); palette.style.display = 'none'; }; list.appendChild(item); }); } // === イベント === document.getElementById('open').onclick = () => { palette.style.display = 'block'; search.focus(); renderList(); }; search.oninput = e => renderList(e.target.value); document.addEventListener('keydown', e => { if (e.key === 'Escape') palette.style.display = 'none'; }); </script> </body> </html>

処理フロー

1. 「Open Pallet」をクリックするとパレットを開く 2. パレットが登録済みコマンドのリストを表示 3. ユーザーが文字を入力してフィルタリング 4. コマンドを選択するとInvokerが対応する処理を呼び出す

デモ

メリット

・UIがシンプル(すべての操作を検索して実行できる) ・新しい機能を追加しても、UI変更なしでパレットに登録できる ・コマンドパターンと親和性が高く、Undo/Redoやマクロ実行も容易

デメリット

・コマンド定義の設計が煩雑になりやすい ・初心者には「どんなコマンドがあるか」が分かりづらい

あとがき

Webツールでは、毎回非常にたくさんの処理を行うパターンです。 いろいろな処理が発生すると思いますが、それぞれに対して、単一のパターンで記述できると非常に効率的なコードになるし、 更新や機能追加もかなり楽になることがわかりますね。 他のパターンとも組み合わせることで、安定性がますでしょう。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ