lacolaco

哲学者になりたいソフトウェアエンジニア / 技術的じゃないことを書きます

ソフトウェア設計を学びたい人々にまず教えるべきことはテスト技法ではないか

根本の問題意識

  • ソフトウェアの設計スキルはどのように獲得する(させる)ことが効果的であるのか

ソフトウェアアーキテクチャの目的

  • そもそもソフトウェアアーキテクチャはどのような欲望を満たすための方法か

ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守するための必要な人材を最小限に抑えること である。 (CLEAN ARCHITECTURE)

  • 「求められるシステムを構築・保守するための必要な人材を最小限に抑えたい」
    • => 構築容易性保守容易性 を確保したい
  • 構築容易性
    • 「構築しやすさ」とは?
      • ソフトウェアを構築するとはどういうことか
    • ソフトウェアの2つの価値: 「振る舞い」と「構造」
      • 振る舞い: 要件を満たすこと => いわゆる機能
      • 構造: 振る舞いを簡単に変更できること => いわゆるアーキテクチャ
    • 構築しやすさ=価値の生み出しやすさ
      • 要件を満たしながら振る舞いを変更し続けられること
      • つまり構築容易性は変更容易性が必要になる
  • 保守容易性
    • 「保守しやすさ」とは?
      • 「要件を満たし続けていること」の検証と維持
    • つまりテスト容易性が必要になる

ここまでのまとめ

  • ソフトウェアアーキテクチャとは何のためのどのような方法か
    • 目的: 構築容易性保守容易性 を確保したい
    • 方法: ソフトウェアに変更とテストが容易となる構造を導入する

変更容易性とテスト容易性

Image https://www.thomasalspaugh.org/pub/fnd/ility.html

  • どちらも 保守性 (Maintainability) に含まれる
  • つまり構造の価値とは
    • PortabilityやUsabilityの要求を満たすための「振る舞い」を維持し、新たな要求に応える労力を最小化しつづけること
    • Maintainability: Code possesses the characteristic maintainability to the extent that it facilitates updating to satisfy new requirements or to correct deficiencies. This implies that the code is understandable, testable and modifiable;

  • 変更が容易であるためには、変更が既存の振る舞いを壊さないこと=要件を満たし続けられていることの確証が必要
    • 変更容易性はテスト容易性・理解容易性に支えられている
  • また、変更容易性はソフトウェアを変更しようとしてはじめてわかる
    • 言い換えれば、変更容易性はソフトウェアを変更しようとしたときの抵抗の逆数である
  • だがソフトウェアの変更の契機は要求の変更であり、内発的に始動するものではない
    • また同じソフトウェアに同等の変更が繰り返し加わることはない(それは変更ではない)
  • ゆえに 変更容易性を直接評価することは難しい
    • 間接的にはMTTRやデプロイ頻度が指標になるが、測りたいときに好きに測れる特性ではない
  • 保守性を高めようとする営みは、まず理解容易性かテスト容易性の改善が内発的に始まり、変更容易性はその結果として間接的に改善されることになる

ここまでのまとめ

  • 変更容易性はそれ自体を直接評価することが困難である
    • 変更容易性はテスト容易性・理解容易性に支えられている
    • ソフトウェアの変更の契機は要求の変更であり、内発的に始動するものではない

保守性と複雑性

Image https://speakerdeck.com/twada/agility-and-quality-characteristics-developers-summit-2021-summer?slide=28

  • 複雑性が理解容易性と変更容易性を損なう
  • ところで
    • "変更容易性はソフトウェアを変更しようとしたときの抵抗の逆数である"
  • 同様に、理解容易性はソフトウェアを理解しようとしたときの抵抗の逆数であるといえる
    • フィードバックとして得られるのは抵抗 = 複雑性
    • 変更しようとしないと変更容易性は評価できない
    • 理解しようとしないと理解容易性は評価できない
  • 容易性の問題
    • 人間の問題
      • 3つの容易性は「人間にとって」容易であることを評価するもの
        • なぜならまだ人間がソフトウェア開発をしているから
      • 人間は慣れてしまう
        • 同じ人間が同じ対象で容易性を繰り返し評価することは難しい
    • 偶然性の問題
      • 試行回数が少ないと、偶然性に影響を受けやすい
      • ある変更は容易だが別の変更は困難な構造
      • ある人には理解しやすいが別の人には理解しにくい構造
    • 評価の頻度と観点の多様性が重要

