Clipした日: 2024-11-25T21:37:19+09:00 Clipした記事: [具体と抽象を行き来するということ|yonekubo](https://note.com/yonekubo/n/n4fe61173fe15?sub_rt=share_pb) ---- ## 具体と抽象を行き来するということ 2024年11月24日 21:32 フォローしました ## はじめに **具体と抽象を行き来する**ことの重要性は、いろいろな方が述べられていて、筆者も本当にそうだと感じています。それがうまくできる人とできない人とで、年収が数百万円のレンジで変わってくると言っても過言ではないのではと思います。 拙書『アーキテクトの教科書』でも第1章に以下の記述があります。 > 抽象と具象を自由自在に行ったり来たりする能力があると、とても重宝します。 『アーキテクトの教科書』第1章より ただ「具体と抽象を行き来する」という表現そのものが極めて抽象度が高いため、ピンとこない人もいるでしょうし、人によってその解釈が異なる可能性もあるでしょう。この記事では、「具体と抽象を行き来する」という行為を具体例を通じて確認し、理解度を深めたいと思います。 ## 言葉の整理 まずは言葉の意味を確認しておきます。 > 【抽象】 > (abstraction)事物または表象の或る側面・性質を抽き離して把握する心的作用。その際おのずから他の側面・性質を排除する作用を伴うが、これを捨象という。一般概念は多数の事物・表象間の共通の側面・性質を抽象して構成される。 > 【具体】 > ①全体をを具備すること。 > ②(concrete)個体が特殊な形態・性質を持つこと。 > 【具象】 > 固有の形態を有していること。形をとって現れること。また、その形。具体。 > 【表象】 > ①象徴に同じ。 > ②\[哲・心\]近くに基づいて意識に現れる外的対象の像。対象が現前している場合(知覚表象)、記憶によって再生される場合(記憶表象)、想像による場合(想像表象)がある。感覚的・具体的な点で概念や理念とは区別される。 『広辞苑 第六版』より 抽象は心的作用、つまり人間の心の中の働きです。高度な認知メカニズムであり、人間に特有のものです。たとえば、あなたがペットに犬を飼っていたとして、犬はあなたとあなたのきょうだいを「家族」としてカテゴライズして認識することはありませんね。 また、抽象は「或る側面・性質を抽き離して把握する」ことであり、常に捨象とセットです。つまり何らかの観点で**線引き**を行うことであり、その線の引き方は自由です。 「具体と抽象を行き来する」とは、まず具体と抽象をきちんと区別することです。物事には具体と抽象がある、という認知を持って物事を捉えるという**メタ認知**とも言えます。 その上で、具体だけで考えるのでも抽象だけで考えるのでもなく、それらを行ったり来たりする、すなわち臨機応変に切り替えて思考することが大事だということです。 では、「具体と抽象を行き来する」ことをパターン分類して見ていきたいと思います。 ## 問題解決パターン > ユーザー「XX画面から、CSVデータをダウンロードできるようにしてほしいんだよね」 > 開発者「わかりました。ボタンの配置はここでいいですか。出したい項目を教えてください」 これは架空の例ですが、このようなやり取りが実際に開発の現場で行われてはいないでしょうか。これは具体レイヤーのみで思考してしまっている例です。 開発者は、ユーザーが提示したシステムの操作レベルの具体的要望を、解釈を加えることなしに詳細仕様の話を始めてしまっています。一方のユーザーは、システムを用いた作業レベルの視点で問題を捉えてしまっています。 > ユーザー「XX画面から、CSVデータをダウンロードできるようにしてほしいんだよね」 > 開発者「CSVデータはどんな目的で使うのですか?」 > ユーザー「部門経費の予算消化状況をチェックしたいんだよ」 > 開発者「現在はどうしてるんですか?」 > ユーザー「会計システムへ連携されたデータを見てるんだけど、タイムリーに把握できなくてね」 > 開発者「予算データを当システムに取り込んでダッシュボードで与実を見れたらどうでしょうか」 > ユーザー「そうなると非常に効率が上がって助かるね!」 今度の会話では、具体的要望に対して「なぜそれが必要なのか」という問いを行い、上位の目的を確認しています。ユーザーの作業ではなく、業務のレベルへ視座を上げることで、解決すべき本当の問題を見つけるのです。 もし具体レイヤーでの問題解決を進めてしまった場合、ユーザーの「タイムリーにデータを把握したい」という問題は解決されるかもしれませんが、「CSVデータをExcelに取り込んで加工する」という手間が新たな問題となるかもしれません。 抽象化によって問題を捉え直すことで、より効果の高い解決策を見出すことができます。今回の例では、開発ベンダーにとって「予実管理のソリューション提案」という機会に繋がるかもしれません。 問題解決パターンの他の具体例: - インシデントに対するポストモーテムにおいて、「手順の実行順序ミスが原因のため、二人一組作業を徹底しチェックリストを用いた再鑑を行う」という対処ではなく、なぜミスが行ったかの分析を行い、より根本的な対応策を講じる。 ## 一般化パターン 次の疑似コードを見てみましょう。 ``` void 申請(...) { ... (長いビジネスロジック) if (userSettings["notification.email"] == true) { var email = new Email(); email.to(approver.emailAddress); ... emailService.send(email); } if (userSettings["notification.teams"] == true) { var message = new TeamsDirectMessage(); ... } ... (長いビジネスロジック) ```  このコードは、以下の仕様を愚直にコードで表現したものと思われます。 - 申請を行うと、承認者(上司)に承認を依頼する通知が飛ぶ - メール通知の設定がONの場合はメールで通知する - Teams通知の設定がONの場合はTeamsのDMで通知をする ビジネスロジックをスクリプトとして一つのコードにまとめるトランザクションスクリプトパターンは、状況によっては選択肢として候補にはなり得ます。しかし、それにしても上記のコードはベタに書き過ぎて、見通しが悪いようです。 システムの仕様は、可能なことを具体的に列挙する必要があります。ですが、それをそのままコードに落とし込むというのは具体レイヤーで思考停止してしまっており、そのためにコードの見通しが悪くなっているのです。 ``` void 申請(...) { ... var notificationMethods = user.notificationMethods(); var notification = Notification.to(approver).title("承認依頼")...; notificationMethods.forEach(method => { notificationService.send(method, notification); } ... ``` 上記のコード改善例のように、メールやTeamsを通知手段として抽象化することで、ビジネスロジックを表現するコードから個別実装が取り除かれます。**一般化**することでコードがすっきりし、全体としての見通しが良くなるのです。 さらに以下のようにするとどうでしょうか。 ``` void 申請(...) { ... var documentApplied = new DocumentApplied(applyUser, ...); domainEvents.add(documentApplied); ... ``` ドメインイベントを用いることで、申請というイベントと、それをトリガーに行われるアクション(通知処理)を分離しています。「申請が行われると、それをきっかけに何らかの業務処理が実行される」というように、もう一段階抽象化を進めたのです。(もちろんメリットとデメリットのある、アーキテクチャ的な設計判断という話にはなります)。 一般化によりコードの見通しがよくなっても、その検証は具体レイヤーに戻って行う必要があります。そうです、**テスト**です。具体値を用いたテストケースを網羅的に実施することによって、一般化されたコードの妥当性が検証されるのです。 一般化パターンの他の具体例: - エラーへの対応を個別に考えるのではなく、リカバリ可能性や業務的インパクト、発生頻度などによって分類した上で、対応方針を決める。実際に業務運用が回るかはウォークスルーによって検証する。 ## コンセプトの転用パターン 戦略とは元は軍事用語で、全局的な方針策定である戦略と、局面での戦闘実行作戦である戦術を分けて考えて、戦争での勝利を目指します。 戦略という言葉がビジネスの世界に転用されて用いられているのは、ライバルとの競争であるビジネス分野においても、資源配分や組織運営の方針を明確に定めて実行へ移すことがビジネスの成功に不可欠だからです。 さらに転用すると、その考え方はアーキテクチャ設計においても役立ちます。ソフトウェアが価値を生み出し、上位目的であるIT戦略を実現するために、さまざまな制約を考慮した上で資源配分やコミュニケーション設計を行うことがアーキテクトには求められます。 このように、物事の仕組みや構造、コンセプトを高い抽象レベルにまで精製して本質的な理解を得ると、他の状況や場面、領域において転用することが可能となります。 そのためには、具体的な事象や知識、経験をよく観察し分析することが必要です。そこから重要なものを抜き出し、そうでないものを捨てるという作業(抽象と捨象)を行い、本質、原理、理(ことわり)と呼べるものを会得するのです。 コンセプトの転用パターンの他の具体例: - アーキテクチャスタイルやアーキテクチャパターンは、多種多様なアーキテクチャの実例から、偉大な先人たちによって見出された一般解です。一般解としての知識を特定の状況下で適切に活用することで、個別解としてのアーキテクチャが生まれます。 ## 要約・詳細パターン > 上司「プロジェクトの進捗状況はどう?」 > 部下「Aさんのタスクが二日ほど遅れていますが、BさんとCさんは若干前倒しで進んでいるので、全体としてはほぼオンスケです〜(中略)〜、あとDさんのレビュー負荷が高いのが課題ですが、私の方で一部を巻き取って何とかなってます〜(略)」 > 上司「?」 なぜ要領を得ない説明や報告をしてしまうのか。それは、話者が日頃見聞きしている具体的事象を、きちんと要約できていないのが原因かもしれません。 > 上司「プロジェクトの進捗状況はどう?」 > 部下「一部タスクに遅れがありますが、全体としてはリカバリー可能であり問題はありません。Dさんのレビュー負荷が高いという課題はありますが、対策は講じています」 > 上司「具体的には?」 > 部下「ひとまず私の方で一部のレビュータスクを引き取りました。Bさんのタスクが前倒しで終わる予定なので、Bさんにも手伝ってもらいます」 > 上司「わかりました。何か支援が必要になったら相談してください」 まずは要約レベルで情報を伝達し、全体感を理解してもらうことが重要です。そして、必要なポイントに対して情報を詳細化するようにします。 要約・詳細パターンの他の具体例: - 欠陥や障害の報告を上げる際は、細かい情報を並び立てる前に、まずは起こっている事象の概要やインパクトなどを端的にまとめて記述すべきです。 - 会議の冒頭では、会議の目的とゴール、アジェンダを提示し参加者の目線を揃えてから議論に入りましょう。 ## まとめ この記事では、以下の4パターンについて「具体と抽象を行き来する」具体例を見ました。 1. 問題解決パターン 2. 一般化パターン 3. コンセプトの転用パターン 4. 要約・詳細パターン 上記以外のパターンも含めて、基本構造は同じです。目の前の具体的事象に即時反応するのではなく、一呼吸入れて、視座を引き上げます。対象をよく分析した上で、**要はどういうことか?**と解釈を行うのです。その際重要なのは上位の目的です。たとえば「上司に状況を適切に報告する」目的ならば、何を捨てて何を抜き出すかは自ずと明らかになります。 抽象レイヤーで枠組みや方向性が定まったなら、次は実行のために具体レイヤーに下がります。アクションは具体的でなくてはなりません。 そして、状況をよく見て、必要に応じてまた抽象へ戻ったり、再度具体へ進んだりを自由自在にできるセンスを磨くこと、これが「具体と抽象を行き来する」ことではないでしょうか。 最後に、「具体と抽象を行き来する」ことを学ぶのにとても役立つ良書を二冊紹介するのでぜひ参考にしてください。 【朗報】『コンセプチュアル思考』はなんとkindle unlimitedで読めるようです!