Windows用ランチャーアプリの設計を考える
作ったもの
Windows用ランチャーアプリ「StartPilot」の設計書を書きました。
実際にアプリを作るのではなく、どう設計するかを考える過程を記録。システム設計の思考プロセスを、個人的な考えを交えて説明します。
設計書は、機能分割、データフロー、コンポーネント構成を図解しています。
まずは、システム全体の構成を見てみましょう:
main(中身)とrenderer(見た目)を分ける。やりとりはAPI(窓口)を通す。この分離が設計の基本です。
なぜ設計書を書いたか
いきなりコードを書き始めると、途中で迷子になる。
最初、設計なしで作ろうとした。大きくつまずいた。
機能を追加するたびに、既存のコードが壊れる。どこに何を書けばいいか分からなくなって、混乱。
「まず設計を固めてから実装する」という基本を思い出した。大学で学んだはずなのに、忘れていた。これは想定が甘かった。
設計書を書くことで、全体像が見える。機能の追加場所も明確になる。
50歳になって、ようやく設計の重要性を実感した。
設計の基本方針
コンポーネント指向
機能を小さな単位(コンポーネント)に分ける。
例えば、「アプリリスト表示」「お気に入り管理」「設定画面」など、役割ごとに独立させる。
各コンポーネントは、自分の仕事だけをする。他のコンポーネントには干渉しない。
この分離が、保守性を高める。新しい機能を追加しても、既存のコードが壊れない。
mainとrendererの分離
Electronアプリは、mainプロセスとrendererプロセスに分かれる。
main:アプリの中核。データ管理、ファイル操作、ウィンドウ制御。
renderer:UI表示。ユーザーが見る画面。HTML、CSS、JavaScriptで構成。
この2つを直接やりとりさせてはいけない。必ずIPC(Inter-Process Communication)を通す。
最初、直接アクセスしようとして、セキュリティエラー。Electronの仕組みを理解していなかった。
IPC通信を経由することで、セキュリティが保たれる。mainは特権プロセスだから、rendererから直接触れるとリスクがある。
データフロー
ユーザーの操作から、データの保存までの流れ:
1. ユーザーがボタンをクリック(renderer)
2. rendererがIPCで「保存して」とmainに要求
3. mainがデータを検証
4. mainがファイルシステムに保存
5. mainが「保存完了」をrendererに返す
6. rendererが「保存しました」と表示
このフローを図解すると、理解しやすい。
API設計
mainとrenderer間のAPIを設計しました。
// renderer → main
ipcRenderer.invoke('app:getList') // アプリリスト取得
ipcRenderer.invoke('app:add', appData) // アプリ追加
ipcRenderer.invoke('app:remove', appId) // アプリ削除
ipcRenderer.invoke('app:launch', appId) // アプリ起動
// main → renderer
mainWindow.webContents.send('app:updated') // リスト更新通知
関数名は統一的なルールに従う。対象:動詞の形式。
app:getListなら、「アプリのリストを取得」と一目で分かる。
最初、getApps、fetchAppList、retrieveApplicationDataなど、バラバラな名前にしていた。統一性がなくて、混乱した。
命名規則を決めたら、コードが読みやすくなった。これだ。
コンポーネント構成
mainプロセス
- AppManager:アプリリストの管理
- FileManager:データの保存・読み込み
- WindowManager:ウィンドウの制御
- ConfigManager:設定の管理
各Managerは独立している。AppManagerがFileManagerを直接呼ぶのではなく、APIを経由する。
疎結合。変更が局所的に収まる。
rendererプロセス
- AppListComponent:アプリリストの表示
- FavoriteComponent:お気に入りの管理
- SettingsComponent:設定画面
- AppShell:全体のレイアウト
各コンポーネントは、自分の表示だけを担当。データ取得はIPCでmainに依頼。
UIとロジックの分離。これが重要です。
設計で悩んだポイント
データの持ち方
アプリのデータをどう持つか。JSON?SQLite?
最初、全部JSONファイルに保存しようとした。シンプルだけど、検索が遅い。
1,000個のアプリを管理したら、検索に数秒かかる。これは課題。
SQLiteに変更。データベースなら、インデックスで高速検索できる。
でも、小規模なら(100個以下)、JSONで十分。過度な最適化は避ける。
最終的に、100個以下ならJSON、それ以上ならSQLiteに切り替える設計にした。
エラーハンドリング
どこでエラーを処理するか。
mainで全部処理?rendererで表示?
両方必要だと気づいた。mainでエラーをキャッチして、rendererに通知。rendererがユーザーに分かりやすく表示。
役割分担が大事。
使ってみて
システム設計は、実装前に全体像を固める作業です。
ポイントは以下の3つ:
- コンポーネント分割:機能を小さな単位に分ける、各コンポーネントは独立
- mainとrendererの分離:中身と見た目を分ける、やりとりはIPC経由
- API設計:命名規則を統一、
対象:動詞の形式で分かりやすく
最初は設計なしで作ろうとして大きくつまずいた。途中で混乱して、最初から作り直しました。設計書を書くことで、全体の見通しが良くなり、実装がスムーズになりました。
設計は面倒に感じるかもしれませんが、結果的に時間を節約できます。
まとめ
今回は、Windows用ランチャーアプリの設計を考えました。
ポイントは以下の5つ:
- コンポーネント指向:機能を役割ごとに分割、独立したコンポーネントとして設計
- mainとrendererの分離:中身(データ管理)と見た目(UI)を明確に分ける
- API設計:IPC通信でやりとり、命名規則を統一して可読性を向上
- データ管理:100個以下ならJSON、それ以上ならSQLiteに切り替え
- エラーハンドリング:mainでキャッチ、rendererで表示、役割分担が重要
設計なしで実装を始めて大きくつまずいた。途中で混乱して作り直しました。設計書を書くことで、全体像が見えて、実装がスムーズになりました。
システム設計を考えている方の参考になれば嬉しいです。
参考にした資料
この記事で興味を持った方におすすめのリンク:
最後まで読んでくださり、ありがとうございました。