ここまでのまとめ

  • 容易性は実際にやってみようとしたときの抵抗の逆数でしか評価(観測)できない
  • 人間は変化するため同じ対象を繰り返し評価することが難しい
  • 試行回数の少ない事柄の容易性は偶然性の影響を受けやすい
  • ではどうやって保守性を評価し、改善につなげるか

テスト容易性とフィードバックサイクル

  • テスト容易性もテストしようとしたときの抵抗の逆数である
    • テストしようとしないとテスト容易性は評価できない
  • テストは開発者の内発的な始動が可能である
    • 要件が変わっていなくてもテストを書くことはできる
  • 変更・理解・テストのなかで、もっとも試行回数を増やしやすく、学習(抵抗の観測)を素早く行えるのがテスト
  • つまり保守性の中でテスト容易性がもっとも評価と学習の容易な副特性である

ソフトウェアアーキテクチャとテスト

  • テスト容易性は複雑性を評価するひとつの見方であり、そのすべてではない
    • テストしやすさだけに傾倒するあまり、行き過ぎた抽象化で理解容易性を損なうこともある
  • とはいえもっとも手軽に複雑性を軽減するための取っ掛かりを作れるのはテスト容易性である
    • テストされていれば他に問題があってもあとから変更しやすい
  • それゆえにソフトウェアアーキテクチャの方法論は「テストしやすく作る」が語られやすい

設計スキルの向上

Image https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition?slide=82

  • この経験とは何の経験か
    • アーキテクチャの経験とは構造の経験
    • つまり変更・理解・テストの経験である
  • 「自分で設計したシステムを長い間メンテする」の意味
    • 変更・理解・テストをすべて経験する × 時間
    • 当然経験としての効果が高い
  • そうした機会に恵まれないプログラマーがどのように経験値を稼ぐか
    • 変更・理解・テストのうち日常的かつ自発的に行えるのはテストである
    • たくさんテストを書くことで「どのようなコードがテスト容易性を損なうか」を経験する
    • テスト容易性というひとつの視点からソフトウェアの複雑性を捉える判断力を身につける
  • 「テストを書く習慣」
    • テスト駆動開発は個人の習慣をチームのワークフローとして拡大する
    • さらに進めばテストされていないコードをデプロイさせないルール化(品質管理)へ
  • アーキテクチャに必要な判断力にテストの経験は不可欠
    • より効果的なテストをより早く書けるようになる
      • 早く描くには上手くなる。上手く描くにはいっぱい描く。いっぱい描くには早く描く。(SHIROBAKO)

  • であれば、保守性に優れたソフトウェアの開発を志す人々にまず教えるべきことはなにか
    • 設計技法は複雑性を抑制する方法であって、複雑性を認識する方法ではない
    • 複雑性を認識するには、「抵抗」を観測する技術を身につける必要がある
    • その方法としてもっとも学習に適しているのはテスト技法ではないか
      • もちろんそれだけではないが
        • 理解容易性から学習する方法の例: たくさんのコードを読み、理解しやすさを左右する構造の特徴を感じ取る
        • 変更容易性から学習する方法の例: 要求の変更が頻繁に起こる環境に身を置き、変更しやすさを左右する構造の特徴を感じ取る
      • テスターの経験がプログラマーとしての成長に寄与するようなことも説明がつく
  • 保守性の高い構造を学習するために、たくさんテストを書くことから始める
    • どうテストすればよいかわからないものをどうしてうまく設計できるだろうか

結論

  • ソフトウェアアーキテクチャの目的はソフトウェアの保守性である
    • 保守性のための方法としてソフトウェアに「構造」を導入する
  • 保守性を構成する3つの容易性
    • その中で開発者にとって評価と学習がもっとも容易なのは「テスト容易性」である
    • アーキテクチャの判断力の習得には経験が不可欠
      • 日常的かつ自発的に増やせるのはテストの経験である
  • であれば、保守性に優れたソフトウェア設計を学びたい人々にまず教えるべきことはテスト技法ではないか
    • 設計技法は複雑性を抑制する方法であって、複雑性を認識する方法ではない
      • 自分では知覚できない脅威に備えるための方法論は実感を伴わないおまじないになる
    • 複雑性を認識するには、「抵抗」を観測する技術を身につける必要がある
    • その方法としてもっとも学習に適しているのはテスト技法ではないか
      • 複雑性を認識できるようになることで、それを抑制・制御するための設計技法の必要性を身を持って理解できる
  • 保守性の高い構造を学習するために、テストを書くことから始める
    • まずテストから書き始めるテスト駆動開発は学習の面からも理にかなった方法論であるといえる

してほしいことはお願いする

○○してもらえるとうれしいです。

あるいは

○○していただけると幸いです。

これらは個人的「言わないように気をつけていることば」ランキングの上位に入る。 うっかり言ってしまった日にはひとりで反省しているが、ひとりで気をつけているだけなので誰にも押し付けるつもりはない。

「してください」でいい

○○してもらえるとうれしいです。

これを言われると大抵の人は「○○をするようお願いしてるんだな」とわかるだろうが、文字通りに受け止めればこれは何もお願いはしていない。 これが表現しているのは私の状態の説明であって、「私は〇〇してもらえるとうれしい状態です」というアピールにすぎない。

これは「お腹すいた」と言って「ごはんを用意してほしい」をリクエストするのと同じであるし、「ごはんできたよ」と言って「すぐに食卓に来て配膳を手伝ってほしい」をリクエストするのと同じである。 このような隠喩的なリクエストは相手の解釈の余地を大いに挟むし、それで自分が求めていたものが出てこないと衝突が起きたりする。最初からはっきりお願いしていれば穏やかに済んだであろうに。

なぜそうなるか。それは「事実から当為は導けない」からであり、共感なき「べき」の押しつけが摩擦を生むからである。

「お腹すいた」が「ごはんを用意してほしい」のリクエストになりえるのは、「あなたは私が空腹にならないよう気を配るべきだ」という「べき」の受け入れを要求しているからだ。扶養関係にある親子ならまだしも、対等な関係だと思っている相手にそんな「べき」を要求すれば機嫌を悪くされても仕方ない。 同じように「○○してもらえるとうれしい」は「私がうれしければあなたもうれしいはずだ」というニュアンスを秘めている。ちょっとひねくれた受け取り方をすれば「あなたを喜ばせるために仕事してるんじゃない」と返されるかもしれないし、それはごもっともである。

してほしいときには「してください」「してほしい」とストレートにリクエストする。ストレートに断られる可能性も当然考慮する。 状態をアピールして相手のアクションへの期待を匂わせる隠喩的なコミュニケーションをしない。特に仕事の場では気をつけている。

参考: 非暴力コミュニケーション http://nvc-japan.net/nvc/

lacolaco as a 個人事業主 2021秋

lacolacoの個人事業主としての活動について 2021年秋の近況

一次情報は ⬇️こちら⬇️

lacolaco.biz

近況

稼働状況

  • 副業として稼働中
    • 本業が週4勤務なので、毎週水曜日を副業用に空けています

技術アドバイザリー

  • Slackでのアドホックな相談 + 定期的なミーティング、という形式で数社と契約中
  • 新規契約は募集中ですが、自分から積極的に増やそうと思ってないのでご連絡待ちです

言語化支援をはじめたい

本業(Classi)の社内でやってる僕の1on1の評判がよいので、社外でも需要があるのではないかと思って1on1ミーティング形式の「言語化支援」サービスをはじめます。

lacolaco.notion.site

たとえばこんな形で力になれると思います。なにかしら課題を感じているテーマを持ち込んでもらえることを想定してます。

  • 抽象的な問題(技術的なものに限らず)についての考えの整理
  • プライベートな悩みの解消に向けた課題の整理
  • コミュニケーションにおける物事の伝え方、受け取り方の相談
  • チームビルディングや目標設定など、共通認識を形成するプロセスについての相談

まったく手探りなので、しばらくはTwitter相互フォローの知り合いに限定して対価無しで実験台になってもらいたいと考えてます。 どんなテーマでも構わないので論理と言葉の組み立てを手伝わせてくれる人、なんとなくlacolacoと1on1してみたいだけでもいいのでTwitterで「ブログ見たよ」とDMください!(秘密保持契約を結ばなくていいレベルの話題でお願いします)

問題はどこにもない

QuestionではなくProblemとしての「問題」についてのlacolacoの考え方

  • 「事実として問題であること」はどこにも存在しない
  • まず、「事実」なるものの存在を否定する
    • まさしく事実なるものはなく、あるのはただ解釈のみ (ニーチェ『権力への意志』)

    • 当然、「事実として問題であること」もない
    • 「まさしく問題なるものはなく、あるのはただ嫌悪のみ 」
  • 「これは問題だ」と感じるとき
    • ここで疑いようのない確かなことは、 「私」に「これは問題だ」と感じさせる「何か」がある ということ
    • 問題感・課題感
      • 恐れ、憂い、抵抗、総じて不快なものに対する嫌悪の反応である
    • 問題とは、 「何か」に対する「私」の捉え方 の名称である
      • 「問題視する」とは言い得て妙
      • 「問題として見ている」のは「私」自身
  • 問題の解明
    • スタート地点は: 「私」に「これは問題だ」と感じさせる「何か」がある
    • その「何か」が備える何らかの属性が、「私」の中の問題意識を刺激している
    • その条件を追求する(現象学的還元)
    • あらゆる解釈・認識は自身の欲望に相関する(欲望相関性)
      • 達成したい目標があるから、それを阻害する要素が「問題になる」
      • 実現したい状態があるから、それに不都合な要素が「問題になる」
    • まずはその欲望を言語化するところからはじめる
  • 問題意識の共有
    • 問題は 「私」と「何か」の関係性の中で立ち現れる現象である
    • これを「われわれ」との関係性にするためには、問題意識を刺激する条件を共有する必要がある
    • あらゆる解釈・認識は自身の欲望に相関する
    • 「われわれ」の欲望を共有することが、問題意識を共有するための前提になる
      • 「われわれは何を実現したいんだっけ?」
      • つまりインセプションデッキの1枚目

決める場と考える仲間

場と人間の関係性、そしてチームをつくるということについて。

「決める場」

  • ある事柄に関して、決定権をもっている「場」を指す
  • 多数決、あるいは議長による判断、なんらかのルールにそって合意形成をする場

「考える仲間」

  • ある事柄について同じ目的のためにともに考えてくれる他者を指す

「決める場」の思考

  • 「決める場」の思考は 損得勘定の思考
    • 事柄の必要性、自身への影響
  • 利害関係者としての思考

「考える仲間」の思考

  • 「考える仲間」の思考は 磨き上げの思考
    • 事柄の可能性、目的に対する効果、「よりよさ」の追求
  • 当事者としての思考

話している相手は「考える仲間」か、それとも「決める場」の利害関係者か

  • 利害関係者に対して「よりよくする」ことを一緒に考えてもらおうと思ってもうまくいかない
    • 自身への影響が現実的に想像できるようになるまで賛成も反対も起きない
  • 「決める場」が生む振る舞い
    • 「考える仲間」が少ない場では、事柄そのものの「よりよさ」へ関心が向けられない
    • 事柄の磨き上げではなく、場への働きかけによって決定を誘導できてしまう
    • ほかの人にどう反応してほしいかによって言葉や行動を選ぶ

「チームをつくる」とはどういうことか

  • 単なる個人の集団ではない「チームをつくる」ということ
    • チームとは、全員が「考える仲間」であること
  • つまり 「よりよさ」を追求しつづけるための構造をつくる ということ

下書き:

scrapbox.io