読書録

分類/書籍名 ページ数
設計(オブジェクト指向アーキテクチャなど) 3174
『実践ドメイン駆動設計』 618
『増補改訂版 Java言語で学ぶデザインパターン入門』 528
ユースケース駆動開発実践ガイド』 514
『実践テスト駆動開発 400
アンチパターン―ソフトウェア危篤患者の救出』 394
『新装版 達人プログラマー 職人から名匠への道』 383
『ビヨンドソフトウェアアーキテクチャ』 368
Web 2862
『Ruby on Rails チュートリアル』 829(*1)
『パーフェクト Ruby on Rails 【増補改訂版】』 528
『Webを支える技術 ―― HTTP,URI,HTML,そしてREST』 400
『Webフロントエンド ハイパフォーマンス チューニング』 337
『フロントエンド開発入門: プロフェッショナルな開発ツールと設計・実装』 285
『入門React: コンポーネントベースのWebフロントエンド開発』 259
『Web API: The Good Parts』 224
データ構造とアルゴリズム 2379
『世界で闘うプログラミング力を鍛える本 コーディング面接189問とその解法』 772
数学ガール/乱択アルゴリズム 485
『問題解決力を鍛える!アルゴリズムとデータ構造』 461
数学ガール/ポアンカレ予想 421
Pythonによるプログラミング入門 東京大学教養学部テキスト: アルゴリズム情報科学の基礎を学ぶ』 240
言語 1368
『プログラミングRust』 608
『Kotlinイン・アクション』 468
『メタプログラミングRuby 第2版』 292
ソフトウェア工学 1298
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 544(大型本)
『エッセンシャル スクラム: アジャイル開発に関わるすべての人のための完全攻略ガイド』 450
GitHub実践入門──Pull Requestによる開発の変革』 304
ネットワーク 1114
『コンピュータネットワーク 第5版』 1114
DB, SQL 660
『データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理』 660
Linux 440
『新しいLinuxの教科書』 440
エディタ 428
『実践Vim 思考のスピードで編集しよう』 428
コンピュータシステムの基礎,低レイヤ 416
『コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方』 416
コンテナ 384
『Kubernetesで実践するクラウドネイティブDevOps』 384
機械学習 320
『ゼロから作るDeep LearningPythonで学ぶディープラーニングの理論と実装』 320
プログラミング基礎 260
『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』 260
クラウド基盤 216
Amazon Web Services 基礎からのネットワーク&サーバー構築』 216
会計 752
『新・現代会計入門 第4版』 752
業務改善 1208
『独学大全 絶対に「学ぶこと」をあきらめたくない人のための55の技法』 788
『問題解決の全体観』 上下巻 420
ソフトウェアビジネス 284
ハッカーと画家 コンピュータ時代の創造者たち』 284
チーム運用 228
『Team Geek ――Googleのギークたちはいかにしてチームを作るのか』 228

(*1) Rails 6対応版のPDF換算のページ数

『 ソフトウェア品質知識体系ガイド(第3版)』学習メモ

第3版出版によせて

  • ソフトウェアシステムは、あらゆる社会活動の基盤であるとともに、新たな価値創造の基盤
    • 成功の鍵は品質
      • 過去の失敗や成功の経験から学び続ける
      • → 品質管理の本質をあらためて尋ねること
      • → 不確実な時代に必要な知見を新たに探ること
  • SQuBOK(Software Quality Body Of Knowledge)
    • 品質にまつわる経験や知見を体系化し、その体系へと容易にアクセス可能とするガイド
  • 第3版の改訂の要点
    • 引き続き重要なsoftware_qualityの知識体系の再整理
      • 国際規格の改訂の判定、セキュリティに代表される専門性の高い品質の知識拡充
    • 不確実な時代に不可欠なデータ駆動および価値共創における価値共創にソフトウェアの品質の考え方を取り込んだ
      • データとデジタル技術を通じたDXを進めるうえでデータ駆動および価値共創のパラダイムが根幹にあり、リスクを押さえつつその真価を最大限に発揮させるために必要な品質のマインドと技術の変革を整理
  • データ駆動は、データに基づき知的なサービスを適応的に提供しビジネスや社会上の価値を創造し続ける
    • 従来のような明確な正解に基づく計画的な品質保証よりも、目標に対し仮説的に組み上げてモニタリングし、変化に応じ改善し続ける仮説検証および探索的な品質の組み入れが重要性を増す
    • データやその源泉の規模および多様性に王子、セキュリティやプライバシー、相互運用性がより重要になる
  • 価値共創 → 能動的にあらゆる時点でモニタリングおよびフィードバックし続けるという品質の組み入れが重要

はじめに

  • SQuBOKのねらい
    • software_qualityに関する暗黙知形式知
    • software_qualityに関する最新テーマの整理、体系化

序章 SQuBOKガイド 概略

  • 知識領域を5つのカテゴリに大別
    • software_qualityの基本概念
    • software_quality_management
    • software_quality技術
    • 専門的なsoftware_qualityの概念と技術
    • software_qualityの応用領域
  • 構成
    • サブカテゴリ、知識領域、副知識領域を各カテゴリで見る
  • Error(誤り、誤差), Fault(障害), Failure(故障)の区別
    • Error: 計算、観測もしくは測定された値または状態と、真の、指定されたもしくは理論的に正しい値または状態との間の相違
    • Fault: 要求された機能を遂行する機能単位の能力の、縮退または喪失を引き起こす、異常な状態
      • ソフトウェアバグなど
    • Failure: 要求された機能を遂行する、機能単位の能力がなくなること
      • ソフトウェアが意図したとおりに動かない現象
    • 意図しない結果を引き起こす人間の行為はmistake, human_errorとして別に定義
  • メトリクスに関する擁護
    • measure, measurement_methodがmetricに代えて使用されているが、これまでの論に合わせて測定量や測定方法を区別したりISO/IEC 25000シリーズに言及するとき以外は、「メトリクス」を用いる

Ch01 software_qualityの基本概念

KA: 品質の概念

  • 品質の定義
    • software_qualityの代表的な定義: 明示された状況下で使用するとき、明示的ニーズまたは暗黙のニーズを満たすためのソフトウェア製品の能力
    • 品質の本質の理解のためには、顧客の要求把握、要求の実現、結果として得られる顧客満足という3つの要素から考える
    • 顧客の要求
      • 明示的要求や規制要求事項だけでなく、明示されない常識的な要求や潜在的なニーズや期待などを含む
      • 時間の要素も考える
      • 要求の取捨選択やバランスが重要
    • 要求の実現
      • 多くの技術の中から適切な技術を選ぶ
      • 技術利用の場面では、プロジェクトに与えられたQCDやプロジェクトの技術レベル、プロセス、開発環境などのプロジェクト特性を考慮し、適用する技術の効果が出るように工夫が必要
      • セキュリティインシデントのようなリスクを低減させつつ、つながることによる便益を最大限にするといった要求の実現が求められている
    • 結果として得られる顧客満足
      • 顧客の予想を超えた価値の提供が重要
      • 使う人や社会の認識の変化に追従して品質要求も変わっていく
      • モノの提供によりコトをつくりだす「コトづくり」において、その本質はQOLの向上に寄与する生活イノベーション
        • 個々の生活者のライフスタイルに応じた、非物質的で精神的な豊かさを作り出すことがコトづくり
        • コトづくり: モノづくりに参加する人たち遠因に夢やロマンある目標や将来像を明示し、その実現のためにみなが奮い立ち、情熱を持って、力を合わせて働きたくなるような仕組みや仕掛け、システムを組み込むことでもある
        • → 提供側の満足も引き出す
    • ICTの進展に伴ってIoTやAIの適用が拡大するにつれ、品質に対する要求はますます多様な広がりと深さを増す
      • IoTでは、セキュリティ、セーフティ、信頼性に加えて、プライバシーやレジリエンス(跳ね返る→前の位置に戻る、中止する)などが重要な特性
      • AI では、AIの予測精度だけでなく、利用目的に応じて、公平性、説明可能性、プライバシー、信頼性、セキュリティ、セーフティなどさまざまな特性が求められる
    • → 幅広い要求を説明する用語として、Trustworthinessが使われるようになった
  • 企業と品質のソフトウェア
    • 企業の視点からの品質の意味
    • どのような経営環境の変化にも的確に対応し、顧客からの高い評価を受け続けることで、持続的な経営ができる
    • 経営の要素として、ヒト、モノ、カネ、情報
      • DXにより企業の経営スタイルやビジネスモデルは変革期にある
    • ソフトウェアシステムは社会基盤として極めて重要な位置づけとなった
    • 社会生活を支えるうえで求められる品質は多岐にわたり、継続的な維持と時代に合わせた変革が必要
    • サービスの価値が利用体験の中で便益を享受したものが独自に見出すものであることから、企業と顧客の価値共創が品質の要となる
    • このように、ソフトウェアの位置づけの変遷、価値の認知や送出スピードの変化を的確に把握して、製品やサービスの品質を考えることが肝要
  • software_qualityに関する用語
    • 序章のError, Fault, Failureの部分
    • 機能性欠陥は、障害の定義に該当し、故障を引き起こす
    • 発展性欠陥は、コードの読みやすさや構造などに起因し、コーディングルールなどの組織標準との乖離(anomaly)に相当する
      • 保守工数の増大や機能性欠陥の誘発へとつながるものの、必ずしも故障を引き起こさない
      • 開発途中の障害には発展性欠陥も含める
  • S-KA: 品質の定義(品質の考え方の変遷)
    • 製品の物質的性質や仕様適合を重要視する考え方から、提供された製品に対する顧客の心理的な受け止め方や顧客満足を重要視する考え方へと変化している
      • 経済学の「効用」など
    • T: 海外の品質の定義
      • 「品質は誰かにとっての価値である」など
    • T: 日本の品質の定義
      • 魅力的品質一元的品質、当たり前品質
      • ニーズにかかわる対象の特徴の全体像という考え
        • 品質は、製品やサービスの提供側ではなく顧客の価値基準で決まる
    • T: 品質とdependabilityの定義
      • dependability: 広い意味の品質に関わる概念
        • 特に時間軸上の品質問題を意識しており、時間の経過に伴う使用状況の変化や、利用に伴うシステムの経年劣化や摩耗部品の交換修理といった概念と関係する
        • 保全性はdependabilityの重要な構成要素
  • S-KA: software_qualityモデル
    • ソフトウェアの品質を階層構造のモデルで表現したもの
      • 誤りの有無のみで評価されるのではなく、ユーザのニーズを満たすために様々な視点のsoftware_quality特性から評価が必要
    • T: システムおよびソフトウェア製品の品質モデル(ISO/IEC 25000シリーズ)
      • システムおよびソフトウェア製品の品質要求と評価に関して規定している国際規格
      • SQuaREシリーズと呼ぶ
      • 利用時の品質モデル
        • 利用者が実際に把握できる品質特性からなるモデル
        • 有効性、効率性、満足性、リスク回避性、利用状況網羅性
      • 製品品質モデル
        • 機能適合性、性能効率性、互換性、使用性、信頼性、セキュリティ、保守性、移植性
      • データ品質モデル特性
        • 正確性、完全性、一貫性、信憑性、最新性、アクセシビリティ、標準的合成、機密性、効率性、精度、追跡可能性、理解性、可用性、移植性、回復性
      • 25000 シリーズの構成
        • 品質管理部門
          • 共通するモデル、用語の定義
        • 品質モデル部門
        • 品質測定部門
        • 品質要求部門
        • 品質評価部門
        • SQuaRE拡張部門
    • T: その他の品質モデル
  • KA: software_qualityの概念
    • software_quality: 品質に関する「組織を指揮し、管理するための調整された活動」
      • 主眼: 顧客の要求事項を満たすことおよび顧客の期待を超える努力をすること
    • 急激なビジネス環境の変化に対応するために、組織の状況に応じて動的に適応できる能力が重要
    • → 制御や統制というより、環境変化へ柔軟かつ臨機応変に適応しながら目的を達成していく活動といった意味に拡大解釈されるようになった
    • 品質は、意図した機能やパフォーマンスだけでなく、顧客によって認識された価値および顧客に対する便益も含まれる
    • ISO 9000では、software_qualityは全体を包括する用語
      • 品質計画において、品質要求事項を満足するための基準などの計画を策定する
      • → この計画にしたがって基準と照合し、基準を満足した製品とすることが品質管理
      • 品質保証は、品質を確認する活動の実施状況を、証拠をもって示す活動
    • 新製品開発重点主義
      • 品質は設計と工程で作りこむ
    • 要因系に焦点を当てるsoftware_qualityは日本で発達してきた方法であり、製品とサービスを作り出すプロセス重視のマネジメント
      • 原因を排除することで、初めから品質の良いものを作り出すプロセスづくりを基本とする
      • → プロセス実施状況を計測して分析し、プロセスを改善する
    • S-KA: 品質保証の考え方
      • ISO 9000では、品質保証を「品質要求事項が満たされるという確信を与えることに焦点を合わせたsoftware_qualityの一部」と定義
        • 活動内容について、信頼感を付与するために証拠をもって示すよう要求
      • 国や地域によって意味が異なる
        • 日本では、顧客満足のための活動を総称する意味で使うことが多く、活動内容の実証を必ずしも重視していない
          • 顧客が満足したという結果をもって、品質保証活動の成果を測るような考え方
          • → かなり広い意味を持っている
          • 顧客が安心、満足、長く使用できることを目的として品質保証が実施されるようになった
            • 品質保証書つきでないと売れない時代
        • 欧米では、契約社会という文化的背景から、品質保証していることの「実証」を重要視して発展してきた
        • ISO 9000と日本流どちらの解釈でも、品質保証を顧客満足を目的とした活動と位置づける点は同じ
      • 方法は、プロセスのアウトプットであるプロダクトの品質を直接確認する方法と、プロセスの実行状況を監視することで品質が確実に作りこまれていることを確認する方法がある
        • これらを、要求品質レベルに応じて組み合わせて実施することが大切であり、どちらかに偏っては不十分
        • 不適合品の生成を減らす必要もあるし、不適合品を検出する必要もある
        • プロダクトとプロセスの両面から品質を確認することが肝要
        • そのほか、V&Vや測定などの品質保証のための重要な手法も、要求品質レベルに合わせて実施する
    • S-KA: 改善の考え方
      • 改善: 市場や事業環境の変化へ効果的に対応する自己変革のメカニズム
      • 目的を効率よく達成するためのすべての活動がマネジメント
        • 改善はそのための武器
      • 目的に対して、より効率よく達成するための方法を模索し、不備を明確にして自己を変えていく、論理的かつ体系的は修正が改善
        • 基盤となる標準が必要
        • → 組織の経験やノウハウを標準として整理し、その標準を出発点として不備を明確化し、修正する
      • ISO 9000では、改善を「パフォーマンスを向上するための活動」、継続的改善を「パフォーマンスを向上するために繰り返し行われる活動」、革新を「価値を実現するまたは再配分する、新しいまたは変更された対象」と定義して区別している
        • 本来の改善は、それぞれの意味を含む
      • 急激な社会変化に対応するためには、抜本的な改善や革新を含めた「改善」が必要
      • T: PDCA
        • 計画では、目的、目標、狙いを明確にし、目的達成のための手段や方法を決定する。そして管理項目を決め目標値を設定する
        • 実施では、管理項目のデータを取りながら計画を遂行する
        • 確認では、目標達成にかかわる進捗や対応状況を、データをもとにして論理的に判断する
        • 処置では、目的あるいは目標と実施の結果に差があるかを見て、その差に応じて対処し、次の計画に結びつける
        • OODA
          • 指揮官のあるべき意思決定プロセスを理論化したもの
          • スピードと柔軟性を重視し、ループを高速で回して意思決定を繰り返す
          • 計画の代わりに観察から始まるので、状況に応じて臨機応変に意思決定できる
      • T: 改善(KAIZEN)
        • 現状の不備を明確にして、その不備を論理的かつ体系的に修正する活動
        • 目的: 品質、コスト、納期の向上を含む総合的なsoftware_qualityを達成すること
        • 全員参加かつ継続的な活動
        • すべての人がプロセスオーナーの意識
          • 責任感と自負心の向上を促す
          • → 組織全体で自律的に不備を修正
          • ↑ 常に変化する事業環境や市場に対応するための重要な施策
        • ソフトウェアでは細かいミスにより致命的な結果を招くことがあるので、改善(KAIZEN)は重要
          • 常に新しい技術やサービスが生み出される市場でもある
        • ツールとして、QC_circle活動
        • TQM(Total_Quality_Management)の中核
  • KA: ソフトウェアのsoftware_qualityの特徴
    • 物理的実体を持たない論理の集合体なので、開発の工程はハードウェアの設計工程に近い
    • 物理化学法則や空間的干渉がないという点で、自由度が高い
    • → 構成要素の組み合わせが膨大になり、論理無住などの誤りを作りこみやすい
    • 技術の変化が速いので、再利用部品の開発は難易度が高くなっている
    • 論理の集合体であるソフトウェアは、外部仕様である働きとその働きを実現する内部仕様との2つを関連付けることが難しい
      • → ソフトウェアを変更する際の難しさの本質
    • 測定すべき物理特性がほとんど存在しないため、何らかの特性を定義しながら設計する必要がある
    • 生産工程がないうえに測定が難しいので、ソフトウェアのテスト工程はハードウェアの検査工程とは異なる位置づけになる
    • → ソフトウェアのテストはハードウェアのDR(設計レビュー)に対応し、非常に高いスキルが要求される
    • 物理的実体がない → 劣化しない
    • ソフトウェアの障害はすべて系統故障 → 同一の条件下では必ず障害が発生してしまう
      • → 故障率やMTBFなどの信頼性指標では単純にソフトウェアの信頼性を表せない
    • ソフトウェアの障害の体系化のためには、障害の原因調査、影響評価を行い、ソフトウェア故障モードを抽出する取り組みが必要
    • 自然言語の使用
    • 開発そのものが難しいだけでなく、開発のゴールを記述する仕様の信頼性も低くなりがち
    • ソフトウェアの開発は人間の知的作業による
    • 人間の知的作業の質は、モチベーションが大きく関係する
    • → やりがいを感じ、快適と感じられる環境が必要
      • チームワークやリーダーシップ、それらを支えるコミュニケーションも重視
    • これらの特徴を十分理解したうえで、ソフトウェアのsoftware_qualityを実施する必要がある
      • まず、定石やデザインパターンなどを用いて設計の自由度を抑制し、品質向上に寄与する指標を検討するといったソフトウェアエンジニアリングの充実が必要
      • 仕様のレビューや管理も重要
      • 次に、障害を分析することで、故障モードのようなソフトウェア開発の悪さの知識を抽出し、体系化したうえで蓄積が必要
      • モチベーションとチームワーク
    • 例: アジャイル
      • 開発の難しさの本質は変わらないが、細かい単位の開発は、ソフトウェアの仕様のあいまいさやそれに伴う信頼性の低下を緩和する可能性がある
    • S-KA: プロダクト品質とプロセス品質
      • ソフトウェア製品のライフサイクルにおける品質を、製品そのものおよび過程の2つの側面から捉えた品質
      • 図1.3.1: ライフサイクルでの品質
        • ソフトウェア製品の品質を、内部特徴、外部特徴、利用時の品質の3つに分類し、それぞれが影響と依存の関係にあるとしている
      • 一般的な製品の品質管理では、プロセス品質をプロセス能力や工程能力もしくは工程性能を呼ぶことがある
        • プロセスの品質をアウトプットのばらつきとして捉え、このばらつきを収束させることでプロセスの安定した結果を保証できると考えているため
        • プロセスのばらつきとして管理する対象は、プロセスの成果物の障害だけでなく、コストや納期なども対象になる
        • ばらつきを収束させる活動として、プロセスの改善活動が行われる
        • 初期の段階でばらつきの少ない状態を得ることを目的として品質工学の手法が適用されることもある
      • 仕様の間違いやプログラムの誤り(一般的な障害)は、プロダクト品質のばらつきとして品質管理手法で制御可能
      • ソフトウェアの仕様や機能の品質は、上流工程の規格や設計で作りこむ必要がある
    • S-KA: 品質作りこみ技術の考え方
      • 成果物を作成する過程で品質を確保するための作業を施し、後に続く工程に障害を流さないようにするという考え方に基づく技術
      • 主に作成後のソフトウェアの評価を目的とするテストとは考え方が異なる
      • 要求分析や設計の工程では、対象をモデル化してシミュレーションや形式手法による検証を実施することにより、要素間の干渉や矛盾を明らかにし、実現可能性を評価できる
        • モデル化: 認知したい構造、振る舞い、現象などについて、別の効率的な形式や方法による表現を用いること
          • 複雑さ、不可逆性を回避するよう単純化し、もとの現象などを扱いやすくすることが多い
          • たいていは抽象化を伴う
      • モデルを用いたシミュレーションは、実装前にシステムの振る舞いを確認できるという点で、開発中に品質を作りこむ方法
      • 数理的な理論に基づき厳密なモデルを作成できれば、形式仕様記述やモデル検査を提供する各種の形式手法を用いて、論理的な不整合の検出や動作の妥当性の検証が可能になる
        • 形式仕様記述: どのように実装すべきかという問題から離れ、システムが何をすべきかを仕様として記述
        • モデル検査: 仕様からモデル検査器に入力するモデルと検査項目を作成し、モデルが取り得るすべての状態に対して検査項目を満たすかどうかを調べることにより、障害を発見する
        • モデルを活用する際は、対象ソフトウェアやアーキテクチャ、モデルの活用から得られる効果や工数にも配慮し、重要な部分、効果の期待できる部分に適用することが肝要
      • ソフトウェアパターンの適用もまた、開発中に品質の作りこみを期待できる方法
        • ソフトウェアパターン: ソフトウェア開発の工程や領域の特定文脈上で繰り返される問題と、それに対して繰り返し適用されてきた熟練者による解決策をまとめて名づけ抽象化したもの
        • 繰り返し利用されてきた解決策の思考過程と成果を再利用することにより生産性や品質の向上を期待できると同時に、適用対象の構造を一貫させ、利害関係者間のコミュニケーションや理解を促進する
    • S-KA: システムおよびソフトウェアの測定と評価の考え方
      • システムおよびソフトウェアの測定は、「測定量の値を決定するという目的を持った操作の集合」と定義されている
      • 測定を本格的、体系的に導入する際は、多くの工数が必要になる
      • 測定の妥当性や必要性を真の目的に照らして絶えず見直し続け、形骸化させないよう留意する
      • システムおよびソフトウェアの評価は、「ある"もの"が、規定要求事項をどれだけ満たすことができるかの程度を示すための体系的な審査」と定義されている
        • ソフトウェア製品の品質を向上させるためには、製品の品質上の属性の測定だけでなく、測定結果を活用した品質評価が不可欠
      • 評価結果のよしあしの判断根拠となる要求事項があらかじめ明確化されていること、および、評価プロセスが確立されていることが必要
      • 要求事項は、汎用の品質モデルを用いることで、品質特性と品質副特性を網羅的に定義できる
      • 評価プロセスの共通的な枠組みは、「最初に評価要求を確立し、次に評価を仕様化し、設計し、そして実行する」プロセスとして定義されている
    • S-KA: V&V(Verification & Validation, 検証と妥当性確認)
      • Verification: 仕様適合性を確認
      • Validation: ニーズ充足性を確認
      • merit
        • リスクが高い問題の早期発見
        • システム要求に対する成果物の評価
        • 品質と開発進捗状況に関する情報の継続的な共有
        • システムのできばえが順次見えることによるユーザとの早期調整
      • Independent V&Vもある

Ch02 software_quality_management

  • 品質管理のためのアクティビティについて
  • 品質は経営層から現場に至るすべてのレイヤの体系化されたアクティビティにより追求すべきものであり、品質管理に関するアクティビティは多岐にわたる

組織レベルのsoftware_quality_management

  • KA: software_quality_management_systemの構築と運用
    • quality_management_systemと改善アプローチ
      • 主眼: 顧客の要求事項を満たすこと、および顧客の期待を超える努力をすること
      • quality_management_systemは、quality_management活動のパフォーマンスを計画し、実行し、監視し、改善するための枠組みを提供する
      • 有効性の改善には、プロセスアプローチが推奨される
        • 相互に関連するプロセスで構成されるため、システムによって結果がどのように生み出されるかを理解することで、組織はシステムやそのパフォーマンスを最適化できる
      • 急激なビジネス環境の変化 → quality_management_systemを動的なシステムとして捉えるようになった
        • この場合も、計画の実施をquality_management_systemのパフォーマンスの両方を定期的に監視および評価することが重要
    • quality_management_systemの特徴と対応
      • ソフトウェアは、開発過程を見える化しにくく状況や状態を把握しづらい、論理の塊
      • チームワークなどの人間的要素が強く品質へ影響するといった特徴
      • → 見えにくい対象を把握し、論理の塊を技術面から整理して取り扱い可能にするとともに、開発者のチームワークやモチベーションを向上させる仕組みを持ったquality_management_systemを構築することがポイント
      • 2つの責務
        • 品質
        • プロセス
      • この2つの責務を明確にした組織形態がソフトウェアには必要
        • 製品の品質に対する責務だけでは、プロセスを大きく変えるような革新的な技術を導入する機会を持ちにくい
      • 両方の責務を持つという動機付けを持った組織が、quality_management_systemを推進することが重要
      • 組織的かつ継続的にquality_management_systemを改善するには、障害の顕在化を契機として改善のサイクルを実行する活動が取り込みやすく効果的
        • 真の原因を分析することで、その障害が二度と作りこまれないようにプロセスを改善する
      • サービスも提供している場合はサービスも対象とする
        • サービスの品質は、モノの品質との違いから考えるのではなく、サービスを中心において、その提供者と受容者が共創しながらサービスやモノの価値を作っていく
          • SLAやDevOpsとも関係が不快
    • S-KA: quality_management_system
      • quality_managementには、品質方針および品質目標の設定、ならびに品質計画、品質保証、品質管理および品質改善を通じて、これらの品質目標を達成するためのプロセスが含まれている
      • 目指すべき品質目標は、トップマネジメントによる品質に関する方向付けのもと設定される
      • 日本のTQCおよびTQMの発展の中で培われたquality_managementの考え方: お客様が安心して使っていただけるような製品を提供するためのすべての活動
        • 徹底した顧客満足の追求や品質を中核とした全員参加での改善が基本
        • 不十分でもとにかく動き出して全員が今より高いところを目指してプロセスそのものを動的に改善しながら進めるという、日本独特の考え方
          • 欧米は、プロセスを定義してそのとおりに実行しているかどうかを確認する
        • QC_circle、統計的技法などの道具を試用し、組織全体がシステムとして機能しているかのような日本型のマネジメントシステムのメリットは、全員が同じ目的に向かって活動するために効率的で無駄のない組織運営ができる点
      • T: quality_management_systemに関する規格(ISO 9000 series)
        • 目的
          • 経済活動のグローバル化が世界的に進む中、スムーズな商取引のためにquality_management_systemへの要求事項の標準化が求められた
          • quality_management_systemの認証制度により急速に普及
        • 方法
          • quality_management_systemの認証制度の基準規格はISO 9001
        • 効果
          • 認証により、自組織のquality_management_systemが世界に通用するものであることを証明するとともに、継続的な審査によりそれを維持できる
        • 留意点
          • 認証があっても品質に問題がないとは限らない
          • コストに見合う改善効果が得られるとは限らない
          • ISO 9001の要求事項への適合にとどまらず、製品およびサービスレベルの改善や顧客満足の向上を意識した改善活動をするとよい
      • T: TQM(Total_Quality_Management)
        • 企業及び組織の経営の「質」の向上に貢献する経営科学および管理技術
        • 「質」: 経営プロセス(Value_Chain)とそのプロセスに関わる広義のリソース(経営資源)の質
        • QC, TQCに続く第3世代の品質管理
          • 世代ごとに、製品そのもの → プロセス → 総合「質」が管理対象
        • 持続可能な成長をもたらすための方法論として、TQCの強みを継承して生まれたのがTQM
        • 目的
          • 企業や組織が「尊敬される存在」「ステークホルダーと感動を共有できる関係」を目指し、「称賛される競争力(技術力、対応力、活力)」の向上を図る
        • 方法
          • 構成要素
            • フィロソフィー、コア・マネジメントシステム、手法、運用技術
          • これらの適用により、経営プロセスや経営リソースの質的向上を目指す
          • 手法には、科学的問題解決法、QC7つ道具、新QC7つ道具など、ソフトウェア組織でもなじみ深い手法が含まれる
        • 効果
          • 企業の競争力向上による収益力の増大を実現するとともに、重要な経営課題をいち早く察知し、解決することに貢献する
        • 留意点
          • TQMは、プロセスとして定義可能であり、結果を左右する要因を制御できるような領域に適用可能
          • 政治的要因や文化的要因、情緒的要因などが大きくかかわるような領域では効果を発揮しにくい
      • T: quality_management_system-持続的成功の指針
        • 成熟した経済社会環境にある企業が、経営環境の変化に的確に対応し、顧客からの高い評価を受け続けることによって、財務的にも持続的に成功するような経営スタイルを実現するための指針を示す規格
        • 目的
          • 成熟した経済社会環境にある企業が、持続的成長を実現するための指針を与える
        • 方法
          • 品質という観点から事業運営を見直し、事業運営とは競争環境における顧客価値提供マネジメントであるとの視点に立ち、製品およびサービスを通して顧客にどのような価値を提供すべきか、その価値提供において組織が持つべき能力は何か、その能力はquality_management_systemのどの要素に実装されるべきかを考察する
          • → 事業環境変化によって組織が持つべき能力がどう変わるかを認識し、革新していく
        • 効果
          • 企業が高い顧客価値を創造し続け、競争優位を確保し、持続的成功を実現できる
        • 留意点
          • 第1版での「質」とした(「品質」としなかった)理由について
    • S-KA: security_management
      • セキュリティ、すなわち守るべき資産の価値が損なわれる脅威を回避、もしくは軽減することを、組織全体を対象としてマネジメントすること
      • T: common_criteria(CC)
        • ソフトウェア、ファームウェアまたはハードウェアとして実装されたIT製品のセキュリティ評価のための共通基準
        • 構成
          • 一般的な概念とモデル、機能性に関する共通要件、保証手段に関する共通要件
        • 評価プロセスにおいてCCのための共通評価方法(CEM)を使うことで、広範な対象者が国際的に共通の枠組みに基づいて評価結果を比較及び参照可能となっている
          • CC/CEMと表記
        • 主要各国のIT製品のセキュリティ評価認証制度に適用され、主に政府機関で調達要件として活用される
        • 目的
          • CC/CEMをソフトウェアの開発プロセスに提供することで、セキュリティ上の脅威に対して有効かつ整合の取れたセキュリティ機能を実装し、要求に応じた脆弱性への対応レベルを満たすための保証を実現する
          • 実現した保証の度合が国際的な水準を満たしているかどうかを明らかにする
        • 方法
          • 開発するソフトウェアのセキュリティ評価にCC/CEMを適用する一般的な方法
            • そのソフトウェアに適用すべきPP(Protection_Profile)の有無を確認の上、保証のレベルと評価対象の範囲を特定
            • CCを参照し、保護資産、脅威、セキュリティ目標、セキュリティ機能要件、セキュリティ保証要件、および要件の実現方法を定義するST(Security_Target)を作成する
            • ソフトウェア開発において、STに従ってセキュリティ機能を実装するとともにCC/CEMを参考として実装の各プロセスである開発、ガイダンス、ライフサイクルサポート、テストおよび脆弱性への対応に係る保証手段がSTで定義したレベルを満たすことを保証するエビデンスを作成する
            • ITセキュリティ評価認証制度を利用する場合、認証申請手続きとしてST を認証機関に提出後、第三者評価機関による評価を受け、評価結果について認証機関の確認を経て、そのソフトウェア製品に対する認証書を取得する
        • 効果
          • ソフトウェア開発において、セキュリティ要件を英利子、具備すべきセキュリティ機能と実施する保証手段の妥当性を国際基準に基づき自己評価するために役立つ
          • ITセキュリティ評価制度の評価及び認証プロセスを通して、セキュリティ機能と保証手段がセキュリティ要件を満たしているかどうかを明らかにできる
          • STおよびこれにもとづく保証がCC/CEMを満たし、要件に対して顕在化する脆弱性が存在しないことが本評価および認証プロセスで確認された場合、対象製品のCC 認証を取得でき、CC認証製品であることが求められる調達に参加できる
          • STおよび評価結果は、製品の購入を検討する利用者が、その製品が利用者の使用用途に対して十分なセキュリティ機能性を具備しているか、仕様に当たって残存するセキュリティリスクを許容できるかを決定するために役立つ
        • 留意点
          • CC/CEMは随時更新されるため、評価を受ける場合に有効なバージョンを確認する必要がある
      • T: ISMS(Information_Security_Management_System)
        • その組織が自身の情報セキュリティを確保し維持するために、継続的に運用する枠組みのこと
        • 範囲: 組織全体にわたってセキュリティ管理体制を構築し、監査することと、リスクマネジメントを実施すること
        • JIPDECが日本国内におけるISMSの適合性評価制度の確立と普及推進を実施している
        • 目的
        • 方法
          • 参考規格が記載されている
        • 効果
          • ISMSを構築し運用することで、その組織は一定のセキュリティ管理レベルを維持できる
          • 認証を受けた場合、取引先などに対し、情報セキュリティについて一定レベルの管理ができていることを示せる
        • 留意点
          • メリットとデメリットの整理が必要
  • KA: lifecycle_process_management
    • ソフトウェアやシステムの構想から廃棄までの活動に対するマネジメント
    • 主たる目的: ライフサイクルモデルを使うことで、発注者、ベンダー、サブコントラクターなど、すべての関係者が共通の言語を使え正確に意思の疎通を図れるようにすること
      • プロセスをアセスメントして改善する国際標準ISO/IEC 33002におけるプロセス参照モデルとして活用することなども想定
    • 安全性を重視するソフトウェアの品質の確保には、ソフトウェア自体の機能的要因だけでなく、その開発過程に係る要因を考慮する必要があるとの認識から、safety_critical_lifecycle_modelが提案されるようになった
    • ライフサイクルモデルにおけるプロセスモデルとは、ライフサイクルモデルが定義する活動のうち、開発部分をモデル化したもの
    • プロセスモデルは、さまざまな開発方法論で定義する開発作業をプロセスとして構成し、開発工程と手順を抽象化してモデル化している
      • 開発の内容や特性に応じてモデルの選定が必要
    • S-KA: ライフサイクルモデル
      • ソフトウェアおよびシステムの構想から廃棄までの活動を、特定の開発方法論およびベンダに依存しない「共通の言語」として制定したもの
      • 多様なニーズに対して製品やサービスの統合が困難になったという問題の克服が必要になったため生まれた
      • 方法
        • ソフトウェアおよびシステムの企画、要求定義から廃棄、処分までのライフサイクルにわたるプロセスを包括的に規定
        • 使用者は目的に応じて、組織、プロジェクト、業務に合わせて部分集合を選択したりテーラリングしたりする
      • 効果
        • 当事者間で開発手順、工程、作業内容、用語などが異なることから生じうるコストや品質面の混乱の防止
      • 留意点
        • 深い解釈や実際の行動面まで整合させると〇
    • S-KA: プロセスモデル
  • KA: ソフトウェアプロセス評価と改善
    • ソフトウェアプロセスをプロセスアセスメントモデルに照らして評価し、それを継続的に改善する活動のこと
    • 求める結果を獲得するためにソフトウェアプロセスを意図的に変更・改善する
    • プロセスを系統的、継続的に改善するためには、プロセスに関する定量的なメトリクスを定義したうえで収集、分析し、評価することが必要
    • 改善の対象は、ソフトウェア開発の技術やツールなどを含めた一連の工程、プロセス
    • 包括的なプロセスモデルとしては、CMMI(Capability_Maturity_Model_Integration)など
    • ISO/IEC 33000シリーズなど特定の産業や分野によらない汎用的なモデルがある一方で、Automotive SPICEやTMMiなど特定の業界及び分野に特化したプロセスモデルも提案されている
    • プロセスモデル適合の目的化やトップダウン偏重による形骸化の回避のため、問題解決型アプローチも提案されている
    • 特徴を十分に理解したうえでのプロセスモデルの活用、そしてそのプロセスがエンジニアのスキルやモチベーションにどのような影響があるかといった人的配慮を含めた本質的なプロセス改善のあり方について、引き続き検討が必要
    • S-KA: software_process_evaluation_model
      • ソフトウェアプロセスの改善を目的として作成されたプロセスモデル
      • T: CMMI
        • 顧客やエンドユーザのニーズを満たすための高品質な製品とサービスを開発する活動に対して、包括的で統合された一連の指針を提供するモデル
        • 「システムや成果物の品質は、それを開発し保守するために用いられるプロセスの品質によって大きく影響される」というプロセス管理の前提にもとづいて開発された
        • → 事業者が主要な事業プロセスの実績を改善することを可能にする、統合されたベストプラクティスの集合
          • 単なるプロセス改善モデルから、ビジネス上のパフォーマンスを向上するためのモデルという位置づけに変わってきている
        • 組織におけるプロセス改善に焦点
          • 場当たり的で未成熟なプロセスから、改善された品質と有効性を伴った秩序ある成熟したプロセスへの深化の改善経路を、プラクティス領域により示す
        • 成熟度レベル
          • プロセス領域の集合に1つ1つ順番に取り組むことにより、関連するプロセスの集合を組織が改善するアプローチ
        • 能力度レベル
          • 組織が選択したプロセスを1つ1つ改善するアプローチ
        • 今後、セーフティやセキュリティ管理、人材管理のプラクティスが追加される予定
        • Method_Definition_Document(MDD)
        • 目的
          • 製品の開発と保守、サービス提供、調達に関するプロセスの成熟度レベルおよび能力度レベルを、内部プロセス改善および外部向け成熟度および能力判定のために示す
        • 方法
          • MDDに定義された評定方法により、CMMIの選択した関連要素群と表現に照らして評定する
        • 効果
          • 客観的証拠に基づいた評定結果を提供できる
        • 留意点
          • 成熟度レベルや能力レベルの達成が、手段から目的に転化し、実際のプロセス改善に結びつかない場合がある
          • → 真の目的を理解した上位管理者のリーダーシップのもと、現場の改善を推進するための資源の確保が〇
      • T: プロセスアセスメントに関する規格(ISO/IEC 33000シリーズ)
        • 目的
          • 製品の開発と保守、サービス提供に関連するプロセスの能力レベルを、次の目的のために評価
            • プロセス改善のために自己のプロセスの状態を理解する
            • 特定の要求事項に対する自己のプロセスの適切性を判定する
            • 契約相手のプロセスの適切性を判定する
        • 方法
          • PRM(Process_Reference_Model)、測定の枠組み、PAM(Process_Assessment_Model)によりアセスメントを行い、プロセスの能力レベルを判定する
        • 効果
          • 目的に対して客観的証拠に基づいたアセスメント結果を提供できる
        • 留意点
          • 能力レベルの達成が、手段から目的に転化することがある
          • → 真の目的を理解した上位管理者のリーダーシップのもと、現場の改善を推進するための資源の確保、さらに実務層が当事者意識を持ち取り組む環境の構築が〇
      • T: Automotive SPICE(Software Process Improvement and Capability dEtermination)
        • 自動車業界の標準として要件抽出、システム要件分析、システムアーキテクチャ設計などのシステムエンジニアリングプロセス群や、ソフトウェア要件分析、ソフトウェアアーキテクチャ設計などのソフトウェアエンジニアリングプロセス群などが定義されている
        • 目的
          • 車載システムの開発プロセス定量的に測定し、プロセスアセスメントやプロセス監査を見える化し評価することで、プロセス改善につなげる
        • 方法
          • PRM、測定の枠組み、PAMを用いてアセスメントを行い、プロセスの能力レベルを判定する
        • 効果
          • 車載システム開発のプロセスに対して、客観的証拠に基づくアセスメント結果を提供できる
        • 留意点
          • ほかのプロセス評価モデルでのアセスメントと同じ
      • T: TMMi(Testing Maturity Model Integration)
        • テストプロセスを段階的に改善していくための技法
        • CMMIと親和性が高く、テストプロセス部分を補完するモデル
        • このほかに、TPI(Test Process Improvement)もある
          • TMap(Test Management approach for structure testing)という構造化されたテストプロセスの方法論をベースにしている
          • TPI NEXT
            • BDTPI(Business Driven Test Process Improvement)を基本モデルとして利用したもの
        • 目的
          • 開発プロセスの改善モデルであるCMMIと連携して、テストプロセスを段階的に構築する
        • 方法
          • CMMIと同様に5段階の水準とそのゴールで構成されている
          • 各水準は以下で構成されており、アセスメントをサポートするためのTMM-AM(TMM Assessment Model)を持つ
            • 成熟度ゴールのセット
            • 成熟度ゴールを支援するサブゴール
            • アクティビティとタスクとレスポンジビリティ
        • 効果
          • CMMIのようにトップダウンアプローチによる段階的なプロセス改善をするため、組織的、かつ、体系的にテストプロセスを改善できる
        • 留意点
          • CMMI同様、自組織のプロセスに当てはめて解釈したうえで、段階的に改善活動を行うと〇
          • そのための専任者や専任グループを確保し、改善を先導すると効率的
          • TMMiの推進はCMMIの導入が前提となっており、日本での適用報告例が限られている
    • S-KA: ソフトウェアプロセス改善技法
      • 品質の良いソフトウェアを開発するために必要な、さまざまな作業のフレームワーク改善を目的とした技法
      • T: Six_Sigma
        • アメリカにおける品質革命運動の中心的な経営革新技法
        • 標準偏差(σ)の6倍という意味
          • 品質特性が正規分布に従っているとき、規格幅が±6σ分あると、特性地の分布の平均が1.5σずれていても、不良率は片側4.5σ外の確率3.4ppmに抑えられる、すなわちミスを無視できるレベルまで下げるための方法論
        • DMAIC(Define, Measurement, Analysis, Improvement, Control)を繰り返すことで、6σのミス発生確率を達成する
        • 目的
          • 企業活動で発生するミスの確率を100万分の3.4以下にすることで、顧客満足度を向上し、よりよく、より早く、よりローコストを実現するとともに、競争優位獲得のための企業文化を構築
        • 方法
          • MAICまたはDMAICと呼ばれるシックスシグマ達成プロセスを繰り返し、6σのミス発生率を達成する
        • 効果
          • 全社最適化の発想により、事業目標を論理的にブレークダウンして実行する枠組みを持つ
      • T: IDEAL
        • 継続的・組織的なソフトウェアプロセス改善のライフサイクルモデル
        • 多人数かつ多様な役割を持つステークホルダーが係る複雑なソフトウェアプロセス改善のための、具体的で段階的な指針を与える参照モデル
        • 目的
          • 新しい開発技術、プロセス、技法の導入といったプロセス改善を効率的に実施するための、体系的なフレームワークを提供
        • 方法
          • Initiating
            • 現在の開発スタイルを変えるべき理由を示す
            • 何を対象に改善するか決定
            • 改善活動のスポンサーを確保し、人材などの改善活動のインフラを手配する
          • Diagnosing
            • 現在の状態と目標の状態のギャップ分析
              • CMMIのモデルを参考にする
            • 分析結果から、目標達成に向けて取り組むべき作業項目を示す
          • Establishing
            • 作業項目の優先順位を決め、その実施方法を検討し、詳細な作業計画を検討
          • Acting
            • 具体的な改善案を提案し、まずパイロット環境で試行
              • この結果から改善案を改良し、実環境に適用
          • Learning
            • 改善結果を分析して評価し、今後実施すべき作業項目を整理する
        • 効果
          • PDCAに比べて手順が詳細に示されているため、プロセス改善を進めるうえでのロードマップが得られる
          • プロセス改善を計画する際のフレームワークとして利用できる
      • T: PSP(Personal Software Process), TSP(Team Software Process)
        • 目的
          • 技術者個人、およびチームのQCDにかかわる見積もり精度、生産性、成果物の質を向上
        • 方法
          • PSPに従い、各技術者が、開発規模、工数、技法、検出障害数などを自分自身で見積もる
            • 完了後に見積もりと実績を比較して、自己改善を図る
          • TSPで述べられているチームにおける各自の役割を理解してチームでプロジェクトを実施
        • 効果
          • PSPによって個人の能力向上を追求する技術者が自己改善できる
          • 生産性および品質が向上し、技術者の式が向上するなどの効果
          • TSPによって、チーム開発経験のない技術者に、ポイントを知らせる
        • 留意点
          • データ収集時間
          • 収集データの扱い
      • T: 企業などで考案された改善技法
        • ソフトウェアプロセス改善は当初、QCサークルの適用やTQC、TQMなどの品質管理手法をそのまま取り込み、問題解決型のアプローチで改善するのが主流だったが、その後ソフトウェアプロセス評価モデルによる評価結果を活用した改善にシフトした
  • KA: 検査のマネジメント
    • 検査活動の主眼は、製品を顧客に提供してよいかどうかの合否判定にある
    • 検査部門、または品質保証部門と呼ばれる組織での実施が多い
    • 顧客の立場に立ち客観的な視点で検査を行う必要がある
    • 開発の途中段階から品質把握に努め、適宜、開発部門に品質向上策を推進させる必要がある
      • 品質上の問題を後工程に持ち越さないための工夫が必要
    • 検査計画
      • 方針、体制、方法、検査環境および日程などの基本的な計画を明確にし、検査計画書を作成する
        • ドキュメントの検査や製品の検査内容を盛り込む
        • 過去の検査実績を十分把握して計画に反映する
      • 関係部署とのレビューを行いステークホルダーに事前に明示
      • 計画との照合、フィードバック
    • ドキュメントの検査
      • レビュー結果が設計書に確実に反映されていることの確認も必要
      • ユーザマニュアルは、設計書と矛盾がないか、ユーザが理解しやすく読みやすい文章になっているか検査
    • 中間品質監査
      • 各開発工程の完了時に、次工程に向けてドキュメントなどの中間成果物や製品の品質が確保されているかの確認のために各工程の品質把握をする
      • ドキュメントレビューの結果評価による設計工程完了監査、テストでの摘出障害件数や摘出傾向の妥当性評価によるテスト工程完了監査
    • 製品検査
      • 検査部門自らが、テスト項目の設計、テストツール、テストプログラム、テストデータなどのテストジョブの作成、テスト環境の構築を行い、製品検査を実施する
      • ユーザの視点で、ユーザが製品に仕様する環境と同等の環境において実際に製品を動作させ、検証や妥当性確認を行う
      • 開発部門のテスト結果も確認して、最終的な合否を判定
    • 出荷後の活動
      • 合格と判断して出荷した製品品質に対して責任を持つ
      • 問題が生じた場合、同様の問題を起こさないよう、開発プロセスや自らの検査プロセスへフィードバックする
      • 製品品質の責任部署として、出荷後問題のとりまとめや対応を行う場合もある
  • KA: 監査のマネジメント
    • 監査: 管理対象となる活動が、組織によって選択された基準をどの程度遵守しているかを、収集した証拠をもとに、客観的、体系的に評価する活動
    • 監査の基準の前提として、その組織ですでに確立している組織規範を用いることもあれば、将来に向けて確立と定着を図る目的で、品質マネジメント規格などをもとに新しく定めた組織規範を用いる場合もある
    • 組織方針、品質規格、規準などを明示的に文書化したものを用いるのが一般的だが、多くはその組織がこれまで培ってきた知識、経験をもとにした「あるべき姿」を整理した「組織固有の考え方」を含んでいる
    • 目的
      • 監査活動による組織プロセスの改善
      • 組織内での適切な組織規範の遵守を担保することによる信頼の付与
      • プロセス遵守状況の経営者によるレビューの実施
    • 一般的な活動サイクル
      • 監査計画の立案、監査の実施、監査の記録、監査のモニタリングとレビュー
    • T: 購買先プロセス監査
      • 購入者が購買先に対して、作業プロセスが適正なものか、標準に対する遵守状況はどの程度かを確認し、必要に応じて作業プロセスの是正および改善勧告を行うこと
      • 第二者監査
    • T: ソフトウェア開発における監査
      • プロセスに焦点を当てて実施するプロセス監査および製品に焦点を当てて実施するプロダクト監査
  • KA: 教育および育成のマネジメント
    • 人材育成計画の立案と、それに従った教育および育成カリキュラムの整備、各個人の専門性の育成を管理するキャリア管理に分かれ、企業全体として取り組むべきマネジメント
    • 人材に必要なスキルおよび知識
      • ITスキル
        • スキルの見える化 → 目標が明確化、人事考課や報酬制度と結びつければ動機付け、個人としても主体的にスキルやキャリアを伸ばすためのツールとなる
      • ソフトウェア品質管理、品質保証の知識およびスキル
        • 特にソフトウェアの品質保証、品質管理に携わる人材は、企業文化の継承者の側面があることに注意が必要
        • 各企業でキャリアパスを独自に整備する必要
        • 人材情報システムでキャリア情報やスキル情報の管理・活用が求められる
    • S-KA: スキル標準
    • S-KA: 開発現場における教育および育成のマネジメント
      • チームビルディングについて
      • キャリア開発計画: 目標となる職務を目指したキャリアパスにそって、経験すべき職務や開発すべき能力をまとめた計画
      • キャリアは個人の生涯にわたって継続するもので、その人の仕事に対する自己イメージを反映したものであり、個人の人間的成長や自己実現の軌跡でもある
        • 職務経歴の中で、経験すべき職務、開発すべき能力を自律的に計画して、職務移動の節目にキャリアを意識しながら職務を選択することが個人に求められる
      • 目的
        • 仕事に意欲を持って働き、個人およびチームの職務能力を向上する
      • 方法
        • キャリア開発計画では、目標となる職務を設定して、それを実現するための計画を立案する
        • 品質に関する向上意欲を高めるための動機付け
          • 具体例
            • 高品質な製品およびサービスはコストカットでき利益を生み、顧客の信頼も得られ、経営的に貢献度が高いことを伝える
            • 障害を隠蔽せずに報告することを妨げない組織文化を作る
            • 品質目標達成の表彰制度などを設ける
        • チームビルディングを進めるうえで、たとえば、アジャイル開発で実施されているスプリントの振り返りは成長の機会となり、チーム学習やチーム改善の活動となる
      • 効果
        • 人的資源のパフォーマンス向上
      • 留意点
  • KA: 法的権利および法的責任のマネジメント

プロジェクトレベル(共通)のsoftware_quality_management

  • KA: 意思決定のマネジメント
    • ビジネス上の判断もできる必要
  • KA: 調達のマネジメント
    • QCDを満足させるために必要となる既製の製品やサービス、技術者などの人的資源を外部から調達し、そのコスト、品質をマネジメントすること
    • 背景: 市場や顧客の要請
    • S-KA: 請負契約による外部委託
      • 方法
        • 委託先のソフトウェア開発プロセスの確認
        • 委託先への要求仕様の提示
        • 委託先が海外企業である場合
  • KA: リスクマネジメント
    • 定義
      • リスクについて、組織を指揮統制するための調整された活動
      • 技術、コストまたはスケジュールに関する潜在的危険度を含んだプロジェクトの対象領域の管理
    • リスクの定義
      • 目的に対する不確かさの影響
      • 起こり得る事象、結果、またはこれらの組み合わせについて述べることで、その特徴を記述する
      • ある事象(周辺状況の変化も含む)の結果とその発生の起こりやすさとの組み合わせで表現
      • 発生が不確実な事象または状態であり、もし発生した場合、1つ以上のプロジェクト目標にプラスまたはマイナスの影響を及ぼすもの
      • 危害の発生確率およびその危害の度合の組み合わせ
    • 継続的にリスクを識別する技法が必要
    • リスクの発生可能性や発生後の影響を考慮して優先度の決定が必要
    • ステークホルダーの参画方法やリスクを判断する規準などを予め明らかにする必要
      • ↑ 立場によって捉えるべきリスクが異なるため
    • S-KA: リスクマネジメントプロセス
      • 定義
        • 方針、手順および方策を、コミュニケーションおよび協議、状況の確定、ならびにリスクのアセスメント、対応、モニタリング、レビュー、記録作成および報告の活動に体系的に適用すること
        • リスクを継続的に識別子、分析し、取り扱い、監視することを目的とする
      • リスクマネジメントシステム: リスクマネジメントプロセスそのものを維持する枠組みと、実際のリスク分析を行うリスクマネジメントプロセスの実施に分けられる
      • 目的
        • プロジェクト成功の可能性を高めるために、リスクの発生確率と影響度を減少させる
      • 方法
        • アクティビティ
          • リスクマネジメントの計画および実行
          • プロジェクトリスク台帳の管理
          • リスク分析の実施
          • リスク監視の実施
          • リスク対応の実施
          • リスクマネジメントプロセスの評価
        • これらのアクティビティを実際に運用するために必要となる計画書やリスク台帳、および運用主体となる組織などからなるリスクマネジメントシステムを整備する
      • 効果
        • 組織の事情に応じた、動的で、繰り返し行われ、変化に対応できるリスクマネジメントができる
      • 留意点
        • リスクマネジメントは、組織の主要な活動およびプロセスから切離された単独の活動ではなく、適用する組織の既存のプロセスを考慮しながら適用すると〇
    • S-KA: リスク識別および特定
      • 目的
        • 対象となるシステムやプロジェクトのリスクをもれなく識別する
      • 方法
        • データを収集し、当該システムやプロジェクトに関する専門家の意見を考慮しリスクをもれなく識別する
        • データ収集方法
          • チェックリスト
          • ブレーンストーミング
          • ブレーンライティング
          • 実務家や専門家へのインタビュー
          • 根本原因分析
          • 前提条件と制約条件の分析
          • SWOT分析
          • 文書分析
          • 特定の分野での技法
            • FMEA(Failure Mode and Effects Analysis)法
            • FTA(Fault Tree Analysis)法
            • HAZOP(Hazard and Operability Studies)法
            • AFD(Anticipatory Failure Determination)法
            • HHM(Hierarchical Holographic Modeling)法
        • 上の技法と併せてリスク区分を用いる
          • 区分により、発見と識別の漏れがないことを期待できる
          • 内的/外的などの区分は最も簡単なもの
          • PMBOKでは、RBS(Risk Breakdown Structure)を例示している
      • 効果
        • リスクをもれなく識別
      • 留意点
        • 対象とする分野に合わせた最適な技法を組み合わせるのが〇
        • ステークホルダーの多様な知識や経験を持ちより、漏れを極力なくす
        • 外部環境の変化に応じてリスクが有効なのか、新たなリスクが識別されないかなど考慮して更新する
    • S-KA: リスク分析と算定
      • 発生原因であるリスク因子や、因子とその結果における因果関係を分析し、リスクの発生度合いや影響度合いを明らかにすること
      • 定性的な分析と定量的な分析
        • 定性的 → リスク対応への優先度設定
        • 定量的 → 影響を具体的な数値に
      • 目的
        • 識別したリスクの発生の確率や、それが与える影響を明らかにする
      • 方法
        • 定性的リスク分析では、リスクの発生確率と影響度からなるマトリクスに、識別したリスクを記入し評価することにより、リスク対応への優先順位を決定する
        • 定量的なリスク分析では、リスクの発生する確率分布にしたがってシミュレーションを実施し、decision_treeやリスクグラフを用いることでコストやスケジュールに対する影響を数値化する
          • 感度分析、インフルエンスダイアグラムなどの方法もある
        • リスク分析時にリスクの影響度を明らかにする技法としては、リスクマトリクス法やR-Map(Risk-Map)法などの技法やモンテカルロ法を用いたシミュレーション技法がある
      • 効果
        • 最適なリスク対応の戦略および方法に関する意思決定ができる
      • 留意点
        • すべてのリスクを定性的な尺度、定量的な尺度の一方で一律に評価できない
          • ステークホルダーは、各リスクの定性的な尺度と定量的な尺度のどちらを用いれば効果的に評価できるのか検討が必要
        • リスク識別と同じく、ステークホルダーの知見や経験を用いる必要がある
          • リスク分析によりリスク対応の優先順位や対処方法が決まってくることから、関係者間におけるリスク情報の共有に留意
    • S-KA: リスク評価および対応
      • リスク評価
      • リスク対応
        • 軽減、排除、予防、低減
      • 目的
        • リスク分析の成果に基づき、どのリスクへの対応が必要か、対応の優先順位をどうするかについて意思決定を支援
      • 方法
        • 代替案分析: 作業を完成する複数の方法を比較し、最適な方法を決める
        • 費用便益分析
      • 効果
        • リスクに対し、優先順位に基づいた対応を行える
      • 留意点
        • 優先順位が高いリスクについては、すべてに対応
        • 著しい困難が伴う、または費用がかかる場合は、すぐに対応しようとせず、定期的に外套のリスクが解消していないか、あるいは新たな対応が行えるようになっているか監視する
  • KA: 構成管理
    • ライフサイクルを通じてソフトウェア作業成果物(ドキュメントやソースコードなど)、およびそれ以外のシステムを構成する要素(OSやフレームワーク、DB、開発環境、ハードウェアなど)を識別し、その組み合わせの結果と変化を管理し、特定の時点における構成の再現および追跡を可能とすること
    • システムやソフトウェアライフサイクルの全般にわたり、構成要素の機能や特性を特定可能にし、それらに対する変更を管理および検証し、その状況を記録する活動
    • → 要素間やその変化が追跡可能になる
    • 目的に対して正しいソフトウェア成果物の構成が得られるため、取り出しミスや認識の不一致など品質に負の影響を与えかねない損失や手戻りを防止できる
    • 活動内容
      • 構成要素の識別とベースラインの設定
      • 構成を制御するための変更管理
      • 構成要素への変更履歴を管理するバージョン管理
      • 品目の完全性、一貫性および正確性を保証するための構成評価
      • 複数の構成要素間の関係を管理するinterface管理
      • 正しい構成要素の組み合わせを配布するためのビルド・リリース管理
    • 広義では、変更管理プロセスも構成管理プロセスに含まれる
    • 変更管理プロセスとバージョン管理を統一する方式が〇
      • ソースコードの追加、変更、削除の要因となるアクティビティとソースコードの変更(セット)を常に追跡可能にすることが重要
      • バグトラッキングツールやタスク管理ツールとバージョン管理ツールとを密に連携が必要
    • ツールを用いて変更管理プロセスとバージョン管理を統一する方式を取り入れることで、ソースコードに触れられないステークホルダーでも、バグやタスクの情報からソフトウェア開発の進捗状況や品質情報を得られるようになる
    • 識別粒度の違いも吸収できる
    • S-KA: 変更管理
      • 構成管理下の構成要素を変更するためのアクティビティ
      • 目的
        • 提案された変更要求を深く吟味し、確実にシステムへ反映する
      • 方法
        • 変更管理の一般的な管理手順
          • 変更要求を受け取り、評価を実施
          • 変更管理委員会が変更を行うことを決定し、リソースを確保し、修正担当者に割り当て
          • 修正担当者が変更を実施し、検証する
          • 検証が終わり、修正済みの作業成果物をリリース
        • 開発の責任者は、上記のような変更管理プロセスを定義し、変更管理ポリシーを定義する
          • 開発者全員に周知徹底
        • 変更管理委員会は、構成管理委員会またはCCB(Change Control Board)と呼ばれ、提案された変更要求と新しく提案された機能のどれを受け入れるかを決定する人々の集合
          • 実際には設計部署の管理者、リーダークラスで構成されることが多い
        • CCBは一度決定したベースラインの成果物に対して、変更を受け入れることの便益と影響を精査する
          • 便益: 顧客満足度の向上や競争力の優位
          • 影響: コスト、リリースの遅れ、品質劣化
      • 効果
        • 決められたプロセスを経ることで、変更要求の内容や影響をステークホルダー間で共有でき、提案された変更要求を正しく確実に反映できる
      • 留意点
        • 影響分析が重要
          • 知見のある開発者に影響分析を指示
          • 要領
            • 変更要求と既存の要求との矛盾
            • 変更を行うことのリスク、技術的な懸念、副作用、スキル面の妥当性
            • 変更による品質要求への悪影響
            • 現在進行中のプロジェクト計画に与える影響、開発環境に与える影響
            • 既存資産(設計、ソース、テストケースなど)に与える影響
        • 影響分析の結果を参考に、変更依頼の承認/却下の判断
    • S-KA: バージョン管理
      • ベースラインからの変更内容を把握可能にする管理
        • ライフサイクルにおけるソフトウェア要素の変更履歴を管理し、任意の変更が反映されたバージョンを一意に識別
      • 目的
        • 特定の時点でのソフトウェアを復元できるように、ソフトウェアのバージョンを適切に管理する
      • 方法
        • バージョン管理ツールの使用
      • 効果
        • バージョン管理を適切に行うことで、必要なときに必要なバージョンを復元できる
          • 特に、障害や故障時における現象を再現し、原因調査などを行う際に重要
      • 留意点
        • 各粒度でバージョン管理が必要
          • 構成管理におけるほかのアクティビティと密接な関係
        • ブランチの管理が必要な場合もある
    • S-KA: 不具合管理
      • 目的
        • 不具合によって発生する構成要素への変更と併せて、不具合の解決がなされたことを管理
        • スムーズな不具合解決を目指す
      • 方法
        • 一般的な手順
          • 不具合が発見された場合、報告された内容に基づき、その現象の再現と原因の調査を実施する
            • 現象の再現は、不具合が発見されたソフトウェアのバージョンにて、現象を再現する環境を構築し調査を実施する
          • 調査の結果、構成要素への変更が必要と判断された場合は、変更作業を行う
            • 変更管理やバージョン管理も併せて実施
        • 個々の不具合の作業ステータスの管理が必要
          • 発見から対処完了、優先度など
      • 効果
        • 例えばテスト期間中の不具合解決の促進が可能
        • 不具合管理を通じて収集した不具合情報を分析することで、プロセスや製品の改善すべき情報を得られる
      • 留意点
        • 不具合が多く発生する期間では、情報の収集について工夫が必要
          • 例えば構成管理と結びつけた厳格な不具合管理など
    • S-KA: トレーサビリティ管理
      • 目的
        • 主に変更要求が発生した際の影響調査、および変更対象の特定を容易にするため、要求事項と、プログラムやモジュールなどのソフトウェア品目を追跡可能な状態に管理する
      • 方法
        • 管理する側の視点と管理する情報を考慮することで、いくつかの異なるアプローチ
          • 要求のトレーサビリティ管理
            • 獲得、分析、仕様化した要求の構造がどのように設計、構築に展開されていくかを管理する
          • 成果物のトレーサビリティ管理
            • 要求定義、方式設計、詳細設計、構築、テストの各アクティビティにおける成果物がどのようにつながっているかを管理する
          • 製品のトレーサビリティ管理
            • ソフトウェアの構成要素がソフトウェア製品にどのように組み込まれているかを管理する
      • 効果
        • いずれのアプローチも変更要求が発生した際に効力を発揮
          • 例えば、変更要求が提案された場合の影響分析において、その変更がどの機能、ソフトウェア品目に影響するのか、テストがどれくらい必要か、などについて容易に調査可能になる
      • 留意点
        • いずれのアプローチも、ソフトウェア・トレーサビリティをどのように管理するかというテーマに対処するもの
        • 開発現場においては、現状の課題に対応したトレーサビリティ管理が求められる
  • KA: プロジェクトマネジメント
    • 品質やコスト、納期などの制約の下で個々のプロジェクトの目標を達成するための計画立案や実行管理を行うこと
    • ますます複雑かつ大規模化している情報システムの分野でも、あらゆるシステムの構築にプロジェクトマネジメントが欠かせない
    • S-KA: PMBOK(プロジェクトマネジメント知識体系)
      • よい実務慣行と一般的に認められているプロジェクトマネジメントの実施方法の集大成
      • 10の知識エリア
        • プロジェクト統合マネジメント
        • プロジェクトスコープマネジメント
        • プロジェクトスケジュールマネジメント
        • プロジェクトコストマネジメント
        • プロジェクト品質マネジメント
        • プロジェクト資源マネジメント
        • プロジェクトコミュニケーションマネジメント
        • プロジェクトリスクマネジメント
        • プロジェクト調達マネジメント
        • プロジェクトステークホルダーマネジメント
      • PDCAサイクルをプロジェクトマネジメントプロセスの基本としている
      • 各プロセスはインプット、ツールと技法、アウトプットの3つで構成されている
      • 目的
        • プロジェクトマネジメントに関する優れた実務慣行などを特定する
        • プロジェクトマネジメントの標準用語集とし、遂行上で関係者間の共通の理解の獲得に役立てる
      • 方法
        • 個々の実情に併せて以下の面からPMBOKの内容を適宜活用する
          • 自プロジェクトでマネジメントすべき側面とその実施内容及び作業項目を参考にする
          • 各プロセスの入出力項目を参考にする
          • 各プロセスで必要となるツールや技法などは、PMBOKで推奨しているものから選んで適用する 0 プロジェクトでのマネジメント実施経過や結果を逐次記録し、その分析結果を今後の組織のプロジェクトマネジメントに向けた知識として蓄積
      • 効果
        • 漏れのない計画を立ててこれに沿って管理を行うことで、適切で効率的なプロジェクトマネジメントができる
        • プロジェクトメンバー間はもとより、ユーザや関連組織とのコミュニケーションを円滑にできる
        • PMBOKという業界標準の知識体系に基づいてプロジェクトマネジメントが行える専門職の育成がでk理宇
      • 留意点
        • 明確なゴールの定義が難しい価値創造型プロジェクトにおいては、明確な計画策定やリスク洗い出しが困難となるため、状況に応じた高度な対応が必要になる
        • 理想的なスキルセット
          • テクニカル・プロジェクトマネジメント
          • リーダーシップ
          • 戦略的およびビジネスのマネジメント
    • S-KA: プロジェクトマネジメントに関する規格

プロジェクトレベル(個別)のsoftware_quality_management

  • KA: 品質計画のマネジメント
    • 効果的かつ適切な品質計画のマネジメント
    • 以下の事項を実施
      • 1.製品およびサービスに関する要求事項の明確化
      • 2.プロセス、製品およびサービスの合否判定に関する基準の設定
      • 3.製品およびサービスの要求事項への適合を達成するために必要な資源の明確化
      • 4.2の基準に従ったプロセスの管理の実施
      • 5.次の目的のために必要な程度の、文書化した情報の明確化、維持および保持
        • プロセスが計画通りに実施されたという確信を持つ
        • 製品およびサービスの要求事項への適合を実証
    • 品質計画書: 特定の製品やプロジェクト、契約に適用される品質マネジメントシステムの、プロセスおよび資源を規定する文書
    • コスト面から、早い段階でレビューやテストによって設計やソースコードを確認するように計画する
    • 要求品質を確保するために工数をかけ、あるいはスキルのある人を入れるなどして必要十分なコストをかける計画にすることも必要
    • 競争力のある目標を設定するためには、ベンチマーキングにより世の中の水準や別組織との比較をすることも必要
    • T: 品質計画書
      • プロセス、製品、プロジェクトまたは契約の要求事項を、製品実現を支援する作業方法および慣行に関連付ける手段
      • プロジェクト計画書の一部、レビュー計画書、テスト計画書など複数の計画書で構成されることが多い
      • 目的
        • 要求される品質の目標を設定し、それを達成するためのプロセスを定めることで、顧客満足の向上を目指す
        • 文書化することで、計画を関係者と合意
      • 方法
        • 製品に対する品質目標と要求事項
        • プロジェクトで必要とするプロセスや資源
          • アーキテクチャ、基準や規約、資源の明確化
          • 開発プロセスには、監視および測定する品質指標など、品質管理の対象が何であり、目標の達成状況をどのように評価するかというプロセスを含めると〇
        • 品質マネジメントの計画
          • 目標達成のためのレビュー/テスト/検査/監査 計画や、それらの合否判定基準を含める
          • 必要なコストとのバランスを考慮して、適切な品質目標を設定
        • 必要な記録
          • 満たしていることの実証のための必要な記録の明確化
        • 潜在的な品質不良のリスクと緩和策
          • 緩和できる程度もまた品質の一種
      • 効果
        • 品質目標を明確にして、その管理対象や達成状況の評価プロセスを定めることで、提供するソフトウェアの品質を保証し、さらにプロセスの改善に結びつけられる
        • 文書として明示することで、関係者とプロセスや目標を共有できる
      • 留意点
        • 用いるレビュー技法やテストツール、基準とするメトリクス、進捗や実行結果の管理プロセスも計画に含めると、品質目標の達成度評価やプロセスの改善を実現しやすくなる
        • 品質計画書は組織によって呼称や範囲が様々
    • T: 費用便益分析
      • 目的
        • 有形/無形の費用と便益を分析し、いずれかの考慮に偏らない、トレードオフを考慮した品質計画策定を支援できる
      • 方法
        • プロジェクトとそれらに関連するすべての費用と便益を計算して、プロジェクトの成果物を生み出す費用がプロジェクトの実行によって生み出される効果より小さいか大きいかで、プロジェクトを評価
        • 効果-費用の値が大きいプロジェクトを優先
      • 効果
        • 定量的把握
        • プロジェクト間比較
      • 留意点
        • 分析内容の確認が必要
          • 前提条件、データ、対象外の要因、技術進歩によるシステムの価値の変化
        • ほかの側面もあるので、ほかの評価技法などと組み合わせて総合的に判断が〇
    • T: ベンチマーキング
      • 種類
        • 自組織内を比較対象とするインターナルベンチマーキング
        • 競合組織を比較対象とするコンペティティブベンチマーキング
        • 業種に関係なく類似の組織機能を比較対象とするファンクショナルベンチマーキング
        • 業種に関係なくビジネスプロセスを比較対象とするプロセスベンチマーキング
      • 目的
        • ベストプラクティスと自らの業務を比較して、結果を導入することで、自組織の業務を改善・改革
      • 方法
        • ベンチマーキングを行うプロセスの決定
        • 信頼のおける比較対象とその情報源を選択
        • 比較対象と自組織のプロセスパフォーマンスを比較し、ギャップを分析して、改善のための検討を行い、指標を決定する
        • 設定した指標をもとに目標値を定めて、自組織の改善計画を立案し実行する
      • 効果
        • ベストプラクティスに基づいて自組織の目標を設定することで、業務改善・改革につながる
        • プロセスパフォーマンスが向上することで、収益などの経営指標の改善が期待できる
      • 留意点
        • 単なる比較分析はベンチマーキングではない
        • ベストプラクティスと自組織の実施方法とのギャップを分析し、プロセスを見直し、その効果を確認して改善や革新に結びつけるまでがベンチマーキング(行動を伴う必要)
  • KA: 要求分析のマネジメント
    • 要求分析の計画
      • 要求抽出
        • 発生源
        • 見落としがないように適切な抽出方法を決定し、要求を文書化し、発生源への再確認などを通じて間違いや漏れがないように留意する
      • 要求分析
        • 異なるステークホルダーから抽出された要求間の競合を解決し、システムの境界、システムとハードウェアや人などとのinterfaceを定め、システム要求からソフトウェア要求へと詳細化すること
        • 要求間の優先順位を明確化し、ユーザと合意する
        • 優先順位付け
          • 企業目標やビジネス戦略に合わせたKPIやBSCを用いることもある
        • 予算や期間の制約によっては実現しないと決める要求もあり、要求のマネジメントを始める時期でもある
      • 要求仕様化
        • ソフトウェア要求を抽出および分析した結果をステークホルダーに伝えて共有するとともに、以降の要求の妥当性確認と評価や要求事項のマネジメントのために文書化すること
        • 要求を文書にすることは、要求分析を成功させるうえで基本的な前提条件であり、文書の品質はプロダクトの品質に大きく影響する
    • 要求の妥当性確認と評価
      • 妥当性確認
        • 仕様書として文書化された要求が、もともとの要求の発生源としてのステークホルダーなどが真に求めるシステムを定義していることを確認すること
        • レビューやプロトタイピング、受入テストの検討などを通じて行われ、要求文書の誤りや間違った仮定などを見出す
      • 評価
        • 要求の明確さとリスクの抽出状況、要求間の整合性、記述の一貫性、明瞭性などを確認すること
        • レビューをなどを通じて実施(妥当性確認と同じく)
      • 要求分析の初期段階でテスト計画とテストケースを作成し、妥当性を確認することが有効
        • ↑ テストは遅い段階のアクティビティになりがちなため
  • KA: 設計のマネジメント
    • 設計: 指定された要求を満足するために、アーキテクチャ、システム要素、interface、データを定義するプロセス
    • ソフトウェア設計のアクティビティを規定した計画を定め、要求されている品質特性と顧客ニーズを満たす設計結果を得るための設計方針を決定し、設計結果が要求仕様および品質を満足しているか評価すること
    • 設計の計画
      • 設計のプロセスや方針、用いる技法、評価方法の決定
      • 開発プロセスと保守プロセスの局面で発生する
      • 以下について具体的な内容を策定
        • 品質計画書の内容に従って、設計における品質の作りこみを可能とする具体的な設計プロセスを規定し、各プロセスに対する入出力成果物の規定や成果物の記述方法を定める
        • 設計方針と設計技法の決定、設計技法の選択に対する具体的な実施方法やトレードオフとなった場合の判断基準の規定
        • 設計の評価に関して、設計成果物のレビュー、テスト、検査の実施時期や実施方法について計画
        • 設計の計画をタテル時点では、リスクの評価方法を規定したうえで、許容可能なリスクを選択・文書化し、ステークホルダー間で合意
      • 保守プロセスでの設計では、以下に留意し、上記の設計計画の各内容に反映する
        • テスト工程に向け、修正部分と非修正部分に着目し、それぞれ区別/結合して、テストやテスト結果を評価するための基準を設定
        • 新しい要求事項や修正された要求事項が、既存の要求に与える影響を評価
        • 品質改善のための重要の活動としてのリファクタリングなどの設計や実装の見直しを、いつどのように実施して結果をどう評価するかも設計計画の中で明確にする
    • 設計方針の決定
      • 設計上の技法や方法の選択を根本的に左右する基本戦略を、関係者全員が共有できるように定めておくこと
      • ソフトウェア構造に一貫性を持たせる一般的な設計方針
        • 分割と統治、段階的詳細化など
      • 設計技法の選択における考慮点
        • ソフトウェア特性(リアルタイム性やuiなど)
        • 品質特性
        • プロジェクト目標、品質目標との整合
        • 設計方針との整合
        • 設計技法の完成度、普及度
        • 開発環境の整備状況
        • 要員の確保と要員教育の教材の充実度
      • 技法
    • 設計の評価
      • 設計成果物のレビュー、テストを実施し、設計結果が要求仕様を正しく実現しているか、求められている品質目標を達成しているか評価すること
      • 評価方法は、選択した設計技法や設計成果物の記法により決定
      • 評価基準の考慮点
        • 要求事項への追跡可能性
        • 外部一貫性
        • 内部一貫性
        • 利用した設計方法や作業標準の適切さ
        • 実現可能性
      • 品質目標の達成度合いは、策定した品質評価計画により評価
  • KA: 実装のマネジメント
    • 実装の計画
      • 品質要求を含む各種の要求を実現するために計画を作成すること
      • 選択する実装方法と品質要求を含む各種要求の組み合わせによって、設定すべきメトリクスや、実装前提条件、実装作業の範囲や実施順序を決定する
      • 実装計画では、実装方法に従い、WBS、品質を含むメトリクスの目標値と計画値、コンポーネントを作成して統合する順序、品質管理手順、その他を定める
    • 実装方針の決定
      • 実装方針の決定とは、実装に際して、品質要求を含む各種の要求を満たすために必要な実装ルールを設定すること
      • 考慮項目
        • 採用する言語と再利用部品の利用
          • 言語の選択は重要
            • 言語を効果的に活用するにはトレーニングとスキルが必要
          • WindowsUnixのテキストベースの構成ファイルや、プログラム・ジェネレータのメニュー式選択リストなどの利用を検討
          • 特定アプリケーション向け再利用部品の統合セットや、アプリケーションを作り上げるための各種設定について検討する
        • コーディング規約とガイド
          • 各条件から、プロジェクトに最適な規約とガイドを設定
        • 標準の利用
          • 外部標準(OMG(Object Management Group)やISOのような国際組織が規定)のソフトウェアおよびハードウェアのinterface仕様、実装言語、実装ツール、interfaceなどの利用を検討する
          • 併せて内部標準(企業単位、部門単位、プロジェクト単位などの標準)の利用を検討
          • 標準により、プロジェクト運営の負荷軽減
            • 検証の組込などへの効果も期待できる
    • 実装の評価
      • 実装成果物のレビュー、テストを実施し、実装結果が要求仕様を正しく実現しているか、求められている品質目標を達成しているか評価すること
      • 基準
        • システム要求事項とシステム設計への追跡可能性
        • システム要求事項との外部一貫性
        • 内部一貫性
        • テスト可能性
        • ソフトウェア設計の実現可能性
        • 運用と保守の実現可能性
      • ウォークスルーによるコードレビューが代表的
        • 要求仕様が正しくコーディングされていることを評価
        • 規約の遵守性も評価
      • テストでは、ホワイトボックステストによるモジュールテストが代表的で、命令や分岐が正しく動作することを評価する
        • 命令や分岐の網羅性が評価基準
      • モジュールを統合してテストするときは、仕様に基づくテスト(ブラックボックステストなど)により、統合したモジュールが要求仕様どおり動作することを評価する
  • KA: レビューのマネジメント
    • レビュー: ソフトウェア開発工程全般における評価と確認作業
      • 関係者が参加し多角的に検討することで、論理の客観性と透明性、構造の妥当性、フィールドへの適応性などを評価し確認する
    • デザインレビュー: 設計審査。品質保証のための合否判定の1手段
    • レビュー計画
      • 開催時期、対象成果物、レビューア、観点、適用する方法とリーディング技法、完了判断基準などのレビュー計画を、プロジェクト計画策定時に明確にする
      • 対象はソフトウェアに関する直接的な成果物だけでなく、設計方針やテスト戦略などの成果物も含める
      • 方法は、最も形式的で公式なインスペクションから、その逆のアドホックレビューまでさまざま
        • 形式的なら、側面や観点に基づいた障害検出の属人性が低減されて管理しやすくなるが、手間やリソースがかかるので、目的に応じて選択する
    • レビュー実施
      • 対象成果物が、当該プロセスのインプットの要求事項を満たすことを確認する
        • 前のプロセ腕示された要求を網羅した記述内容であることを確認
      • 曖昧性がないこと、内容や構造に矛盾、誤り、漏れがないことも確認
      • 人や組織ではなく成果物をレビューすることや、問題を指摘事項として挙げるものの解決はしなくてもよい場合があることなどを、ガイドラインとして作成しておく
    • レビューの記録
      • レビュー報告書の発行
      • → 品質記録としての意味
        • 品質保証活動の一環としてのレビューが確実に実施されたことの証拠となる
        • この記録をもとに追跡して完結したことをフォローする
      • 記録は、内容と手順をプロジェクト計画策定時に立案し、プロジェクトメンバに徹底しておく
    • レビュー実施状況のマネジメント
      • プロジェクト実行段階において、レビューが計画通りに行われていることを追跡し、指摘結果の反映確認を確実に行う
  • KA: テストのマネジメント
    • 対象のプロダクトやサービスが、プロジェクトで定義した品質を達成するために実施される、テストの活動のマネジメント
    • テストの実行で、テスト対象がプロジェクトで定義した品質レベルに達しているかを確認する
    • テストの対象に残存する欠陥がテストとデバッグにより除去されることで、テスト対象が持つ品質リスクを下げる
    • テストは、設計とは違う視点から設計を洗練させ、開発プロセス全体の品質向上にも貢献
    • 適切なテストは、十分な品質レベルにあり、残存リスクも許容レベルにあると判断された製品やサービスを市場にリリースするうえで必要であり、そのテストが適切に行われることについてのマネジメントも必要となる
    • テストは欠陥があることは示せるが、欠陥がないことは示せないという限界がある
      • テストの十分制覇、網羅性やテストの実施量、欠陥の傾向やそれらの管理グラフなどから総合的に判断する
      • 品質レベルについても、上記のようなテストに関するメトリクスや残存するプロダクトリスクなど、テストマネジメントの実施の上で得られるすべてのデータを利用して総合的に判断する必要がある
    • テスト活動に関与する組織の在り方も、テストマネジメントの成否を左右する
      • 一般的に、開発組織から独立したテスト組織によってテストを実施するとテストの効果は向上するが、開発スピードを損なうことがある
      • → 独立の度合いは、技術、管理、財務の観点から検討してテスト組織の位置づけを決める必要がある
        • 独立強
          • 技術面では、異なる視点でのテストができるため、効果up
          • 管理面では、テスト組織に出荷権限を与えることで厳格な品質保証活動が可能になる
          • 財務面では、テスト組織でのリソースの融通がしやすくなる
      • テスト組織のメンバは、各テストレベルにおけるテストタイプを考慮し、性能や使用性などのテストのスペシャリストを含めて構成が〇
      • 一般的にアジャイル開発では、開発担当やテスト担当が1つのチームで一体となって開発することが多く、単独のテスト組織は存在しない場合がある
    • テストに関する標準や規格への適合が重要になってきている
    • プロジェクトマネジメントの1要素でもあるので、ステークホルダーとの調整が不可欠
      • 用語の統一も重要
      • → ISTQBが発行しているGlossaryが使える
    • S-KA: テストプロセス
      • テストアクティビティを具体化するときは、ソフトウェア開発ライフサイクルの諸活動やさまざまなステークホルダーの存在を識別したうえで、ソフトウェア開発のプロセスと連携したテストプロセスの形成が必要
      • 目的
        • ソフトウェア開発のプロセスと連携した、効果的なテストプロセスを形成する
      • 方法
        • ソフトウェア開発のプロセスに対応付けたテストのプロセスモデルであるV字モデルやW字モデルを参考にテストプロセスを策定
        • V字モデル
          • ウォーターフォールモデルにおける各工程に対応するテストレベルを示すためのモデル
          • V字の左側を品質を作りこむ過程、右側を品質を確認する工程と呼ぶこともある
        • W字モデル
          • 開発プロセスの早期段階からテストプロセスを開始することを表現するために考案された
          • 開発プロセスのV字とテストプロセスのV字が並行して進む様子
          • 上流工程でテストの計画や設計を行うことで、開発工程の成果物のレビューが行われ、さらにテスト容易性などの観点から評価とフィードバックが行われる
      • 効果
        • ソフトウェア開発プロセスと対応付けたテストプロセスを策定することで、各テスト工程の設計の元になる情報やテスト対象範囲を明らかにできる
        • W字モデルの導入により、上流工程からの品質の作りこみ、開発とテスト準備作業の並行性向上(ひいては短納期開発)、テストエンジニアの知見の活用、テストしやすいソフトウェア開発の促進が期待できる
      • 留意点
        • 開発プロジェクトが採用するプロセスモデルによってテストレベルの数が決まる(固定的ではない)
        • W字モデルにおいて、テストの計画や設計の作業を通じて、上流工程で要求や設計の問題点を検出してフィードバックするには、相応の技術力が必要
          • 経験の浅いテスターが上流工程で単にテストケースを作成するだけではW字モデルの効果は得られない
    • S-KA: テストの構造
      • 目的
        • テストの構造を明確にすることで、テストのマネジメントを容易にする
      • 方法
        • テストレベル
          • 単体テスト
            • モジュールやクラスなど独立してテスト可能な部分のテスト
          • 統合テスト
            • モジュールやクラス間のinterfaceのテスト
          • システムテスト
            • 機能の組み合わせに着目したテスト、パフォーマンスなどの非機能要件に対するテスト、ビジネスプロセス、ユースケースなどに対するテストを実施
          • 受入テスト
            • 顧客やユーザにより、システムの全体や一部、また非機能要件に対するテストを実施
            • UAT, 運用受入テスト、αテスト、ベータテストなど
        • テストタイプ
      • 効果
        • テストの構造を決めることで、対象や範囲を整理して、目的に沿ったテストを設計でき、段階的、体系的にテストを進められる
      • 留意点
        • テストレベルの種類や数は、プロジェクトが採用するプロセスモデルや開発スケジュールなど、そのプロジェクトの特徴に応じて設定する
        • テストタイプは具体的なテストケースを示すものではないので、テストタイプの主旨に沿ってテストの詳細の設計が必要
    • S-KA: テストの計画と遂行
      • 目的
        • プロジェクトにおけるテストの目的やプロセス、ゴールとそれに至る手段、リスク、テスト環境を明確にして実現可能な実施計画を作成し、テストを遂行する
      • 方法
        • 開発プロジェクト発足後、プロジェクト計画策定とほぼ同時期に、開発ライフサイクル全体を包括するものとしてテスト計画を策定する
        • 策定時は、プロジェクト計画で策定された目的、戦略と戦術、スケジュールや耐性、環境、リスクとその対策などを勘案し、最終的に全体計画となるマスターテスト計画書、テストレベルに応じた個別のテスト計画書などに記述する
        • 検討事項
          • テスト全般の内容と工数の見積もり
            • 範囲、内容、方法、体制、要員、スケジュールの定義
            • 工数見積もりは、過去や類似のプロジェクトの実績値を参考にする方法や、作業の実行者やエキスパートによる見積もりをベースにする方法がある
          • テストにかかわるリスク
            • 識別し、予防策、回避策、発生時の対策を決定
            • 適切なテスト技法やテスト対象、優先順位を決定して実施することでプロダクトのリスクに対処
            • リスクベースドテストでリスクの発生を最小限に抑える
            • リソースについてのリスク分析、マネジメントも実施
          • テスト環境
            • テストレベルに応じた機器やソフトウェアの選定と調達
            • 限界値/異常値テストが実施可能なテスト環境
            • 場所や電源など物理的リソースの確保
        • テストの遂行では、計画通りに進捗しているか品質なども含めて計画にフィードバック
          • 状況や結果に関する情報
            • テストの消化状況
            • 障害情報
            • 要求、仕様やコードに対する確認の網羅性
      • 効果
        • 実施すべき作業とスケジュール、ゴールが明確になることでテストを円滑に実施、管理できる
        • テストプロセスの進行状況の把握やテスト終了の判断、品質問題の早期発見ができる
      • 留意点
        • フィードバック要
        • リスクの定期的再評価
        • 必要な情報のみ収集、容易な収集方法
    • S-KA: テストに関する標準
      • 目的
        • 組織、テスト対象、テスト実施形態にかかわらず適用できる規格を用いてテストに関する作業を標準化する
      • 方法
        • テストに関する規格
          • 2013年にISO/IEC/IEEE 29119シリーズの発行が開始されている
          • テストに関する規格以外でもソフトウェアに対する要求事項が規定され、その中にテストへの要求事項が含まれているものもある
        • テスト技術者資格認定
          • ISTQB
            • スキルの度合い
              • Foundation, Advanced, Expert
            • テスト技術分野
              • Core, Agile, Specialist
      • 効果
        • 公的・実質的な規格により作業が一定水準で標準化できる
        • 技術者はグローバルな統一基準にもとづいて段階的にテスト技術を習得でき、開発組織は体系的に技術者を育成できる
      • 留意点
        • 規格の適用にあたっては、開発方法、プロセス、プロジェクトの特性に合わせてテーラリング
        • プロジェクトが準拠する規格によりテストへの要求事項は変わる
        • ISTQBで実施されている試験でも、JSTQBでは実施されていないものがある
  • KA: 品質分析と評価のマネジメント
    • 実行過程、実行結果や成果物に関するデータを収集、分析し評価すること
    • 留意点
      • プロダクト品質とプロセス品質の両面から評価
      • 障害件数のみでなく品質特性やプロセスの特性にも着目し、さまざまな観点で評価
      • データの分析と評価結果の使用方法を明確にする
        • 具体的なアクションやフィードバック、改善に結びつくデータ収集や分析、評価となるようにする
      • 対象範囲を明確にし、偏りや抜けのないデータとする
      • 分析と評価はCh03の技法を使う
      • 定量的に行い客観性を保持
      • 技法や評価観点を使うときは、自環境を考慮してカスタマイズ
        • 技法や観点の背景の理解が必要
    • S-KA: プロダクト品質とプロセス品質の分析と評価
      • 目的
        • プロダクト品質の分析と評価 → ユーザの視点でさまざまな側面から評価する
        • プロセス品質の分析と評価 → 開発プロセスの妥当性と一貫性の確認
  • KA: リリース可否判定
    • リリース: プロセスを次の段階またはプロセスに進めることを認めることを意味する
    • 目的
      • 実施時期に応じた目的
    • 方法
      • 判定責任者を設けて権限を明確にしておく
      • ステークホルダーやその他の関係者を含めた版tネイの体制も明確にする
  • KA: 運用および保守のマネジメント
    • S-KA: ITIL
      • 目的
        • ITサービスの提供と管理のベストプラクティスを提供する
      • 方法
        • ITサービス提供者が、自己のサービス提供と管理の仕組みをITILのベストプラクティスに照らして見直して改善を進める
        • 運用および保守のマネジメントとして、特にサービスの品質に関連の深いマネジメントプラクティス
          • 可用性管理
          • キャパシティとパフォーマンス管理
          • インシデント管理
          • 問題管理
          • リリース管理
          • サービス継続性管理
      • 効果
        • ITサービスを継続的に改善しつつ、効果的かつ効率的に提供できる運用管理を実現できる
      • 留意点
        • 改善のための手段から認証のための手段に転化しないよう、上位管理者のリーダーシップと資源確保に留意する
    • S-KA: SLAとSLM
      • 目的
        • SLAにより、サービスの内容を厳格に定義し、サービスの品質水準をメトリクスと基準値によって明示的、定量的に定義し、あいまいさを排除する
        • SLMを通じて、サービス提供者がSLAを達成する
      • 方法
        • サービス品質のカテゴリごとにメトリクスと基準値を設定して定義し、SLAに組み込む
        • SLMではPDCAサイクルを回す
        • SLMの主要な活動
          • サービスと目標のサービスレベルについて顧客と共通認識を持つ
          • 測定基準の収集、分析、保存、報告を通じて、組織が所定のサービスレベルを満たしていることを確実にする
          • サービスのレビューを実施して、現在の一連のサービスが組織と顧客のニーズを継続的に満たしていることを確認する
          • 所定のサービスレベルとパフォーマンスの比較など、サービスに関する課題を補足して報告する
      • 効果
        • SLAにより契約したサービスの内容と品質水準に関する認識の相違や誤解を防止できる
          • 文書化されていないとき期待水準が拡大してしまうが、これを制御できる
        • SLMによりサービス提供者がSLAを安定的に達成
      • 留意点
        • SLAは単なる運用上の測定基準ではなく、所定の成果に関連が必要
          • 顧客満足度や主要な事業成果などの測定基準をバランスよく組み合わせて実現する
        • SLMでは、SLAに合意したサービスの内容と品質を正しく表す、客観的で自動計測可能なメトリクスと基準値を用いると〇
    • S-KA: サービスマネジメントに関する規格
      • SMS(Service Management System)
      • ITサービスの提供者に対する要求事項の規定
    • S-KA: 保守に関する規格
      • 保守プロセスの実行計画立案、実行とコントロール、レビューと評価、終了に対するガイド
      • 分類
        • 是正保守、予防保守、適応保守、完全化保守

(以下は、業務などで課題を見つけたときに通読するようにし、今は構成・概観だけ確認する。)

Ch03 ソフトウェア品質技術

  • 品質の作りこみや確認のための技術について

工程に共通なソフトウェア品質技術

  • KA: メトリクス
    • S-KA: 測定理論
      • T: 測定に関する用語
      • T: 測定プロセス
      • T: GQM(Foal-Question-Metric)
    • S-KA: プロダクトメトリクス
      • T: 製品品質メトリクス
      • T: 利用時の品質メトリクス
      • T: 複雑殿メトリクス
      • T: LOC(Lines of Code)
      • T: ファンクションポイント
    • S-KA: プロセスメトリクス
  • KA: モデル化の技法
    • S-KA: 離散系のモデル化技法
      • T: UML
      • T: SysML(Systems Modeling Language)
    • S-KA: 連続系のモデル化技法
    • S-KA: DSL
  • KA: 形式手法
    • 数理論理学に基づいて、仕様記述や検証を行うアプローチの総称
    • S-KA: 形式仕様記述の技法
    • S-KA: 形式検証の技法

工程に個別なソフトウェア品質技術

  • KA: 要求分析の技法
    • S-KA: 要求抽出
    • S-KA: 要求分析
      • T: 機能要求分析
      • T: 非機能要求分析
      • T: 品質機能展開
      • T: 要求可変性分析
    • S-KA: 要求仕様化
      • T: ソフトウェア要求仕様
      • T: USDM
    • S-KA: 要求の妥当性確認と評価
  • KA: 設計の技法
  • KA: 実装の技法
  • KA: レビューの技法
    • S-KA: レビュー方法
    • S-KA: 仕様やコードに基づいた技法
    • S-KA: フォールトに基づいた技法
    • S-KA: リーディング技法
  • KA: テストの技法
    • S-KA: テスト設計技法
      • T: 仕様に基づいた技法
      • T: コードに基づいた技法
      • T: 経験と直感に基づいた技法
      • T: フォールトに基づいた技法
      • T: リスクに基づいた技法
      • T: 利用に基づいた技法
      • T: 組み合わせの技法
      • T: コード解析技法
    • S-KA: テスト自動化技法
  • KA: 品質分析と評価の技法
    • 目的: 解析、見える化、予測、フィードバックと根本原因分析により、結果として製品の品質を高めること
    • S-KA: 信頼性予測に関する技法
      • T: ソフトウェア信頼性モデル
      • T: Fault-Prone分析
        • Fault-Proneモジュール判別モデルと呼ばれる数学的モデルを使う
    • S-KA: 品質進捗管理に関する技法
      • T: 工数・成果モデル
        • 工数指標と発見障害などの成果を組み合わせたマトリクスを作成し、座標位置によりプロセス品質を把握する技法
      • T: Rayleighモデル
        • ソフトウェア開発プロセスのすべてにおける障害率を表したモデル
        • m=2のWeibull曲線の特別な場合
        • 目的: 出荷後の障害率を見積もるなどできる
      • T: PTR(Problem Tracking Report)サブモデル
      • T: その他の品質進捗管理に関する技法
    • S-KA: 障害分析に関する技法
      • T: ODC(Orthogonal Defect Classfication, 直交欠陥分類)
        • 目的: 今後予測される障害の顕在化を抑制
        • 効果: 障害管理に工夫を加えることで、プロジェクト進捗の健全性、開発プロセスの実施内容の十分性の全容が把握でき、早期に異変の察知と改善策の実施が可能になる
      • T: バグ分析
    • S-KA: データ解析と表現に関する技法
      • 収集したデータや分析結果を分かりやすく表現することで、論理的思考や数値的分析を必要とする作業や問題解決などに用いる技法
      • T: QC7つ道具
      • T: 新QC7つ道具
      • T: その他の統計技法
  • KA: 運用と保守の技法
    • S-KA: 運用の技法
      • T: ソフトウェア若化(software rejuvenation)
        • 経年劣化の未然防止
    • S-KA: 保守の種類と技法
      • T: 保守の種類
        • 是正、予防、適応、完全化
      • T: 保守の技法
        • 理解と解析、拡張と変更

Ch04 専門的なソフトウェア品質の概念と技術

  • KA: ユーザビリティ
  • KA: セーフティ
    • S-KA: セーフティの品質の概念
      • 本質安全
        • ハザードを取り除く性質
      • 機能安全
        • ハザードにより危害に至らない性質や危害を回避できる性質
      • リスク評価
      • セーフティを最優先する組織文化
    • S-KA: セーフティの技法
      • T: セーフティ実現のためのリスク低減技法
      • T: セーフティ・クリティカルシステムのテスト
    • S-KA: セーフティ・クリティカル・ライフサイクルモデル
      • 安全性解析
      • 開発
      • 安全妥当性確認
      • T: 電気・電子・プログラマブル電子安全間連携の機能安全
      • T: 自動車-機能安全
      • T: 医療機器ソフトウェア-ソフトウェアライフサイクルプロセス
  • KA: セキュリティ
    • セーフティとの違いは、「攻撃者」を想定しているかどうか
    • S-KA: セキュリティの品質の概念
      • 機密性、完全性、可用性
      • 真正性、責任追跡性、否認防止、信頼性、インテグリティ
      • T: 情報セキュリティの定義
        • 近年は、サイバーセキュリティの用語が多用されるようになっている
    • S-KA: セキュリティの技法
      • T: セキュリティ要求分析
      • T: セキュリティ設計
      • T: セキュリティパターン
      • T: セキュアコーディング
      • T: セキュリティテスト
      • T: 脆弱性管理
  • KA: プライバシー
    • S-KA: プライバシーの品質の概念
    • S-KA: プライバシーの技法
      • T: プライバシー影響評価(PIA: Privacy Impact Assessment)
      • T: プライバシー保護技術(Privacy Enhancing Technologies)

Ch05 ソフトウェア品質の応用領域

  • KA: AIにおける品質
    • S-KA: AIにおける品質の概念
      • 訓練データとテストデータの品質
      • モデルの品質
      • 機械学習を用いたシステムの品質
    • S-KA: AIシステムの品質マネジメント
      • PoC(Proof of Concept)という試験的で探索的なプロセス
    • S-KA: AIシステムの品質技術
      • モデルの性能指標以外の品質技術については、2020年時点では発展途上で、アプリケーションへの依存度が高い
      • T: 疑似オラク
      • T: メタモルフィックテスティング
      • T: 頑健性検査
      • T: ニューロンカバレッジ
      • T: 説明生成
  • KA: IoTシステムにおける品質
    • IoTは、従来のシステムが扱っていたサイバー世界にとどまらず、モノやヒトなどの物理世界とともに密に連携するシステムインフラ
    • 類似語: CPS(Cyber-Physical-System)
    • S-KA: IoTシステムにおける品質の概念
      • T: IoTセキュリティ
        • エッジに含まれるセンサーとデバイスのセキュリティが、IoTセキュリティを特徴づける
      • T: IoTプライバシー
    • S-KA: IoTシステムの品質マネジメント
      • 表5.2.1: IoTシステムの運用と保守におけるリスクと注意点
    • S-KA: IoTシステムの品質技術
      • T: IoTセキュリティ技術
        • 表5.2.2: IoTセキュリティベストプラクティス
          • バイス、ネットワーク、IoTシステム全体
      • T: IoTプライバシー保護技術
  • KA: アジャイル開発とDevOpsにおける品質
    • S-KA: アジャイル開発とDevOpsに置ける品質の概念
      • T: アジャイル開発の品質
        • 設計と同時にテスト
        • 自動化
        • 変更容易性
        • 開発チームの自律性を尊重
      • T: DevOpsの品質
        • 表5.3.1: DevOpsにおける品質特性と意味
    • S-KA: アジャイル開発とDevOpsの品質マネジメント
      • T: 伝統的なQA(Quality Assurance)からAQ(アジャイルクオリティ)へ転換
        • 表5.3.2 QA to AQ 主要パターン
      • T: アジャイルスキル体系
        • ITSS+やSFIA(7)から、必要なスキルが分かる
      • T: コミュニケーション管理
    • S-KA: アジャイル開発とDevOpsの品質技術
      • T: アジャイルメトリクス
      • T: 品質ダッシュボード
      • T: アジャイル開発とDevOpsのツールと自動化
        • 表5.3.3: アジャイル開発とDevOpsを支えるツールを形成する要素
          • 抽象化、自動化、共通化、CI、モニタリング
      • T: プルリクエスト駆動開発
      • T: CI
        • → さらに発展ならCD
          • 本番ソフトウェアの作成や本番システムへのデプロイも対象になる
      • T: アジャイルテスト
        • 顧客価値を継続的に向上させることを念頭に置いたテスト技法
      • T: 継続的テスト
      • T: シフトレフトテスト
        • 開発の早い段階から
      • T: シフトライトテスト
        • 本番環境に入った後に実施するテスト
      • T: カオスエンジニアリング
        • 本番環境で、将来の可能性あるイベントに対処できるかどうか確認できる
      • T: カナリアテスト
  • KA: クラウドサービスにおける品質
    • クラウドサービスプロバイダ、クラウドサービスカスタマー
      • クラウドサービスカスタマーは、サービスプロバイダとエンドユーザを含む
    • S-KA: クラウドサービスにおける品質の概念
      • クラウドサービスの機能面は、クラウドサービスプロバイダから提供される文書を用いて機能適合性を確認する必要
      • 非機能面は、提供されるSLAを確認
      • セキュリティも重要な確認事項
      • T: クラウドサービスの機能適合性と互換性
      • T: クラウドサービスのSLA
        • SLO
        • SQO
      • T: クラウドサービスのセキュリティ
    • S-KA: クラウドサービスの品質マネジメント
    • S-KA: クラウドサービスの品質技術
      • クラウドネイティブ: クラウド上での利用を前提として設計されたシステムやサービス
      • マイクロサービスを利用したシステムは複雑になりがち
        • → 本番環境で実験するカオスエンジニアリングで、従来の手法で発見困難な障害を検出する
      • T: 仮想化
        • 計算機、ストレージ、ネットワーク
        • 仮想化の利点を考慮した設計のソフトウェアでないと効果は限定的
      • T: マイクロサービス
        • 協調して動作する小規模で自律的なサービス
        • 目的
          • スケーラビリティを確保した迅速な機能追加や修正の能力などを持ったサービスを提供
        • 方法
          • 大きなサービスを、業務やデータの塊で互いに疎結合な複数のサービスに分割し、各マイクロサービスを小さな1つの役割に専念させる
          • マイクロサービス間のやりとりは、REST、GraphQL、gRPCなどの軽量なinterfaceであるWeb APIを公開し、それらのみでアクセスするよう構成
          • マイクロサービスごとにアジャイル開発チームを編成する
        • 留意点
          • 小さく複雑でなく改修頻度が低いシステムは、マイクロサービスに分割するデメリットの方が大きい
          • Kubernetesなどの使用
      • T: クラウドデザインパターン
  • KA: OSS利活用における品質
    • S-KA: OSS利活用における品質の概念
      • 将来性を見据えた選択と、利活用の前のOSSの品質評価が必要
    • S-KA: OSS利活用の品質マネジメント
      • OSS管理
        • 公開されているOSSの障害情報を収集し、OSSの選択や障害対応を効率的に実現するマネジメント
        • 障害情報の自動収集
        • プログラムの特徴量や、ソフトウェアの開発履歴が記録される構成管理システムの変更ログなどを用いて、潜在欠陥が混入しているモジュールを特定する手法など
        • OSSとして公開されるライブラリの脆弱性を多数記録するDB(Snyk)などを利用する
    • S-KA: OSS利活用の品質技術
      • OSS健全性評価メトリクス
        • OSSに関与する組織の健全性と持続可能性を評価する
        • マイニングソフトウェアリポジトリ分野の学術会議や産業界において指標が提案されている
        • CHAOSS
          • Dicersity-Inclusion
          • Growth-Maturity-Decline
          • Risk
            • 人的要因、ライセンス、脆弱性の観点
          • Value

『サイバーセキュリティプログラミング』学習メモ

Ch01 Python環境のセットアップ

  • pipのインストール
    • これを参照
    • aptだとpython3の方のpip3しか入れられなかった
  • github3.py
    • python -m pip install github3.py==1.0.0
    • バージョンを指定しないとSyntaxError(最新版はPython 2.7は対象じゃないらしい)
  • Wing IDE
    • ダウンロードしてdpkg -i (ファイル名)
    • Stack Data
    • Debug Probe
      • personalにはない?

Ch02 通信programの作成: 基礎

  • ネットワークを介して攻撃を行うためのツールが,target companyにはない
    • 一方,Pythonがインストールされていることはよくある
    • Pythonを足がかりにする
  • Pythonによる通信programについて
    • Pythonでserver client communicationを行うthird_partyのツールはたくさんあるが,そのすべての核となっているのがsocket library
    • socket library: TCP, UDPで通信するclient, serverのprogramを素早く書いたり,raw socketを利用したり,その他さまざまな通信programを作成したりするうえで,必要不可欠なもの
      • このモジュールを使えば,target terminalへの侵入やメンテナンスなど,必要なことはすべて実現できる
  • TCP_client
    • penetration_testでは,サービスの検査やゴミデータの送信,fuzzingやその他のさまざまなことを行うためのTCP_clientを手早く作ることがたびたび必要になる
      • 制約によっては,コピペやネット接続すらできないこともある
    • 重要な仮定
      • このスクリプトを使った接続は常に成功する
      • 接続先のサーバが常にデータを先に送ると想定している
      • 接続先のサーバはいつでもうぐさまデータを返信してくる
  • UDP_client
    • TCP_clientとほとんど変わらない
      • socket type がSOCK_DGRAM
      • sendtoのみ(connect()は不要)
  • TCP_server
    • 簡単なコードだが,Netcatの自作やTCP proxyの作成を行う以降の節で拡張していくことになる,便利なコード
  • Netcatの置き換え
    • Netcatは攻撃者にとって非常に便利なツール
    • Web applcationに対する攻撃で侵入したときは,侵入に成功した後の接続経路を確保したいと考える
    • subprocess library
      • process generateで役立つinterface
      • processを立ち上げたり子processとやりとりしたりするのに利用される
      • このコードでは,渡したコマンドをそのままローカルのOSに渡して実行させている
        • 実行結果はサーバに接続してきているクライアントに送信する
        • 例外処理では,一般的なエラーを補足し,コマンド実行が失敗したことを伝えるメッセージをクライアントに送るようにしている
    • ファイルのアップロード,コマンド実行,コマンドシェルの実行を行う処理を実装
    • 試してみる
      • サーバとして動作するスクリプトUnixホスト上で動作しているため,SSHでログインしているときやUnixホストのローカルで作業をしているときにコマンドを実行しているかのような出力になっている
      • 技術的にはまったく高度ではないが,Pythonで複数のclientやserverのソケットを一度にハックして悪さしようとするときの基本的なやり方
  • TCP_proxyの構築
    • toolboxにTCP_proxyを入れておくべき理由
      • あるホストから別のホストにデータを転送したり,ネットワークを利用するソフトウェアの検査をしたりといった作業に必要になる
    • 詳細がわからないプロトコルを解き明かしたり,applcationに送る通信データを改変したり,ファジングテストのためのデータを作ったりといった,様々な場面で使える簡単なPythonのproxy script
    • proxy_handler()
      • response_handler()の中で,パケットの書き換え,ファジングテストの実施,認証における問題のテストなど,リモートから受信したパケットに対してやりたいことをなんでも実施できる
        • request_handler()も同様
        • 認証情報が平文でやりとりされるapplcationの通信で,一般ユーザの情報の代わりに管理者の情報を送ることで権限昇格を試みるときなどに便利
    • hexdump()
      • 16進数表記およびASCIIの表示可能文字で画面に出力する関数を作る
      • 詳細がよくわからないプロトコルを解き明かす場合や,平文でやりとりされるプロトコルにおいてユーザの認証情報を取得する場合など,多くの場面で役立つ
    • 試してみる
      • 内容と返還後の文字列が表示される
  • Paramikoを用いたSSH通信programの作成
    • 検知から逃れるために通信の暗号化が〇
    • ParamikoというPyCryptoを使ったlibraryを使えば,SSH2 protocolを簡単に扱える
    • 実装
    • SSHサーバに接続して複数のコマンドを実行させたり,複数のSSHサーバに接続してコマンドを実行させたりできる
    • Windowsには誰でもすぐに使えるSSHサーバは備えられていないので,独自に作ったSSHサーバからSSHクライアントにコマンドを送るようにする必要がある
    • 試してみる
      • コマンドがSSHサーバに送られ実行され,結果をサーバ上で表示
  • SSH_tunneling
    • 目的: SSH clientで入力されたコマンドを遠隔地のSSH server上で動かすこと
    • SSH_tunnelingを使う場合,送信データはまとめられてSSHで送信され,SSHサーバ上でその中身が取り出され,サーバの処理に引き渡される
    • 状況
      • internetを介してアクセスできるSSH_serverがあり,そのSSH_serverと同じネットワーク内にあるWebサーバにアクセスしたい
      • Webサーバに直接アクセスはできないが,SSH_serverからはアクセスできる
      • SSH_serverには使いたいツールがインストールされていない
    • → 手段1: SSH_forward_tunneling
      • ssh -L 8008:web:80 justin@sshserverというコマンドを実行すると,justinというユーザでSSH_serverに接続し,ローカルシステムの8008番ポートの準備が行われる
    • 多くのWindowsシステムではSSH_serverが動作していないが,そのような状況でも,SSH_tunnelingを逆向きに設定することで解決できる
    • → 手段2: SSH_reverse_tunneling
      • reverse_forward_tunnel()
        • transport()
          • 暗号化された接続の作成や設定
        • channel
          • 暗号化されたセッションを通じてデータの送受信を行うためのソケットのようなもの
    • 試してみる
      • Windowsの環境からSSH_serverとの接続を確立し,そのサーバの8080ポートを待機状態にする
        • 8080ポートへの通信はWebサーバの80番ポートに転送される
        • Linuxでブラウザからhttp://127.0.0.1:8080にアクセスすると,SSH_tunnelを通じてWeb_serverに接続することになる
    • SSHSSH_tunnelingを理解し,利用するのは重要
      • 使いどきや使い方の把握
    • Paramikoを使えば既存のPythonツールにSSHの機能を追加できる
  • まとめ
    • とても単純だが非常に役立つツールの作成
    • 目標: penetration_testを行うときや攻撃が成功した後の活動を行うとき,バグ探しのときなどに使うツールを作成するのに十分な,Pythonのネットワークプログラミング技術を身につけること

Ch03 network: raw_socketと盗聴

  • network_sniffer: target machineが送受信するパケットの観測を可能にするため,攻撃の前後でよく利用される
  • network通信を観測したりでコードしたりするスニッファーを即席で作る方法を知る
    • 手軽で成熟したツールに関して深い理解
    • Pythonの新しいテクニックの学習
    • 低レイヤーのネットワークの動きを理解
  • 生のIPヘッダやICMPヘッダのような低レベルのネットワーク情報にアクセスするには,raw socketを使う
  • UDPを用いたホスト発見ツールの作成
    • target networkで動作中のホストを発見するUDPベースのスニッファーの作成
    • 攻撃者は事前調査を行ったり,攻撃対象を絞り込んだりするために,ネットワーク上に潜むすべての標的を見つけようとする
    • 特定のIPアドレスでホストが稼働しているか判断するために,UDP portにパケットが届いた時の処理方法を利用する
      • 一般的には,UDPデータグラムをホスト上の閉じたポートに送ると,当該ポートに到達できないことを示すICMPメッセージが返信される
      • UDPデータグラムに対する応答を受信できなければ,ホストは存在しない
      • ICMPメッセージを受信できる → ホストが稼働していることを意味
    • UDPを選ぶ理由: overheadなし
    • scannerで,発見したすべてのホストに対してNmapによる完全なポートスキャンを開始させるような処理の追加もできる
  • WindowsLinuxにおけるパケット盗聴
    • 試してみる
      • pingを実行したときのrequestをキャプチャ
  • IP_layerのデコード
    • ctypes構造体の定義
    • protocolとIPアドレスを読みやすい形式に変換
    • 試してみる
      • IPヘッダがデコードされる
  • ICMPのデコード
    • type=3: 宛先到達不可能クラス
    • code=3: ポート到達不可能エラーが発生
    • 元のデータグラムの先頭8バイトがICMPメッセージに含まれるため,照合できる
    • netaddr libraryを使うコードを追加し,ホスト発見用のスキャンをサブネット全体に対して実施できるようにする
      • netaddr module
        • subnet maskを入力として受付,適切に処理
        • subnet, addressをとても簡単に処理できるようになる
    • 試してみる
      • 対象のサブネット内をスキャンできる

Ch04 Scapyによるネットワークの掌握

  • e_mailの平文の認証情報の窃取,同一ネットワーク内の通信を傍受するための標的マシンに対するARPポイズニングの体験
  • Scapyのpcap処理を拡張してHTTP通信から画像を切り出し,その画像に人が含まれているかを判断するために顔検出を行うデモを実施
  • e_mailの認証情報の窃取
    • Scapyのinterfaceを使って,パケットを傍受しその内容を詳細に分析する方法を見る
    • SMTP, POP3, IMAPの認証情報を窃取する簡単なスニッファーの構築
      • あらゆるprotocolに適用できる
    • ARP_poisoningによる中間者攻撃(MITM)を組み合わせて,ネットワーク上のほかのマシンから容易に認証情報が窃取可能なことを示す
    • sniff()
      • 傍受用の関数
      • store=0: Scapyはメモリ上にパケットを保持しないようになる
        • 長時間スニッファーを動作させておくならこれを使う
    • 試してみる
      • メールクライアントが平文の認証情報を送っていることが分かる
  • Scapyを使ったARP_cache_poisoning
    • ARP_cache_poisoning: ハッキング用ツールキットに含まれるものの中で最も古い技術の1つだが,いまだに最も効果的な技術の一つでもある
    • target machineには自分のマシンをゲートウェイと思わせ,ゲートウェイにも自分のマシンを通す必要があると思わせる
    • network上のすべてのコンピュータが持っているARP_cacheを,攻撃用に用意したエントリーで汚染する
    • ipconfigでARP_cacheを確認
      • ゲートウェイのIP_addressと,関連付けられたARP_cacheのエントリーが持っているMAC_addressを確認
    • 試してみる
      • scriptを動かす前に,ローカルホストのマシンを,ゲートウェイと標的のIP_addressの両方に対してパケットの転送が可能な状態にする必要がある
      • ARP_cacheが汚染される(ゲートウェイMAC_addressが攻撃者のMAC_addressと同じになっている)
  • pcap fileの処理
    • キャプチャーされたネットワーク通信に基づいたファジング用のテストケースの生成や,以前にキャプチャーした通信を再生するような単純な作業に,PythonやScapyを使ってさまざまな観点でpcapを分析する
    • HTTP通信からの画像ファイルの切り出し
    • pcapの解析
    • 画像の判定と出力
    • 試してみる
      • target画見ている内容の種類の確認や,ソーシャルエンジニアリングを用いた面白いアプローチの八景に役立つ
      • Web_crawlingや解析の処理と連携することもできる

Ch05 Web_serverへの攻撃

  • Web_applicationの解析は,攻撃者にとってもペネトレーションテストをする者にとっても非常に重要
    • 最も攻撃にさらされ,侵入に最もよく使われている
  • Pythonを使ったWeb_serverとのやりとりについて,事前調査と総当たり攻撃のツールを作成しつつ見ていく
    • 総当たり攻撃や調査ツールの作成,テキスト量の多いサイトでの検索において,HTMLのパースがいかに大事か分かる
  • Webのソケットライブラリ: urllib2
    • Requestクラスを使って捜査する
  • open_sourceのWeb_applicationのインストール
    • セキュリティ対策やインストール手順の誤りが,攻撃者のWeb_serverへの侵入につながる
    • インストールすればファイルやディレクトリの構成がすべてわかるので,特定のターゲット専用のスキャナーを作成できる
    • thread safeなPythonのQueueオブジェクトを使って,多数のスレッドを起動して複数のアイテムを処理 → 素早くスキャナーを実行
    • 試してみる
      • ファイルを取得できる
  • ディレクトリとファイルの総当たり攻撃
    • Web_server上のアクセス可能なファイルを全て知るのは難しい
      • → 通常は,Burp Suiteにも含まれるスパイダーを使い,ターゲットとなるWeb_siteをクロールし,可能な限り情報を集めることになる
      • → 設定ファイルや消し忘れの開発途中のファイル,デバッグ用のスクリプトやセキュリティに関係するその他のファイルなどを見つけ,重要な情報やソフトウェア開発者が意図せず稼働している機能を把握できる
      • 総当たり攻撃ツールを使ってよくあるファイル名やディレクトリ名をしらみつぶしに探すしかない
    • 実装
      • DirBuster project, SVNDiggerのような一般的な総当たり攻撃用の辞書
      • threadを作ってファイルを探索する
      • network接続が切断した場合やターゲットのサイトがダウンした場合に備えて,途中から再開できる機能も作っておく
      • リクエストを作る際に使う拡張子のリスト
      • status_codeが404の場合以外もURLを表示する → File not found以外のstatus_codeが攻撃の助けになる可能性があるため
    • 試してみる
      • OWASP(Open Web Application Security Project)は,ツールのテスト用にオンラインやオフラインで脆弱なWeb_applicationのリストを公開している
      • target Web_serverから興味深い情報を取得
      • Web_applicationをターゲットとする場合,総当たり攻撃による情報収集がなにより重要
  • HTML_formの認証を総当たり攻撃で破る
    • CAPTCHAトークンの使用など,Webシステムの総当たり攻撃対策は日に日に一般的になってきている
    • Joomlaに対する総当たり攻撃
      • パスワード入力の前にログインフォームからログイントークンを取得する
      • urllib2でCookieを使えるようにすることが↑と合わせて必要
      • ログインフォームのパース
        • HTMLParser libraryを使って行う
      • 総当たり攻撃に必要ないくつかの情報(例)
        • 宛先のパスに対してPOSTリクエストを送ること
        • すべての項目に入力する必要がある
        • hidden fieldでname attributeに長くてランダムな文字列が設定されている
          • ランダムな文字列はCookieに格納されたうえでセッション管理に使われている
      • → 手順
        • ログイン画面を取得し,Cookieをすべて受け入れる
        • HTMLからフォームの要素を取り出す
        • ユーザ名やパスワードを辞書から推測し設定する
        • すべてのフォームのフィールドを設定し,CookieとともにPOSTリクエストとして送信する
        • Web_applicationにログインできたかどうか確認する
      • 実際のターゲットで試しながらツールを作るべきではない
    • HTMLParserクラスの使い方の基礎を押さえれば,将来攻撃するであろうWeb_applicationについての情報収集に応用できる
      • 最初に,結果の一覧を保存する辞書を作る
      • パースして,タグを見つける度にhandle
        • 特にinputタグが重要で,見つかった時はメインの処理を行う
        • name, value属性が見つかった時はtag_resultsという辞書に保存
      • パースが終わったら,総当たり攻撃のクラスでユーザ名とパスワードのフィールドの値を置き換える
    • HTMLParserの基礎
      • handle_starttag
      • handle_endtag
      • handle_data
      • フォームのパースやリンクの収集,データの解析のためのテキストの取得,ページ内の画像の検索など,さまざまなことができるようになる
    • 試してみる
      • ターゲットのJoomlaに対してログインできる

Ch06 Burp Proxyの拡張

  • Burp Suite: スパイダーやプロキシによる通信の閲覧など,攻撃を支援するツール
    • Extensionsを使って,攻撃や詳細な事前調査を行うための便利なツールをBurpに追加する
  • セットアップ
  • Burpを使ったファジング
    • HTTP通信に隠されたバイナリプロトコルや,複雑なJSONリクエストを扱う場合,典型的なWeb_applicationのバグを検査できるということは非常に重要
    • ペイロードを自由に操作できるお手製のファジングツールでリクエスト本体をいじりつつ,認証のためのCookieなどの基本的なHTTP通信の確立はBurpに任せられるようにすると便利
    • BurpはWeb_applicationの検査を行うためのさまざまなツールを持っている
      • 基本的には,すべてのリクエストをプロキシでとらえ,興味深いリクエストを見つけたときは,ほかのツールにそれを渡す
        • Web通信を再現してくれるBurp Repeaterにリクエストを渡して,手動で面白そうな部分を編集するなど
        • query parameterを使った攻撃の自動化
          • requestをBurp Intruderに渡せばHTTP通信の中で変更したいであろう場所を自動的に把握してくれる
            • → エラーメッセージを表示させたり脆弱性を見つけたりするための様々な攻撃に使える
    • まず,BurpのAPIドキュメントを読んで,どのBurpクラスが拡張機能を作成するために必要なのかを探る
      • ExtenderタブのAPIsタブをクリックするとドキュメントを表示
    • Pythonコードの実装
      • IIntruderPayloadGeneratorクラスを追加
      • 3つの関数を含む基底クラスを実装
    • 単純なSQLインジェクションのテスト,クロスサイトスクリプティングのテスト,オリジナルのペイロードからランダムに塊を取り出してランダムな回数分繰り返したものを追加するテスト,という3つのうち1つをランダムで選び出して実行するシンプルなファジングツールを作成
    • 試してみる
      • query parameterがハイライトされる
      • 警告から,SQLインジェクション脆弱性が表示される
      • Web_applicationのエラーを誘発したり,アプリケーションのパスを開示したり,ほかのスキャナーができないようなさまざまなことができる
      • 大事なのは,Intruderによる攻撃で使う拡張機能の操作方法を学ぶこと
  • BurpでBingを使う
    • Bing APIを使ってプログラムでクエリ―を送信し,結果を解析する
      • 発見したターゲットを自動的に追加
    • 実装
      • BingのAPIキーを設定
      • BurpのHTTP APIを使うときは,送信する前に完全なHTTP リクエストの文字列の作成が必要
      • Jython APIPythonの組み合わせで,特定のターゲットを攻撃する際の詳細な事前調査を,Burpの拡張機能で実現
    • 試してみる
      • GetリクエストからBingに送って,自動的に新たなホストがターゲットに追加
  • Web_siteのコンテンツをパスワード作成に利用する
    • セキュリティはしばしばユーザのパスワードに帰結する
    • onlineでのパスワード攻撃の肝は,適切な単語リストの入手
    • 実装
      • BurpのUIにコンテキストメニューを追加する
      • 独自の単語リストをセットに保存し,同じ単語を導入しないようにする
      • BurpからHTTPのトラフィックを選択し単語リストに追加
      • mangle()で,ベースとなる単語を切り出して,一般的なパスワード生成戦略をもとに単語を作成する
    • 試してみる
      • 単語リストの作成と表示

Ch07 GitHubを通じた指令の送受信

  • トロイの木馬の堅牢なフレームワークを作るときに最も困難なことの1つは,設置したトロイの木馬の制御やアップデート,データの受信を非同期的に行うこと
  • remoteのトロイの木馬にコードを送信するための普遍的な方法を持つことが重要
    • トロイの木馬ごとに異なる作業をさせる
    • ターゲットのOSにあったコードを追加
  • GitHubを使って,設置したトロイの木馬の設定情報や窃取したデータだけでなく,タスクを実行するために必要なモジュールを保存するようにする
  • Pythonがライブラリをインポートする仕組みをハックすれば,設置したトロイの木馬が,新たに作成したモジュールと必要なライブラリをリポジトリから自動的に取得してくるようにできる
  • GitHubとの通信はSSLで暗号化されており,GitHubがブロックされていることも非常に少ない
  • GitHubのアカウントを設定する
  • moduleの作成
    • 開発する各モジュールは,複数の引数を渡せるようにしたrun関数で実行されるようにするべき
      • → 各モジュールを同じ方法でロードでき,かつ設定ファイルをカスタマイズしてモジュールに引数を渡すようにもできる
    • ローカル環境のトロイの木馬で新たなモジュールを有効にすることで,モジュールが正常に動作するか確認
  • トロイの木馬の設定
    • さまざまな捜査をしつつ長期間にわたってトロイの木馬に仕事をさせるためには,どのような操作を実行するか,どのモジュールがその操作に必要なのかを指示する仕組みが必要
    • ↑ 設定ファイルで操作を制御し,必要ならタスクを与えないことでトロイの木馬を眠らせておくこともできる
    • モジュールの実装の際,実行時間,実行回数,引数などのオプションを追加できると便利
    • トロイの木馬にインポートして実行してほしいモジュールの辞書のリストを渡す
  • GitHubから指令を受信するトロイの木馬の作成
    • GitHubへの接続と認証,APIの操作を行うコードの作成
    • 実際のシナリオでは,認証のやり取りは可能な限り隠すべき
    • 発見されてもデータを削除されないように,トロイの木馬がアクセスするリポジトリにアクセス制限をかけることも一考
  • Pythonのインポート機能をハックする
    • トロイの木馬が必要なlibraryをすべて読み込んでくれるようにする
    • ランダムな時間スリープしてパターン解析によって発見されることを防ぐ
    • ほかの処理を行ってトロイの木馬が何をしているのか隠すのも〇
    • 試してみる
      • 実行結果がGitHubにpushされている → 取得すれば見られる
  • 改善,拡張
    • モジュールや設定,取得したデータをすべて暗号化
    • updateなどの自動か

Ch08 Windowsトロイの木馬がよく悪用するテクニック

  • ウイルス対策ソフトやエンドユーザ自身によって検出される可能性との戦い
  • トロイの木馬を設置した後の標的マシンを注意深くモデル化し,トロイの木馬を本当に標的にマシンに対して送りつける前に,実験環境内でそれらのモジュールをテストする
  • 趣味と実益のためのキーロガー
    • キーロガー: 最も古い物の1つだが,さまざまな隠蔽方法とともにいまだに使われている
      • 認証情報や会話の内容といった機密情報の窃取に非常に効果的
    • pyHookによりキー入力のイベントを容易にトラップできる
      • ネイティブWindows APIであるSetWindowsHookExを活用している
        • 特定のWindowsイベントが発生した際に呼び出されるユーザ定義の関数を設定できる
        • → キー入力のイベントに対してフックを設定
      • どのプロセスに対してキー入力が行われているか正確に知ることで,ユーザ名,パスワード,およびその他の有用な情報がいつ入力されたかも割り出せる
      • pyHookは,キーロガーの中核となるロジックは我々に任せつつ,低レベルプログラミングの部分の面倒を見てくれる
    • イベントに対して別のフックが存在していた場合,コールバック関数は真を返すことで,次のフックにもイベントを処理させることができる
  • 試してみる
    • どのウィンドウで何を入力したか分かる
  • screenshotの撮影
    • パケットキャプチャやキーロガーでは手に入らない,デスクトップの画像やビデオの撮影,その他の機密データの入手に役立つことがある
    • WindowsのGraphics Device Interface(GDI)を使用する
  • Python流のシェルコードの実装
    • ctypesモジュールをスカってメモリ上のバッファをさす関数ポインタを作成して,その関数を呼び出す
    • ここでは,urllib2を使ってWeb_serverからBase64形式でシェルコードを受け取って実行できるようにする
    • ctypesのcastでバッファを関数ポインタに型変換し,シェルコードを通常のPythonの関数と同じように呼び出せる
    • 試してみる
      • カレントディレクトリをWebルートディレクトリとして扱うために,SimpleHTTPServerモジュールを使う
        • → Webのリクエストに対して任意のファイルを提供できる
      • Webサーバからスクリプトがシェルコードを受け取る
  • sandbox検知
    • 最近のウイルス技術ソフトは,疑わしいファイルの振る舞いのチェックに,ある種のサンドボックス技術を取り入れている
      • いくつかの指標を使って,サンドボックス上で動いているかどうかを判断する
    • 今回は,標的マシン上で,キー入力やマウスのクリックといった,利用者の入力が最近あったかを監視する方法を実践
      • パソコンを起動してからの経過時間と利用者が最後にパソコンに入力した時間を確認
      • → この方法は,利用者が使用中かどうかで活動を変更する方法にも活用できる
    • ctypes libraryで実装
    • 一般的な利用ではない発生の仕方の場合もサンドボックスと分かるようにする

Ch09 Internet Explorerで楽しもう

  • applcationにIEのCOMオブジェクトを埋め込める
  • → ネイティブのIEオートメーションオブジェクトを利用して,ある種のMan_in_the_Browserタイプの攻撃を行い,利用者がWebサイトとやり取りする際に認証情報を窃取する
  • → 拡張して,複数の標的Webサイトに関しても実現可能にする
  • 最後にIEを使用して標的マシンからデータを窃取する
    • 窃取データの保護には公開鍵暗号を使用し,我々しか復号できないようにする
  • (ある種の)Man_in_the_Browser
    • MITMが通信に介在するのに対して,MITBはブラウザそのものに寄生することで認証情報や機密情報を窃取する
    • この種のマルウェアのほとんどが(典型的にはBrowser Helper Objectのような形で)ブラウザに寄生するか,あるいはコードをインジェクションすることで,ブラウザのプロセスそのものを操作する
    • IE用にネイティブCOM interfaceを使用することで,SNSサイトや電子メールサービス用の認証情報をあらゆるIEのセッションから窃取する
      • ロジックの拡張もできる
        • 利用者のパスワードの変更,ログイン時のやり取りに介在,キーロガーモジュールを併用して,再認証を強制的に発生させてキー入力を取得するなど
    • 実装
      • 目的のサイトの認証情報を窃取するための中心となるループ処理
        • すべての動作中のIEオブジェクトを繰り返しチェックすることから始める
        • ログアウトさせる
        • ログインフォームを改ざん
        • 認証情報の送り先WebサーバへのアクセスURLの末尾が標的サイトになっている
          • これにより,用意しておいたWebサーバのログなどを通じて,認証情報の窃取に成功した標的サイトが何かを明らかにできる
        • wait_for_browser()によって,ページのコンテンツがすべて読み込まれてから,ページを編集したりパースしたりするようにしている
    • サーバの作成
      • 窃取した認証情報を集める
    • 試してみる
      • 最初のテスト
        • いろいろなサイトを閲覧して,利用者に見られるべきでない変な挙動を目にすることがないか確認する
        • FacebookまたはGmailにアクセスし,ログインする
      • 利用者の認証情報を入手できる
  • IEのCOM_automationを使用した情報の盗み出し
    • 標的ネットワークに侵入することは戦いの一部でしかない
    • 一般的な目的: データファイルの窃取
    • セキュリティ対策によっては,通信をするプロセスや通信先を確認して,遮断などの措置を行うことがある
      • iexplore.exeは通常信頼されていてホワイトリストに入っているため,情報を外部のネットワークへ盗み出す手口としてIEのCOM_automationを使用するのは非常に優れている
    • ローカルのファイルシステム上からWord文書ファイルを検出するPythonスクリプトの作成
      • 検出したら公開鍵暗号を使ってそのファイルを暗号化し,tumblr.comにあるブログに投稿することを自動化する
        • Tumblrのように一般的に信頼できると認知されているサイトを使うことで,ファイアウォールやプロキシなどが持つブラックリストによるIP_addressのWeb_serverへの情報送信のブロックも回避できる
    • 実装
      • encrypt_string(plain_text)
      • encrypt_post(filename)
      • login_to_tumblr(ie)
        • 正確なタイミングの計測,DOMとの対話,必要なHTML要素を明らかにする必要
      • post_to_tumblr(ie, title, post)
      • exfiltrate(document_path) exfiltrate: こっそり抜け出す
        • Tumblrに保存したい文書ファイルを発見するたびに呼び出される
        • Windowの表示・非表示を指定できる
      • RSA暗号用の鍵の生成スクリプト
      • Tumblrに投稿された暗号化データをペーストして平文に復号するスクリプト
    • 試してみる
      • ファイル名が窃取される
      • オリジナルのファイルサイズを暗号化して記載するのも〇

Ch10 Windowsにおける権限昇格

  • 必須要素のインストール
  • process監視ツールの作成
    • WMIを使用したプロセス監視
      • WMIのAPI群は,システム上での特定のイベントの発生を監視し,そのイベントが発生した際にコールバックを受け取る方法をプログラマーに提供する
    • 試してみる
      • あらゆるプロセス,スケジュール化されたタスク,さまざまなソフトウェアの自動アップデートなどが実行されていることを確認できる
  • Windowsにおけるトークンと権限
    • Windowsにおけるトークン: プロセスまたはスレッドのセキュリティコンテキストを記述するオブジェクト
    • 一般ユーザの権限で動作しているプロセスが誤った権限を持って動作していることを確認できれば,SYSTEM権限またはカーネルレベルでコードを実行する足がかりになる
    • 注目すべき権限
      • SeBackupPrivilege
      • SeDebugPrivilege
      • SeLoadDriver
    • 監視しているプロセスに与えられた権限を自動的に取得するPythonスクリプトの作成
  • 競合状態に勝つ
    • 多くの商用ソフトウェアが,一時フォルダ内にファイルをコピーし,実行したうえでそのファイルを削除する,という動作を行っている
    • ソフトウェアやタスクスケジューラがファイルを作成する際,プロセスがそれを実行する前にそのファイルに攻撃コードを書き込み,そのうえでプロセスに実行させて最後に削除する
    • 実現のカギ: 特定のディレクトリを監視して,ファイルやサブディレクトリの変更を検出するReadDirectoryChangesWという便利なWindows API
      • 潜在的な権限の昇格以外に対しても〇
    • 試してみる
      • ファイルの作成→実行→削除を検出できる
  • code_injection
    • 実装
      • マーカーを使って,無限ループを回避
      • 監視スクリプトのメイン処理にコードインジェクションの呼び出しを追加する
    • 試してみる
      • SYSTEM権限でリスナーを起動する
      • SYSTEM権限を奪取
  • 特定の環境下においてローカルのアカウントやアプリケーションへの攻撃に使用する,独自ツールにも換えられる
  • いったんネットワーク内部に侵入できれば,WMIだけでもローカルネットワークの調査データのよい供給源となり,そのデータをさらなる攻撃に利用できる
  • 権限昇格はあらゆるトロイの木馬にとって必要不可欠な要素

Ch11 forensic attackへの転用と自動化

  • forensic: 侵入された後に,またはインシデントが起こったかどうか判断するために必要とされるもの
    • メモリに含まれる暗号化の鍵谷その他の情報を得るために,汚染されたマシンのRAMのスナップショットが求められる
  • VolatilityというPythonで書かれたforensic frameworkがある
  • install
  • profile
    • profilerにより,メモリダンプから情報を引き出すために必要なシグネチャやオフセットをどのように適用するかを決定する
    • imageinfoというpluginで,そのときのターゲットに対してどのprofileを使うべきか判断してくれる
  • password_hashを手に入れる
    • targetのハードウェアにアクセスすることさえできれば,仮想マシンから情報収集できる
    • Volatilityはpassword_hashの復元処理を非常に容易にする
      • 最初にpassword_hashを取得できそうなメモリ上の場所を見つけ,それからハッシュを実際に取得するために必要なプラグインの操作方法を見る
      • これらの処理を一括で行うスクリプトを作る
    • WindowsはローカルパスワードをSAMレジストリハイブにハッシュの形で保存しており,同時にWindowsのブートキーをシステムレジストリハイブに保存している
      • memory imageからハッシュを取り出すにはこれらのハイブが必要
      • hivelist plugin: 2つのハイブがメモリ内のどこにあるかVolatilityが見つけられるようにする
      • → 情報をhashdump pluginに渡して,実際にハッシュの解析を行う
  • 直接的なコードインジェクション
    • Immunity Debugger
      • reverse engineering
      • Pycommandを使って,exeのすべての関数を見つけて,一度だけ有効なブレークポイントを設置する
    • 複数のステップ
      • memoryをスキャン
      • exeのプロセスを見つけてシェルコードを挿入する場所を決定
      • その場所のRAMイメージの物理アドレスを割り出す
      • 指定の操作に割り当てられている関数のアドレスにジャンプ命令を挿入し,シェルコードにジャンプさせてそれを実行する
    • 実装
      • メモリ上の各ページを調べるとき,まずページの物理的なオフセットを見つける
      • そしてRAMイメージを開き,そのページが存在する場所のオフセットを調べ,メモリ上のページ全体に読み込む
      • シェルコードを同じサイズのNULLバイトの塊を探す
        • ここがRAMイメージ内でシェルコードを書き込む場所
      • 挿入したら,シェルコードをアドレスを取得しx86のバイナリコードを作成する
      • 操作のオフセットを計算し,トランポリンを仕掛ける
    • 試してみる
      • ある操作に対して処理を埋め込める
      • この技術を利用して,kernel objectを操作しrootkitのようなまねをさせることもできる
      • これらの技術は,メモリのフォレンジックに親しむための方法であり,また物理的にマシンにアクセスできる場合や,複数の仮想マシンをホストしているサーバに侵入した際にも使える

Appendix A reverse engineering用framework miasm

  • miasm
    • 用途: バイナリプログラムの解析,編集,生成
    • 機能
      • 実行ファイルの解析,編集,生成
      • プログラムコードのアセンブル,逆アセンブル
      • プログラムコードのエミュレーション
    • x86以外にもさまざまなCPUアーキテクチャに対応している
    • symbolic実行と呼ばれる先進的なソフトウェア解析機能が盛り込まれている点も特徴
  • setup
  • x86_64 assemble
    • データ領域から実行権限が排除されているため,Ch08よりコードの追加が必要
    • assemble_text()でネイティブコードを生成し,execute_native_code()で実行
    • miasmによるエミュレーション
      • サンプルコードがDockerイメージ内にあり,それをもとに作る
      • 柔軟に命令ごとに解釈を変え,処理を追加したり挙動を変更したりできる
      • → 特定の機械語命令が呼ばれた回数を数えるprofilerを作成
      • メモリアクセスの頻度の計測や,関数呼び出しの深さを調べたりと応用できる
  • symbolic実行
    • symbolic実行: レジスタやメモリ内容を具体的な値ではなくシンボルとしてエミュレーションする仕組み
      • たとえば,ある実行パスに到達するための入力値の条件を自動的に求められるなど
  • miasmはリバースエンジニアリングに必要になるさまざまな機能を持っている

Appendix B さまざまなサンドボックス検知

  • サンドボックスによるフックの検知,フックの回避,C言語で書かれた仮想マシン検知プログラムをモジュールとして呼び出す方法
  • マルウェアを解析するサンドボックスでは,解析対象の挙動を把握するため,マルウェアが呼び出すライブラリ関数をフック氏,呼び出された関数名やその関数に渡された引数を取得する
    • フックの実装には,解析対象のプログラムやライブラリを書き換える方法と,ランタイム環境側に手を加える方法がある
    • → 書き換えられた痕跡を見つけることで,前者で実装されたサンドボックスを検知する
    • 仮想マシンを見つけることで,後者の方法で実装されたサンドボックスを間接的に検知する方法もある
  • 簡易サンドボックスの準備
    • ソフトフック
      • 特定のAPI呼び出しをモニタリングする簡易的なサンドボックスを実装する
      • target processにアタッチしINT3に対するブレークポイントハンドラを実装して実行フローを横取りするもの
      • → 具体的にはフック対象の命令をINT3命令に置き換えることで,実行された際,ブレークポイント例外を発生させ,あらかじめブレークポイントハンドラに登録しておいた処理を実行させる
    • 簡易サンドボックス pydbg_sbx.py
      • PyDbgを使い,解析対象が呼び出すAPIをソフトフックにより監視する簡易サンドボックスを実装
    • 実行
      • 引数を伴って関数を呼び出したことがモニタリングできる
  • ソフトフックの痕跡を見つける
    • APIの先頭アドレスにセットされたINT3命令の有無をチェックすることでフックを検出する
    • ハードフックも,jmp命令などの分岐命令がAPIの先頭にあるかをチェックすることで,検知できる
  • サンドボックスを回避する
    • sliding_call
      • APIの先頭アドレスから数命令ずらしてAPIを呼び出す手法
      • Windowsではホットパッチという仕組みがあり,APIの先頭2バイトはホットパッチ用のコードが置かれていることが多い
      • APIの処理に直接影響がないので,実行を飛ばしても基本的に動作に影響しない
    • フックを回避してAPIを呼び出す
    • ハードフックでも.jmp命令のためのバイト分だけずらしてコールすればよい
  • runtime環境の特徴を見つける
    • サンドボックスの中には,解析対象が動作するランタイム環境側(OS,仮想マシンなど)に手を加えてフックを実現しているものも存在する
      • 自身が動作している環境の特徴を見つけることで,間接的にサンドボックスを検知できる
    • 低レイヤへのアクセス → PythonよりC
    • 仮想マシンの検知
      • VMWareで動作するゲストOSは,ホストOS側とやりとりするための通信チャネルが用意されている
        • IN命令の例外の有無を利用して,自身がVMWare上で動作しているか判断できる
    • PythonからC言語で書かれたコードを呼び出す
      • 以下の3つを準備
        • Python用ラッパー関数
        • モジュールのメソッドテーブル
          • メソッド名と実装の対応関係を保持
        • モジュールの初期化関数
    • 実行
  • その他のサンドボックス検知方法
    • debugされているかをWindows APIで確認
    • 特定のプロセス,ファイル,レジストリの有無で確認
    • IP_addressのレンジからクラウド環境で実行されているかなどをもとにして一般的なユーザのデスクトップ環境ではないことを判断し,それに基づいてサンドボックスを検知することもある

『エンジニアの知的生産術』学習メモ

はじめに

  • intellectual_productionとは
    • 知識を用いて価値を生み出す
  • programmingの学び方
    • →↓ x軸 具体: 情報収集,体験
    • ↓ y軸 抽象: 抽象化,モデル化,パターンの発見
    • ↑← z軸 応用: 実践,検証
  • ↑ (y軸は積み上げより掘り下げのイメージ)
    • ちゃんと広い穴を開けておかないと奥が見えない的な
    • xもzも穴のメタファーで回収してた感じはある(そもそもそんな言語化してたわけではないが)

Ch01 新しいことを学ぶには

  • cycleを回す原動力: やる気
    • 学びを分類
    • 逆風が強い → 強いやる気が必要
      • やる気の出るthemeを見つける
    • やる気の維持
      • goalは近くに明確に
        • SMART criteria
    • MOOCでの学び
    • 参考書の探し方
      • 大学の講義の参考図書になっている
      • 正誤表が充実している
      • 改訂されている,ロングセラーである
  • 情報収集の3つのポイント
    • 知りたいところから
    • 知りたいところから学ぶための前提条件
      • 目標を明確にする
        • 現実とのgapを表現する
        • なぜ予想と違うのか
      • 目標が達成可能
      • 大まかに全体像を把握
    • 大雑把に
      • 情報技術の進化により,まだ誰も経験していないことへの価値が上がる
      • ソースコードを段階的に読む
        • 内部構造を解説したdocument
        • directory構造
        • file構成
        • 略語を調査
        • data structure
        • 関数同士の呼び出し関係を把握
        • 関数
      • 民法の地図
        • 地図のように考えるというのは昔思ったことある
    • 片っ端から
      • 写経
      • 数学
        • 正確な積み上げが必要な場合
        • できるだけ効率化しながら,必要な部分を前から積み上げていく
      • 時間を区切る
        • 一定時間で評価する
      • 写経は補助輪
      • 写経しなければ分からないくらいであれば,新しい分野にチャレンジしていることが分かる
  • 抽象とは何か
    • 集めた情報からpatternを発見したり抽象化したりして,モデルが作られていくprocessを学ぶ
    • abstract
    • model
      • すべてのmodelは間違っている
      • modelの価値: 現実との一致度ではなく,modelの操作が現実を操作することに比べてどれくらい低コストになるか
    • module
      • 物理的なものづくりと違い,局在しない
      • 相互作用の制限
      • 重要でない部分を隠す=重要な部分を抜き出す
    • MVC
    • patternの発見
      • 具体的な事例を集めて,規則性や共通の特徴.繰り返し現れるものを見つける
      • グラフでの表現など
    • design_pattern
      • もともとは建築の分野から
    • patternの命名
      • 人間の知能を増強する方法
        • 人工物
        • 言語
          • 世界のmodeling
          • 生み出されつつある言語/制度化された言語
        • 方法論
        • 教育
    • なぜ抽象化が必要か
      • 問題間違えたときに答え読みながら考えることと同じ
        • 抽象化・一般化・汎用化された知識の獲得
      • patternの発見による一般化
      • 新しい知識を生み出すことと,哲学用語としての「帰納」の関係 → ポアンカレの『科学と仮説』 ← 読みたい
  • どうやって抽象化するか
    • 比較して学ぶ
      • 同じと違うの間に注目
        • 交換可能になっている部分に注目する
      • たとえ話
        • 伝えようとしている抽象的な概念と,それに似ている具体的なものとを,比較させて理解を促すtechnique
        • どこの部分が同じかが重要
      • 違いに注目
        • 違いに注目,一見矛盾していると見えるものについて考えてみる
        • 弁証法
        • 対立と対立の解消を繰り返す
    • 歴史から学ぶ
      • 今と昔の比較
      • 現在進行中のできごとについて,次に何が起こるか予測
      • 変更前と後でどう変わったか,なぜ変わったか
      • source_codeにはhowしかない
    • pattern本から学ぶ
      • 自分の言葉で説明できるか
      • 自分の経験に基づいた具体例を挙げられるか
      • 自分の目的を達成するためにその知識を使えるか
  • 検証
    • 作って検証
      • programmingはほかの分野より学びのcycleが速くなる
      • 解説を作ることも〇
    • 試験で検証
      • 変化が少ない分野,良い教科書が整備されている分野で〇
    • 検証の難しい分野
      • 繰り返し実験しやすく,実験結果に影響する環境要因をコントロールしやすい分野が検証しやすい
        • 科学,工学など
  • まとめ
    • 情報収集・モデル化・検証という学びのサイクルについて
    • アインシュタインの図式
      • →↓ 直接経験E(dataなど)
      • ↓ 公理(直感によって生まれる.パターンの発見.論理的に導かれたものではない)
      • ↓ 公理から具体的な主張が論理的に導かれる
      • ↑← 経験を通じた検証
        • whyは,comment, commit log, mailing listなどに書かれている

Ch02 やる気を出すには

  • Getting Things Done(GTD)
    • まず気になることをすべて集めるだけ
      • ToDoと違って判断しない
    • 集めると考えるの複数タスクを一緒にしないようにする
    • 処理
      • これは何か?行動を起こす必要があるか?を問う
      • 必要あり → どういう結果を求めているか?: ゴールの明確化
    • 次に取るべき具体的な行動
      • 行動を起こす必要のないものを,ゴミ・資料・保留の3つに分類する
      • 具体的な行動が複数 → projectにする
      • 具体的な行動が2分以内 → 今すぐやる
      • 具体的な行動をやるのが自分でない → 他人に任せて連絡待ちリストに入れる
      • 具体的な行動をやるのが特定の日時 → カレンダーに書く
      • どれにも当てはまらない → 次に取るべき行動のリストに入る
        • 上から1度に1件ずつ処理していく
    • 完了までに時間がかかるのが難点
    • 部屋の片づけと似ている
    • まず基地を作る
      • 領域を区切る
      • 片付いている領域を作る
      • 今日やることの整理に集中する
    • 緊急性分解理論
      • 質,量,納期,方法,代替,お金で解決,どうしようもないならやめる
  • 優先順位づけはそれ自体が難しいタスク ← 感覚的にわかるところが言語化されている
    • sortの計算量
    • 1次元でないと大小比較ができない
      • 単純に十分な方法論がないうえに,タスクごとの重要度が依存し合っていることもある
    • 不確定要素がある場合の大小関係
      • 悲観的な勘違い
      • 探索と利用のトレードオフ
        • 過去の経験からベストと思う行動ばかり → 探索不足
        • 未経験の行動ばかり → 過去の経験が活かせない
      • → 不確かなときは楽観的に
        • 気づきのチャンスがない分,悲観的な勘違いは影響が大きい
        • 不確かであることをポジティブに評価する項を足してから選択肢を比較
        • 楽観主義が後悔を最小化する
        • UCB: Upper Confidence Bound
          • 信頼区間の大きいほうの境界
          • 平均で判断するのではなく,ベストで判断する
        • ↑ 悲観的な勘違いで損失が確定するより,楽観的な勘違いでfeedbackを獲得しながらベストに近づける方が良いというようなこと
      • risk, value, priority
        • featureのpriority
          • value, cost
          • new knowledge, risk
          • value, riskが高いfeatureから実装し,次にvalueが高くてriskが低いfeatureを実装し,最後にvalueが低くriskも低いfeatureを実装する
            • valueが低くriskが高いものは実装しない
    • 重要事項を優先する
      • ③緊急だが重要でないものにNoといい,②緊急でないが重要なものに取り組む
      • 主体性が必要 ← ③は働きかけがあるが②は働きかけがないため
      • 境界が不明瞭
        • 通知は緊急ではない
          • まずは記録して自分のペースで実施する
      • 価値観はボトムアップ言語化する
        • 現在の行動 → 現在のproject → 注意を向けるべき分野・責任を負っていること → 1~2年後の目標 → 3~5年後の構想 → 人生の目的・価値観
        • GTDではまず現在の行動に集中して,そこから注意を向けるべき分野などを見つけていく
          • 注意を向ける分野が言語化されれば,下のprojectやactionにも影響を与え始める
      • 7つの習慣
        • 私的成功を支えるもの
          • 主体的である
          • 終わりを思い描くことから始める
          • 最優先事項を優先する
        • 公的成功を支えるもの
          • Win-Winを考える
          • 理解してから理解される
          • 相乗効果を発揮する
        • 刀を研ぐ
    • 優先順位を今決めようとしなくてよい
      • 順位をつけることが本質的に難しい
      • 日々の行動を行う中で,徐々に自分の価値観や人生の目的が明確になると考えました
        • 価値観などの軸が明確になると,その軸と照合して,各タスクの重要度が分かるようになる
        • これにより優先順位ができるようになる
      • 自分がどういうタスクが好きなのか,どうなるとうれしいのかを日々観察していくことで,事後的に優先順位づけができるようになる
  • 1つのタスクのやる気を出す
    • タスクが大きすぎる
    • timebox
      • 終了条件が明確でないものは時間で切るのがフィットする
      • 集中力の限界
      • 逃避を避けるために,時間を区切って,見えるところにゴールを設定するのが有用
      • pomodoro technique
        • 1 pomodoro: 25 min
        • 今日1日分のタスクリストを作る
        • タスクの大きさをpomodoroの個数で見積もる
        • もし自分または他人による割り込みが発生したらそれを記録する
        • 1 pomodoro集中した状態を継続出来たら,立ち上がって数歩歩くなどして視点を切り替える
        • 連続的なものとして捉えられがちな時間を,pomodoroの個数としてタスクの大きさを見積もる
      • 見積もり能力を鍛える
        • 1日にできるのは4~8 pomodoro程度
      • 分単位で見積もるタスクシュート時間術
        • 計測の重要性
        • 不要なタスクにpomodoroを与えない
        • column: PDCA_cycle
          • 重要なのはcycleを回して徐々に改善していく考え方
          • OODAもある
      • 計測し,退け,まとめる
        • Drucker
          • 仕事より計画よりまずは計測
        • programを高速化したくなったときは,まずはどこが遅いのかを詳細に計測するべき
        • 1 pomodoroの間はタスクの変更をせずに1つのことに集中する
  • まとめ
    • やる気が出ない状態をどうやって解決するかについて
    • 1つに絞る
    • タスクを小さくする
    • 計測する

Ch03 記憶を鍛えるには

  • 記憶の仕組み
    • カンデルという人の本より
    • 海馬
    • 記憶には2種類ある
      • 非陳述記憶
      • 抽象化
  • 記憶と筋肉の共通点
    • 信号を伝えるシナプス
      • シナプス後細胞の電位が変化する
      • 複数の細胞から短い時間の間に立て続けに信号が届くと,電位が大きくなる
        • 発火という
        • 先の細胞に信号を伝えられる
    • シナプスの長期補強
      • シナプス後細胞が発火すると,表面の受容体が増える
        • それ以降より少ない刺激でシナプス後細胞が発火するようになる: Long-term potentiation, LTP, 長期補強
          • 1回では2時間程度で元に戻る
          • 短い間隔で4回刺激すると,長期補強が28時間程度持続するようになる
          • 短いほうが前期長期補強,長いほうが後期長期補強
          • 後期長期補強では,受容体を作る量自体が増える ←→ 前期長期補強はあらかじめ作って細胞の中にためてあった受容体が細胞膜に設置される ← 受容体のストックが減るので長続きしない
            • 作る量が増えて長続き
    • まず消えやすい方法で作り,徐々に長持ちする方法に変える
      • 学習を繰り返すとシナプス自体も増える
      • まずは海馬に保管され,時間をかけて大脳皮質などに移動していく
      • 記憶は段階的に作られ,繰り返すことで徐々に長持ちする方法で保存されていく
      • 記憶の作成は,ファイルの保存というより筋肉のトレーニングに近い
  • 繰り返し使うことによって強くなる
    • 記憶をinputする銘記のフェーズと,記憶をoutputする想起のフェーズ
      • 両方必要
    • 繰り返し似た情報が入ってくると反応が鈍くなる性質
    • outputに対して報酬が得られるとなおよい
    • column: 海馬では時間が10倍に圧縮される
      • 具体的な記憶から抽象的な情報を作り出すプロセス
      • 遅く読みすぎると理解できなくなるのもこれ
  • outputが記憶を鍛える
    • testは記憶の手段
    • テストをしてからさらに学ぶ
    • 自信はないが成績は高い
      • 主観的な気持ちと客観的なテスト結果が逆になる
    • Adoptive_Boosting
      • 弱識別器を集めて,もっと正解率の高い識別器を作る方法
      • 間違えた問題を重視することが重要
      • 繰り返し学習で弱識別器を集めて集計して答えを出すことで正解できるようになる
    • テストの高速サイクル
  • 知識を長持ちさせる間隔反復法
    • 忘れてから復習する
      • テストまでの感覚が1日以上のときには,テストまでの感覚の1/10程度の時期に復習するのが良い
        • ただし,ピークの後はそれほど悪くならないので,後であればOK
    • ライトナーシステム
      • 間違えたものは短期,正解したものは長期で復習
      • SuperMemo
    • 問題のやさしさ
      • SuperMemoの学習感覚決定algorithmは,SM-2 algorithmと呼ばれた
      • そのなかにやさしさ係数がある
    • 知識を構造化する20のルール
      • 最小情報原則
        • 問題はできるだけシンプルに
          • 半端な結果が出ない
      • 順序の定まらない集合を覚えようとしない
      • 複数のものの並びを覚えようとしない
      • 穴埋め問題は覚えやすく効率的
    • Anki
      • 学習フェーズと復習フェーズ
      • 隙間時間で細切れに学習する場合に〇
    • 難易度の自動調節
      • 適度なチャレンジのときのみ,高い集中力を発揮するフロー状態になる
        • そうでないときは,不安か退屈が勝ってしまう
      • 間隔反復法では,難しい場合に対処できない
        • → 自動保留
        • 保留の解除は,干渉を見つけて取り除くようにする
    • column: 知識を構造化する残り15のルール
    • 教材は自分で作る
      • 作る過程で理解が深まる
        • 覚える前にまず理解
        • 認知的に高度な作業をした方が記憶にとどまる
      • 個人的な情報を利用できる
        • 自分の記憶・体験・感情と関連付ける
      • 著作権と私的使用のための複製
  • まとめ
    • 記憶について
    • 海馬が長期記憶にも使われている
    • 繰り返しが必要
    • 単に繰り返すよりtestが〇
      • 主観的な自信はなくなるが,客観的な成果は高くなる
    • テストの繰り返し間隔や難易度を自動調整するしくみが実現されてきている

Ch04 効率的に読むには

  • 読むとは何か?
    • 本を読むことの目的
      • 娯楽はスコープ外
      • 情報を得ることが目的か?
      • 情報伝達の歴史
      • 一次元の情報を脳内で組み立てる
      • 本の内容だけが組み立てる材料ではない
        • 自分の脳内のモデルと合わせて理解を構築する
      • 見つけると組み立てるのグラデーション
        • 味見するだけでよいか,よく噛んで消化する必要があるか,丸のみするか
    • 読むの種類と速度
  • 自分の普段の読む速度は?
    • 読む速度のピラミッド
      • 声に出して読む速度
        • 1冊15時間
      • 視覚の限界速度
        • 1冊30秒
    • 頭の理解速度がボトルネック
      • 組み立てる時間
    • 速読の苦しみ
      • 理解速度がボトルネックなら,入力速度が上がっても意味がない
        • 主観的には頑張って速読したけど,理解にはなっていないとなって苦しくなる
      • 続けられるペースを把握する
        • 自分の認知能力ではこの速度が限界だという現実を認める
        • 長く続けることで徐々に体力がつき,ペースが上がっていく
    • 読まない
      • 読まずに知識を手に入れる
        • 読む前に知識を取得する
  • 1ページ2秒以下の見つける読み方
    • 準備の大事さ,段階的詳細化,繰り返し読むこと
    • Whole Mind System
      • 準備
        • 目的の明確化とリラックス
      • preview
        • 5 min 程度
        • 大雑把に全体像を把握
        • 調査
        • keyword探し
          • 20 pageごとに開いて目についたkeywordをメモする
        • 読むべきか,目的を修正すべきか考える
      • photo reading
        • 目のフォーカスをぼかして,ページ全体を眺める
        • 見開きを1~2秒で読む
        • 賛否が分かれるところ
        • 効果ないこともある
      • 質問を作る
        • 目的を具体化していくための情報を集めて,事後的に目的を詳細化する
      • 熟成させる
        • 少なくとも10~20分,可能なら一晩時間を置く
      • 答えを探す
      • mind mapを作る
      • 高速reading
        • 通読
      • 5日間トレーニン
    • focus reading
      • 仕入れ→加工→販売
      • 本の著者の力読み手の経験値読み手のビジネス力
      • 速度を計測しコントロールする
        • 得たい理解度に合わせて速度をコントロール
    • 見出しなどへの注目
      • 先行オーガナイザ
      • 本文より見出しの方が書く上でコストがかかっている
      • title, sub titleは商業上の理由が大きいので,参考にしない
      • 図は注目に値する
        • cost 大
      • 箇条書きも〇
      • 脚注とコラムは最初は読まない
    • column: 時間軸方向の読み方
      • 同じ著者が似たテーマを繰り返し書いているときなど
      • 何が一時の思い付きなのか分かる
  • 1ページ3分以上の組み立てる読み方
    • 哲学書の読み方
      • 開いている本
        • 著者が自分の意見を言っていない本
        • 読者が自分で考える本
      • 閉じている本
        • 著者が自分の結論を持っており,そこへ向けて論を進める本
      • 外部参照が必要な本
        • 前提知識
      • 登山型の本
        • 概念積み上げ
        • 手順をおろそかにすると後で困る
      • ハイキング型の本
        • 色々な概念を次々と
        • 山の頂上に到達するのが目的ではなく,景色を楽しむことが主眼
    • 1冊に40時間かけて読む
      • 予備調査と選書に3時間
      • 通読に4時間
      • 詳細読みに10時間
      • +方法論自体の習熟コスト
      • 棚を見る
        • 本を選ぶ方法
        • 分野の棚の本を全部見る(気になるものがあれば目次も見る)
        • ↑を繰り返す(可能なら複数の書店で)
        • 分野の全体像をスケッチしてみる
        • 易しい本ではなく,自分の興味のある本を選ぶべき
          • motivation維持のため
      • 読書ノートに書きながら読む
        • 読みたいときに読みたいところから読む
        • 全体の分量を1章10ページなどと先に決め,章の小見出しを先に記入していく
        • わからないことは何でも記録する
        • 何度も出現する単語を記録する
        • 概念の間の関係や理由と結論の関係などを矢印でつなぐ
      • わからないことを解消するために読む
        • わからないの理由
          • 用語の理解が不十分
          • 論理の筋道の理解が不十分
          • 問題意識の理解が不十分
          • 図解する必要がある
    • 数学書の読み方
      • 1回のゼミの準備に50時間かかるのは不思議ではない
      • 数学所は登山型の本が多い
      • ここは絶対大丈夫というのを少しずつでも増やしていく感じ
      • 全体像を理解することと,定義を理解することの違い
      • 厳密な議論が必要
      • わかるの定義
        • なぜそうなのかという質問に答えられること
      • わかることは必要か
  • 読むというタスクの設計
    • 理解は不確実タスク
      • 挑戦の量で測る
        • 冊数や時間など
    • 読書は手段,目的は別
      • 大雑把な地図の入手
      • 結合を起こす
      • 思考の道具を手に入れる
        • 経験によって得た名前のついていない概念や考え方に,本を読むことで名前が付くことがある
        • 概念の名前が分かれば,概念の検索ができ,関連知識を入手しやすくなる
        • 言葉を手に入れて,言葉によって思考ができるようになる
    • 復習のための教材を作る
      • 読書の目的として,復習のための教材を作ることとするのがおすすめ
        • 記憶を定着させるためには間隔を空けて繰り返すことが大事
        • 繰り返しのために重要
      • leverege_memo(lever: 梃子)を作る
        • 書籍の中で重要な部分を抜き出し,濃縮してleverege_memoを作る
        • problem
          • 文脈から切り離されてしまう
          • 量が増える一方である
      • incremental reading
        • 問題反復法のシステムを流用
        • 明示的に捨てる決心をする必要がない
          • 必要になったら検索して見つけれられる
        • 繰り返し提示されて抜き書きを作っていくことで,価値のあると感じる情報の抜き書きが徐々に増える
        • 複数の情報源からの情報が混ざってランダムな順番で提示されることで,知識との結合が促進
        • 発展途上
          • これ以上編集不要なものの扱い
      • 人に教える
  • まとめ
    • 知識が入ってくるプロセスについて
    • 特に文章を読むことにフォーカスし,情報を見つけることと,理解を組み立てることのグラデーションを見た
    • 語られなかったが有益なプロセス: 会話,実験
      • 実験: 新しく知識を作り出す効果

Ch05 考えをまとめるには

  • 情報の整理とアイデアを生み出すことは,連続的なグラデーション
  • 情報が多すぎる?少なすぎる?
    • 書き出し法で情報量を確認
      • 5分間,言及するとよさそうな情報を思いつく限り書き出してみる
      • KJ法のために,書いたものを容易に移動できることが必要
      • 質を求めてはいけない
      • 実践してみる
      • 100枚を目標にする
        • merit
          • 進捗が明確に計測できる
          • 中断が容易
      • 重複は気にしない
        • 重複は重要度の指標として重要
  • 多すぎる情報をどうまとめるか
    • 並べて一貫性を高める
      • 視線の移動だけで脳に戻すことができるようになる
      • 中心は作業領域としてゆとりをもたせる
      • column: 書き出し法の実例
    • 並べる過程で思い出したらすぐ記録
    • 関係のありそうなものを近くに移動
      • 川喜田二郎の『発想法』から → イニシャルよりKJ法
      • KJ法の流れ
        • 探検
          • KJ法の前の情報収集
            • 内部探検,外部探検(フィールドワークなど)
        • 繰り返し実行
          • labeling
          • grouping
            • ラベル拡げ
              • 並べて一覧化
            • ラベル集め
              • 関係のありそうなものを近くに移動
            • 表札作り
          • A型図解化
            • 空間的に配置
          • B型文章化
            • 文章化
        • 断片の集合から図解へ,図解から文章へとフォーマットを変えていくことで,視点を変え,見落としに気づく
    • column: ふせんのサイズ: 50mm×38mm
    • groupingには発想の転換が必要
      • groupingは客観的ではない
        • 客観的に正しいというものはないという話
      • groupingは階層的分類ではない
      • 既存の分類基準を使うデメリット
        • KJ法によって得られる構造が,既存の構造と同じものになってしまう
          • KJ法の意味がない
      • column: frameworkによる効率化
        • 変化が不要な状況でのみframeworkは有用
      • 事前に分類基準を作るデメリット
        • 全体像を把握できていない状態で事前に作った分類基準は,高い確率で間違っている
        • 盲点に気づき,既存の思い込みの枠を壊すことが重要
          • 既存の枠を手放すこと自体が難しいので,そもそも持たないことが大事
        • 具体的な情報が主体で,どう構造化するかという主観的な解釈は,具体的な情報に従属する
      • 分類で負担を減らすメリット
    • 関係とは何か
      • 類似だけが関係ではない
      • NM法は対立関係に着目する
        • 対立の解消に役立つかもしれない仮説を立てることを目指す
      • 話題がつながる関係
        • KJ法のgroupをプレゼンテーションのスライドにたとえる
        • 話がつながるのが良いgrouping
        • つなぐstoryを考えることで新しい情報が生み出されることもある
    • 束ねて表札をつけ,圧縮していく
      • 表札作りのメリット・デメリット
        • merit
          • 見かけの枚数の削減
        • demerit
          • 束ねたものの中身を見るのに手間
      • 表札を作れるgroupが良いgroup
        • groupingの段階で分類をしないことが必要
      • ふせんが膨大なときの表札作り
        • まず具体的な情報を用意し,それを集め,その上に表札を置いていく
      • 「考えがまとまらない」と「部屋が片付かない」
        • 情報デザイン: 情報を,人が効率的かつ効果的に使えるような形で準備する技法
        • 片づけのテクニック
          • 収納場所に先に分類ラベルを貼らない
      • column: 表札とふせんの色
        • 一度に書き出した内容が同じ色である確率が高くなるという点がメリットになる
      • column: 知識の整合性
        • 正しさの保証: より多くのものと整合していること
          • 応用範囲が広いため
        • KJ法にて,関係がありそうと感じたものをgroupingし,それに表札をつける
          • → 整合しそうな知識を組み合わせ,なぜ整合するのか言語化していく作業がある
          • これを繰り返すことで,知識間の整合性が増していき,知識のネットワークが構築される
    • 束ねたふせんをまた広げる
      • 関係がある者が近い位置になるように空間的配置され,囲みや矢印が加筆された図解ができる
    • 文章化してoutput
      • format変換作業が有益
        • あいまいなつながりに気づける
  • 社会人向けチューニング
    • stepの省略
      • 表札作りや図解化は省略する
    • 中断可能な設計
    • A4書類の整理法
      • 押し出しファイリング
      • クリアファイル整理法
        • 探したいものの番号はデータの中で検索
  • 繰り返していくことが大事
    • KJ法は認知的に高度な処理であり,それを繰り返すことで,効率よく記憶を作ることができる
    • KJ法を繰り返す
      • よく耕された畑のようになる
      • よく整理された文房具棚
    • 繰り返しのtrigger
      • 言及されたときに,再度読み返してみて,少し再構成したいというときに,再度KJ法を使う
    • incrementalな改善
      • 締め切りがある場合にはフィットしないこともあるが,長期的に自分を鍛えるためには使える
    • 過去の出力を再度grouping
      • 基本は再度書き出し法から実施する
      • 電子化が必要
    • 電子化
      • 画面サイズは140cm×80cmくらいあればできそう
      • 共同編集は不要
  • まとめ
    • 考えがまとまらないという悩みの解決のために,まず書き出して十分な情報があるか確認し,それから書き出したものを机の上で物理的にまとめていく方法を見た
    • 知的生産の重要なプロセス
      • 書き出してから考える
      • 描いたものをボトムアップでgrouping
      • グループをうまく要約した表札をつける
    • 特にボトムアップにgroupingが重要な原理原則を強調

Ch06 アイデアを思いつくには

  • 「ideaを思いつく」はあいまいで大きなタスク
    • 分解して,計測や管理可能なフェーズとする
    • ideaを思いつく3フェーズ
      • 耕すフェーズ
        • 情報を集め,かき混ぜ,つながりを見出そうとするフェーズ
      • 芽生えるフェーズ
        • 管理できない
        • 情報を寝かせて,ideaが芽生えるのを待つ
        • 締め切りがあれば,time limitまでに芽生えたもので残りのフェーズを進める
      • 育てるフェーズ
        • 生まれたideaを磨き上げていくフェーズ
        • 有用かどうか実験によって検証し,修正していく
    • 先人の発想法
      • Youngのideaの作り方
        • ①資料集め
        • ②資料の加工
        • ③努力の放棄
        • ④ideaの誕生
        • ⑤ideaのcheck
        • ①と②はまとめて耕すフェーズ
        • ③と④は芽生えるフェーズ
          • 芽生えさせるのではない
        • ⑤が育てるフェーズ
      • 川喜田二郎の発想法
        • W型問題解決モデル
        • 実験科学の前に野外科学が必要
        • 野外科学
          • 問題提起,探検,観察,発想,仮説の採択
          • 探検学やKJ法を使用
          • 観察で情報収集,発想でKJ法を使ってまとめて仮説を思いつく
        • 実験科学
          • 推論,実験計画,観察,検証
      • Scharmerの変化のパターン
        • U理論
        • U曲線モデル
          • level 1(4つの意識状態: level)
            • Downloading
              • 思い込みにとらわれて外界を観察していない状態
            • Performing
              • ideaが既存のシステムに組み込まれ,機能している状態
          • Voice of Judgement
          • level 2
            • Seeing
              • 外界を観察しているが,自分の既存の枠にしがみついて,他者の視点から情報を感じ取れていない状態
            • Prototyping
              • prototypeが作られた状態
          • Voice of Cynicism
          • level 3
            • Sensing
              • 他者の視点から情報を感じ取り,自分の既存の枠が壊れたが,「自分」を手放していない状態
            • Crystallizing
              • ideaが結晶化された状態
          • Voice of Fear
          • level 4
            • Presensing
              • 「自分」を手放し,未来の変化の可能性を見ている状態
      • 芽生えは管理できない
        • 運しだい
        • 芽生えなかった時のリスクの管理
        • 耕すことに時間を使う
        • 育てる時間を確保する
        • 管理できるところは管理し,できないものは管理しないのが,いいアイデアを生むための最大限の努力
  • まずは情報を収集する
    • 自分の中の探検
      • 特殊資料 ←→ 一般的資料
        • 今解決したい問題について特化した資料
        • 自分の身近な問題の解決には,主観的な考えも確認する必要
    • 言語化を促す方法
      • 自分の中から情報を引き出すために
      • 質問によるtrigger
        • framework
          • 質問の束
          • merit
            • 盲点を埋めることに有益
          • demerit
            • framework自体が既存の固定化した思考の枠
          • 枠に収まらない情報こそ生産において重要なこともある
          • 適切なタイミングで少しだけ使えば有効だが,乱用し継続的に使い続けると有害になる
          • 探索と利用のバランスが重要
      • 創造は主観的
        • 客観的に説明できることを制約条件としてしまうと,すでにあるものから遠からぬものとなってしまう
        • 耕し,芽生えを待つフェーズでは主観的に考える必要がある
    • 身体感覚
      • ファインマン,科学とは何か
      • 抽象概念を身体感覚に近づける必要
      • 絵に描いてみる
    • たとえ話,メタファー,アナロジー
      • 抽象概念が現実に形を持たないため
      • 遠い分野のアナロジーが使われたときに,製品の新規性が高まるという調査
      • NM法とアナロジー
        • 課題からkeywordを選ぶ
        • keywordを別の空間(メタファーの空間)に対応付ける(アナロジー
        • メタファーの空間で連想する
        • 連想したものを課題の空間に引き戻す
        • e.g. vector複素数の対応付け
      • Clean Language, Symbolic Modelling
        • 相手からメタファーを引き出すことを目的とした方法論
        • 前提を含まない質問
          • どんな種類?ほかには?どこにある?どのあたりにある?何のよう?
        • → symbolの生成
        • symbolの時間軸上での変化やsymbolの間の関係を明確化していくことでsymbolを使って作られたモデルができる
        • symbolの時間軸上での変化を明らかにする質問
          • それから何が起こる?
          • 次に何が起こる?
          • そのすぐ前には何が起きる?
          • それはどこから来る?
        • symbolの関係を明らかにしていく質問
          • XとYはどういう関係?
          • XとYは同じ?違う?
          • XとYの間には何がある?
          • (Xが出来事のとき)Xが起きたとき,Yには何が起こる?
    • まだ言葉になっていないもの
      • 暗黙知: 解決に近づいている感覚
        • 独創的な発見がいかにして起こるのかの考察が背景
        • 効率よく新しいものを生み出すために,暗黙知が役立っているという考え
          • 人間は問題の解決に近づいているか近づいていないか感じることができる
        • column: 2種類の暗黙知
          • tacit knowing/ tacit knowledge
      • 違和感は重要な兆候
        • 違和感: 問題の解決から遠ざかっている感覚
      • Thinking At the Edge: まだ言葉にならないところ
        • 違和感に注目して言語化を進めていく
        • フェルトセンス: まだうまく言葉にできていない,しかし重要だと感じる,身体的な感覚
      • 辞書との照合
      • 公共の言葉と私的な言葉
        • 公共の言葉にするために辞書
      • KJ法も違和感に注目
        • 分類をしてはいけない理由
        • ここに並べた理由は何かという問いに既存の分類を答えてしまうと,言語化されていないものを言語化する効果を発揮できない
        • これがKJ法の一番重要な部分
    • 言語化のまとめ
      • 情報を収集する方法の一環として,自分や他人の中にすでに存在する情報をどうやって取り出すのかについて重点をおいて解説
      • 身体感覚や経験,違和感に注目することが大事
        • まだ言葉になっていない
        • まず自分の中から私的な言語でもいいので取り出す
        • そのあとに人に伝わる形に改善すればよい
        • 言語から身体感覚が外れている場合は,取り戻す
      • 自分の中のまだ言語化されていないものと,きちんとつながった言語化されたものを作ることが目的
  • 磨き上げる
    • 最小限の実現可能な製品(Minimum Viable Product: MVP)
      • 構築・計測・学習のループを回してすばやく学習することが大事
      • 誰が顧客かわからなければ何が品質かもわからない
      • 何を検証すべきかは目的によって異なる
    • U曲線を登る
      • Crystallizing
        • 漠然と思っていたことや不完全なideaが,書き出したり加工したり人に話したりすることで徐々に明確な形になっていく
      • Prototyping
        • 早い段階で問題に気づく
      • Performing
        • できあがったものを,より上位のシステムに埋め込みつつある状態
      • サイクルを回して何度も登る
    • 他人の視点が大事
    • 誰からでも学ぶことができる
      • それぞれ分野が異なる
      • 相手がどう感じているのかの言語化を促し,それを吸収する
    • time machineを作れ
      • 相手の私的な言語を,質問を通じて理解する
    • column: 知識の分布図
      • 知識分野は独立しておらず,固定的でもない
      • → 滑らかにつながった,閉じた円環でないものを使って表す
    • 再び耕す
      • 十分に他人の視点からの情報収集ができた後
      • 1つは,改善
      • もう1つは,idea自体を作り直すapproach
    • column: 書籍とは双方向のcommunicationができない
      • KJ法で対応する
        • 著者エミュレータの作成
          • 本に書かれていない質問に答えられるかどうかで検証 モデル化
  • まとめ
    • ideaが生み出されるprocess, 知的生産の「生産」に直結する部分を掘り下げ
    • 学ぶことは,自分の外のものを自分の中に取り込むこと
    • ideaを生み出すことは,自分の中のものを外に出すこと
    • 学びとideaの創造は,逆向きのことではなく,ほぼ同じこと
      • 耕すフェーズは情報収集,育てるフェーズは検証と密に関連
      • ideaが芽生える瞬間に起きることは,新しい結合であり,異なる者の間の関連の発見であり,パターンの発見であり,モデル化であり,抽象化
    • まだ言語化されていないものを言語化する方法について掘り下げ
      • 最初から客観的であろうとしたり正しくあろうとしたりする気持ちは,新しいものを生み出すことの障害になる
      • まずは主観的な違和感や身体感覚,個人的なメタファーを駆使して,誰も見たことのないものを手繰り寄せる
        • 磨き上げるのはそのあと
    • KJ法は,仮説を生み出す知的生産の方法でもある
      • 客観的に分類するのではなく主観的に結合を見出していくことが,新しいものを生み出すために必要
      • KJ法は,情報を耕し,芽生えやすい環境を整える,有用な手法
    • 磨き上げる手法
      • MVP
      • 小さく実験して,徐々に改善

Ch07 何を学ぶかを決めるには

  • 何を学ぶのが正しいか?
    • 数学の正しさ
      • 公理が正しいと仮定したときに,公理の組み合わせによって論理的に導かれたもの
    • 科学と数学の正しさの違い
      • 科学では,何度も実験して確認されたことは正しい
      • 数学では,何度も実験して確認しても,それが正しいことは保証されない
      • 科学では,実験で否定されていない主張は仮に正しいものとする
        • 主張を支持する結果が観測されればされるほど,その主張は信頼性が高まる
    • 意思決定の正しさ
      • 繰り返す科学実験と一回性の意思決定
        • 意思決定に繰り返しは使えないことも多い
      • 事後的に決まる有用性
        • 有用性が1つの基準だが,事前には決まらない
      • 過去を振り返って点をつなぐ
        • 将来何らかの形で点がつながると信じて行動するしかない
        • 何が有用かは事後的にしか分からない
        • 何を学びたいかの答えを外に見つけても見つからない
  • 自分経営戦略
    • 経営戦略のアナロジー
    • 学びたい対象を探す探索戦略
      • 自分の内面の「熱意が湧いてくるかどうか」に着目した戦略
      • 何かを学ぶことで学ぶ力が培われ,別の分野の学びの効率も高められる
      • column: 選択肢の数が意思決定の質にもたらす影響
        • 二択より三択の方が16.7倍も良い結果
      • 探索範囲を広くする
        • 目についたもの,少しでも興味の湧いたものを片っ端から学んでみる
        • 特に大学生向け
        • 盲点の発見に他人の視点
        • 違和感があったら無理に続けなくてもいい
    • 知識を利用して拡大再生産戦略
      • 自分の外側に注目
      • ポジショニング学派: 自分が置かれている状況をポジションにたとえて,周囲の状況を分析し有利な場所を占めようとする戦略
      • 社会人は,まず「今やっている仕事の効率化」を学び,時間の余裕を作り,その余裕を新たな学びに投資する
      • ↑ 知識の拡大再生産戦略
        • 拡大再生産: 企業が利益を上げたときに,その利益を生産設備などに投資し,その設備を使ってさらに利益を上げる
      • 知識を使って時間を得て,その時間を知識獲得に投資する
      • 知識を使ってお金を得て,そのお金を知識獲得に投資する
      • 知識を使って立場を得て,その立場を使って知識獲得をする
    • 卓越を目指す差別化戦略
      • 他人からの知識の獲得はコストが安い
        • Vanhoucke @Google
          • 何かに詰まったとき,まず自分で15分解決を試みる.15分経ったらほかの人に助けを求める
      • 他人から得た知識は価値が低い
        • 立場から選択肢が生まれ,生産のための取捨選択ができるようになる
        • → 他者の部分集合になるのは損
      • 卓越性の追求
        • 知識を価値につなげていくには,その知識分野に最も詳しい人になる
        • まず最優先で卓越し,それによって成長の機会を得る
        • 差別化戦略
    • かけ合わせによる差別化戦略
      • ある領域で1番でなくても,ほかの領域とかけ合わせて1番になればOK
      • ふたこぶの知識
        • communication〇
        • T(またはπ)型人材
      • 連続スペシャリスト
        • 1つ目の専門性によって卓越の立場を作り,その立場から収穫を得て,それを2つ目の専門性の獲得に投資する
        • 拡大再生産戦略と卓越を目指す戦略の融合
      • 新入社員の戦略案
        • 会社で得る知識Xとは異なる,新しい分野Yを見つける
        • → その分野で卓越
    • 組織の境界をまたぐ知識の貿易商戦略
      • 知識の流れの滞り
        • この流れの円滑化はしばしば経済的な価値を伴う
        • → 複数の組織をまたぎ,組織間の情報流通を起こすことで価値を生む戦略が成立
      • 知識とその需要が自分に集中するようになる
      • 知識は複製できるので,知識が自分の中を流れるようにすると,知識の複製が自分の中に蓄積され,自分の価値を徐々に高めていく
      • いくつかの方法
        • 積極的に外部の情報源に触れる方法や,社内で学んだことを社外に伝える方法,複数の組織に所属する方法など
      • 相互に教え合って相互に得をする形が〇
        • outputのみの状況にならずに済む
  • 知識を創造する
    • 外の知識を取り込んでも,差別化につながりにくい
    • 実際の応用の現場で必要に応じて生み出された知識は,流通しておらず,現場の状況にフィットした価値の高い知識
      • → 新しい知識を生み出す力が,価値の源泉

心的な負傷からの回復・ケアについて

目的・動機

  • 個人的には,過去の不快な出来事について,過去のこととなったにもかかわらず思い出されてしまうことをなくしたい
  • 「傷つかないようにするために」というテーマの文献は(質を問わなければ)多く出てくるが,一方で「傷ついた後の回復」について考えられた文献がなかなか出てこない.情報を整理したい
    • この情報の偏りそのものも,けっこうストレスに感じることが多い.それも解消したい
      • 「傷ついた後の回復」について理解することで,偏りを回避できる検索方法の理解もついでに期待できると思う
  • おそらくはこういった人の目に届く情報の偏りが故と思うが,傷ついた後の人に対して「その出来事についてあなたは恐怖を感じるべきではなかった(または別の捉え方があったんじゃないの)」みたいな的外れなことを言っているのを,見たり聞いたりしてしまうことがある.そのときに,それは違うのだと,明確に棄却できる状態でありたい(必要なら説明したり文献を紹介したりできるようにする)
    • 以下に示す文献にもあるが,重要なのはその出来事をどう捉えるべきだったかではなく,その出来事とは関係がない/関係が薄いことまで恐怖に感じてしまう状況を改善することにある(過去の出来事そのものと想起した記憶は異なるなど)
    • なぜその出来事に恐怖を感じたかは最終的には理解することになるが,それは加害者の視点での理解では断じてなく,被害者の視点での理解・整理
      • 傷ついた側に,傷つけた側の考え・視点を押し付けようとして傷をえぐるのは,本当に酷いこと

調査内容

  • ハラスメント被害者の心理的回復について,小西聖子先生の講演内容が文献となっていたので,まずはそれを元に心理的回復について概観を見た
  • 上の文献で,治療法が紹介されていた.特に使われているというPE法について,概要の記載がある文献を閲読した

概要

  • 恐怖条件付けの再学習が必要
  • 過去の出来事そのものと記憶の想起が異なるものだということを理解する
    • 過去の出来事とは異なり,振り返りは実際にその時脅かされるわけではない
  • まずは症状を安定させる
    • 今の状況の理解,薬物治療など
  • 準備が整ったら,トラウマ記憶を整理して,恐怖条件の再学習をする
    • 症状が安定しているという前提の上で,今の(過去の出来事とは異なる)出来事や振り返りについて,回避をしないようにしていく
  • 回復の目安
    • 未来のことも,どういう行動をしたら何が起こるか,加害者と遭遇する可能性があるか考えられる
      • 確率が低いこと,遭遇したらどうすればいいか,そういうことを考えることがとても大事
    • 心配するのではなく考えるということが回復につながる
    • 過去のその記憶の時点にしか生きていない状態から外れて,ゆっくり考えることができることが,臨床的な回復の目安
  • 加害の視点で捉えてはいけない
  • ハラスメントは,アサーティブに対応するなどして回避できるものではない(被害者には選択の余地がない)
    • 構造的な問題は上が解決するしかない

考察

  • 被害者の視点での,過去の出来事,認知の整理が必要
  • 加害者の視点から話されているものが多い
    • それらは決して被害者の助けにはならない
  • 段階を踏む必要があることを,いきなりやってしまうようなケースは避けるべき
    • 状態を理解したうえで,状態に合わせて対応する必要がある
  • 過去の出来事そのものと記憶の想起が異なると理解することは,本当に重要
    • 想起では実際にそのとき害される恐れはない
  • 善意があってもリソースがないときは,良い治療者を紹介するのがよい
    • かじった程度の知識で対応できる問題ではなかなかない
    • ただし,適切な対応ができない治療者も多くいると思われるので,紹介するなら選定は慎重にする必要がある

課題

  • 被引用文献など関係する文献を探す
  • 病理の理解
    • biologicalな説明
    • 学習心理学的な側面からの恐怖条件付け
  • リラックスの方法とか呼吸を整える方法とか具体的な方法を見る
  • PE法のワークブックとか実践的な部分を学ぶ

参考文献

ハラスメント被害者の心理的回復

  • ハラスメント被害の問題は,その後に職場に復帰する,あるいは精神的痛手から回復するというところまで視野に入れる必要
    • しかし,この点が軽んじられていたり,また非常に難しい問題でもある
    • 医学的,臨床心理学的な背景から事後的な回復に焦点を当てる
  • 小西先生の立場
    • 被害者学的には,被害者の心理的ケア
    • 医学的心理学的には,PTSD治療
    • 特に性暴力の被害,DVの被害,虐待の被害,それらがかかわる犯罪の被害などを扱うことが多い
    • 被害者の臨床的な回復の支援
    • 支援・治療・鑑定という,それぞれ視点の違う支援・ケアをされている
  • 臨床側からでしか明確に見えてこない2点
    • Point 1. 暴力の心理的影響は,加害者や第三者としての周囲が考えるよりも,ずっと大きいことが多い
      • 共感性の不足は,特別の人にだけ生じるわけではない
      • 非対称性が,被害と加害の中には本質的に含まれている
      • 被害を受けた人がどういう風に感じていて,どういうところに苦痛を感じているかに共感していくことは,技量が必要ということを知る必要がある
      • トラウマの分野では,予期せぬ突然の出来事というのは,すごく悪影響を与える
        • トラウマとしての大きさのインパクトを増す
      • 被害者には選択肢もなく,予期もできないという点で,対称でない
    • Point 2. 被害からの回復には周囲が想像するより長い時間がかかる
      • 加害行為が止まれば終わるものではない
      • 骨折のimage
        • 外からの力が,衝撃が心にかかって負担となる
        • 治療の仕方が良くないと,元と同じ機能は持てないこともある
        • supportが必要
      • 二次被害(その後のストレス)
      • 多くの人が学校や会社にいけなくなっている
      • 年単位の回復経過となる
      • 症状
        • 振り返れない,話せない,検討などましてできない
        • 交渉や,相手に意見が伝わることが怖くなる
        • 身体症状や感情のコントロールが悪くなる
        • 感情が麻痺
          • 合理的に思考している部分と,恐怖で考えることのできない部分が共存する
        • 精神医学的に診断をつけるなら,トラウマおよびストレス関連疾患と診断することが多い
        • 診断はつかないけれども苦痛はあるという人もいる
        • こういった複雑さが被害者の回復を見えにくくしている
    • 臨床の専門家としての支援の2つの柱
      • ハラスメントの構造を見極め,相談者の人権を守る.自己決定を尊重し,職場との対応や裁判に可能な範囲で協力する
        • 被害者の何が苦痛を与えているのか,あるいは,どういうところで引っかかっているのかということを理解する必要
        • 何をしたいのか,どういうふうにやりたいのかを知る必要
      • トラウマ/ストレスによって生じた心理的反応(時には診断名のつく障害)を軽減し治療し,日常の生活を取り戻す
    • 事例1.セクシャルハラスメント
      • 最初は,本人の感情や経験,時にはそれを感じないこととか覚えていないこと,を批判せずによく聞く
        • ここのところで治療者が平気で批判したりして医者からの二次被害になることもある
        • 多くの人の場合,自責感が強い
          • 誤解の多いところ
          • 被害を訴えていても,こういう体験をした人の多くが合理的とは言えない自責感を強く感じている
        • 表面だけではないリアルな状況に本当に理解し共感をすることが必要
          • 知識が必要
      • PTSDについて(例)
        • トラウマ記憶や,それを思い出させるものへの回避が非常に強かった
          • flashback, 事件のことがそのまま頭によみがえってきて,非常に苦痛
          • 恥辱感や無力感が強く思い出されて苦痛なため,それを回避する傾向が強くなっていた
        • 侵入症状,回避症状,認知や感情のネガティブな変化,覚醒の亢進というだいたいこの4つが症状
          • 1か月以上持続する
          • これらに,トラウマ体験と,重要な機能が障害されているという条件で,PTSDと診断される
        • トラウマのreminderの回避のために日常生活が困難
          • たいがいは電車に乗ることができなくなる
          • 道を1人で歩くことが怖くなる
          • 電話ができなくなる
        • 合理的でない自責の念
        • 訴えたことにより相手から攻撃的な感情を向けられることの恐怖
        • 侵入
          • 記憶が勝手に向こうから,自分の意思と関係なく繰り返しよみがえってくるというような症状
            • かなり苦痛を伴う
              • 身体的反応が起きたり,心理的な反応が起こる
        • 回避
          • 考えない,刺激のそばによらない
            • 日常生活を困難にする
        • 覚醒
          • いつも緊張
          • 不眠,ちょっとした物音にすごく驚いたりというような状態
        • 自責感,自分を壊したいというような行動,いらだちなど
      • ケアの方法
        • まずは症状の安定化
          • 心理教育でよく使う言葉,今その人がどういう状態にあるかを話す
          • 薬物治療
          • relaxationの方法の教授
          • まだトラウマに切り込むことはできない
            • 少しずつ今の状況を整理していく
          • 共感的でない人にかかると,都合のいいとこだけ怠けてるんじゃないのというようなことを言われかねない状況
            • 自分でもちゃんと復帰したいんだけどできないのだっていうことを,ちゃんとわかる,理解するということがとても大事
          • このようなことで,だんだんと自分の症状を理解して話せるようになる
        • PTSDだということが理解されてきたところで,PTSD認知行動療法を入れる
          • トラウマ記憶を整理し直して,恐怖条件付けを消去というか正確には再学習する
          • PTSDの病理がどういうふうに発生するのかの説明の仕方
            • biologicalな説明もあるし,けっこう有力な説明としても,学習心理学的な側面からの恐怖条件付けのことで説明していく方法がある
            • PTSD認知行動療法,特に行動療法を中心にするものは,こういう仮説でやっている
          • 繰り返して話すことで,ある程度自分の過去について,振り返ることができるようになった
            • ここでやっと,話せる傷ついた人というスタートラインに立ったと言える
            • 治療を始めるまでに早くても半年程度,ここまでの治療に4か月程度ですでに1年近く経過
        • 出来事が考えられると,次は裁判に出ていく
          • 診断書が必要になったり,相手の出してきた意見というのを読んだり,それについて反論しなくてはいけないことも多く,被害者にはとてもとても大変な作業
          • 相手に罰を与えるためには裁判くらいしかないので,どういうふうなことができるようにならなくちゃいけないかを話し合い,準備することもある
          • 裁判への心理的な対応も必要になる
        • 事件後2年ほどたった頃に,外出や被害に関係あるところから少し離れた場所に行けるようになった
          • 過去のことについて考えられるようになり,アルバイトもできるようになった
        • 2年5か月ほどたって,復帰を勧められて復帰したが,被害に関係あるところの近くへの用事があった時に突然flashback
          • → またいけなくなる
          • なぜそうなったか話し合い
            • 自分のことを思ってくれている人の話は聞かなくてはいけないと,従順に思ってしまったことが良くなかったということを確認
          • 一時的に具合が悪くなったが,いったん治療した後なので,割と早く症状が軽減
        • さらに自分の行動についてよくコントロールできるようになり,4年後に大学を辞めることを選択して就職し,普通に勤務,自活できるようになった
        • 被害者から見ると,本当にそれぞれのときにかなりできることは精一杯している
          • ただ,時間がすごくかかっている
        • 全部が良くなるまで待つと,何年もかかってしまうことも多い
        • 回復の目安
          • 全部ネガティブではなくなってくる
          • 小さい楽しみが出てくる
          • この回復の目安がとても重要
          • トラウマ体験となったようなこと,過去のことを,ただ恐怖するのではなく,そのことを十分に考えることができる,頭にとどめておいて分析できる
          • 未来のことも,どういう行動をしたら何が起こるか,加害者と遭遇する可能性があるか考えられる
            • 確率が低いこと,遭遇したらどうすればいいか,そういうことを考えることがとても大事
          • 心配するのではなく考えるということが回復につながる
          • 過去のその記憶の時点にしか生きていない状態から外れて,ゆっくり考えることができることが,臨床的な回復の目安
        • 科学的エビデンスのある治療法の第一選択は,PTSDの場合は,薬物より認知行動療法
          • PE(Prolonged exposure)法, CPT(Cognitive processing therapy)
          • いずれの治療法も一定の効果はある,特に認知行動療法が一番効果量が大きい
            • ただし,薬はなかなか難しい.成績が良くないものもある
          • → 放っておくのが一番いけない
    • 事例2.パワーハラスメント
      • 抑うつと不安を伴う適応障害
        • 服薬治療
      • 自責感が強まり自己評価が低下
        • 症状やPower_abuseについての心理教育,認知のゆがみについて,認知的療法による介入
      • 1か月後から徐々に別の職場に復帰し,加害者の退職を機に普通に仕事ができるようになった
        • 最初のうちは,怯えもあり疲労感を訴えていた
      • こういうケースは,加害者の行動から周りに良くない構造があり集団内が分裂していたり状態が良くないことがあり,疲労度が強まる
      • 特定のイベントで加害者に遭遇したらどうしようかと非常に強く心配することもあった
      • 最終的には2年で治療が終了
    • 事例3.セクシャルハラスメント
      • 優秀な一方で発達障害,traitsがあるということで,男性なら変わり者で済むようなことが,女性のケースではさまざまな情緒的機能を満たすように暗に要求されることが多い
        • そのことで破綻をきたすことがある
      • 脆弱性から生じるハラスメント
      • 回復していないトラウマがあることで,対人関係が上手くいかず,傷つきやすく,再被害に遭いやすいということもある
      • 発症のリスク要因
        • 事前の精神障害があるようなときは,ハラスメントに弱くなる
      • それはそれとしてハラスメントはハラスメント
        • リスク要因が発症に促進的に関わってくる点と切り分けられるものではない
      • 脆弱性がトラウマやストレスに関連する精神障害発症の一定のリスク要因となる
        • 発症しやすく,症状が重くなる
      • PTSDの発症のリスク要因
        • 単純に女性であるということ
        • 事前のトラウマ歴がある
          • 乖離症状が起きたりする
        • 何らかの精神障害や,通院歴の既往がある
        • 事後の発症リスク要因として,ソーシャルサポートがないこと
          • 孤立は非常に良くない
      • 発達障害があるような方の場合は,治療しても回復がなかなか上手くいかないこともある
      • 脆弱性はリスクを背負いこみやすいが,ハラスメントの加害性は当然ある
      • 加害は加害
        • どんな人もどんなトラウマも複雑.程度の問題.法律では0-1で切り取ってしまうが.
          • 心理的,臨床的に個別性を尊重することは,法律とは違うこと
        • どんな人も,ハラスメントを受けるいわれはない.強者の側には常に行動の選択肢がある.
          • 被害者は常に選択肢がない
          • 加害者が常に選択肢を持っている → 行為は加害者の責任
        • ハラスメント調査が終わっても,心理的影響は終わらない.環境がその人のその後を大きく左右する.
  • 指定討論
    • 学校の特殊性
      • 学生はclientでありながらパワーがない
      • 異動がない
    • 法的なサポート
      • 操作そのものが加害の視点で組み立てられている
      • 被害者の視点を謙虚に聞く必要
      • 治療しなくちゃ説明できないくらいショックを受けていることを,誰も知らずに整合性がないといわれるのは酷いこと
      • 記憶の想起は記憶の改変と同等というのが学術上の1つの答え
        • 1つの事実に対して正直に話すか嘘をつくかという捜査の前提自体が間違っている
        • 治療しても記憶は変わってしまうが,話す権利を奪われるよりは治療した方が良い
      • どういうふうに話せないかということを社会に知ってもらいたい
    • 発達障害について
      • 本人が自分の状態を分かって治していく,コントロールしていかなくては,リスクが下がらない
  • 質疑応答
    • PE法を使った時に,発達障害PTSDが両方ある方に,どういう限界があるか
      • ある1つのことについて,自分の責任ではなく,相手がこういうことを選択したことがいけなかったんだという,症状としての自責感が消えていくような洞察が発達障害がない方ではできるようになる
        • これが,洞察まではいくけれども,ある程度の時間がかかったことや複数回の被害について,汎化が起こりづらい
          • トラウマの体験の記憶についての整理を1つずつやりたいというようになる
          • → これからどうするかという洞察が来にくい
          • 認知療法の部分で進みが悪くなる
    • 階層構造の改善
      • 上が知るしかない
    • 加害者の特徴
      • パワーの構造に従う人
      • 対策
        • 自分より弱い人に対して優しくする
          • 共感性を示すところでもあり,パワーの構造に意識的になる
    • ハラスメントを避けられるケースがあるか
      • 距離を取るのが1番
      • アサーティブに立ち向かって解決できるものではない

PTSD(心的外傷後ストレス障害)の認知行動療法マニュアル(治療者用) PE法のprotocol(概要)

はじめに

  • 理論的基礎
    • PE(Prolonged_exposure)は,不安障害のためのエクスポージャー療法の長い歴史と,PTSDの情動処理理論(Emotional_Processing_Theory)に基づく
    • Emotional_Processing_Theoryによれば,恐怖は1つの認知構造として記憶の中に表現される
      • 恐怖刺激,恐怖反応,刺激に関連した意味,さらにこれらへの反応が含まれる
    • PTSDの背景にある恐怖構造の特徴
      • 第一に危険であると誤解されている刺激が非常に多く存在すること
      • 第二にそうした刺激がPTSD症状に見られるような生理学的な覚醒の亢進と行動的な回避反応と結びついていること
    • 2つの広義な否定的な認知(世界はすべて危険,対処するには自分はまったく無力)が,さらにPTSD症状を悪化させて,誤った認知を一層強化する
  • PTSDの自然回復と慢性化
    • 回復の経緯(自然回復の場合)
      • 日常生活の情動処理の結果
      • トラウマ記憶が何度も賦活され,トラウマに関連した考えや感情が呼び起され,それをほかの人間と話し合い,トラウマを思い出させるような状況に向き合うことで,否定的な認知(世界は危険であるとか,自分は無力であるとか)が修正される
      • 助けになってくれるものを相手にトラウマの出来事について話したり考えることで,事件の記憶の筋道が整理し直される
    • PTSDの慢性化は,トラウマの想起刺激を極度に回避したためにトラウマ記憶が適切に処理されなかったために起こる
      • → 治療では,情動処理を促進する必要
      • PEでは,自然回復のときと同じく恐怖構造が十分に賦活されると考えられている
        • 想像および現実エクスポージャーを通じてそのような賦活が生じることで,患者はトラウマに関連した思考,イメージ,状況に意図的に向き合い,自分と世界についての感じ方が不適切であったことを学ぶことができる
    • 認知や行動に負の強化が加えられていることでPTSDは維持されているが,PEはトラウマの記憶や想起刺激への直面化を通じてこのような強化を減少させる
      • さらに馴化が生じると,回避以外に苦痛をやわらげる方法はないという思い込みは否定される
    • 想像および現実エクスポージャーによって,患者はトラウマ的な出来事と,それに似てはいるが危険ではない出来事の区別ができるようになる
      • 再び被害を受けるわけではないことが理解されるようになる
      • 被害の出来事について考えることは危険ではないと気づき,過去と現在が区別できるようになる
      • 繰り返しトラウマ記憶の扉を開いて物語ることで,出来事の記憶の中には様々な別の要素があることに気づき,必ずしも世界が危険だとか自分は無力であると信じる必要はないことが正確に判断できるようになる
  • PE全体の概観(手続き)
    • 心理教育.トラウマ後の一般的な反応の説明など
    • 呼吸再調整法.自分を落ち着かせるための呼吸法の指導
    • 現実エクスポージャー.トラウマによる苦痛や不安のために患者が避けている状況や対象に対して,繰り返し行う
    • 想像エクスポージャー(想像の中でトラウマ記憶に立ち戻って話すこと).トラウマ記憶に対して,繰り返し,持続的に行う
  • 適応
    • 一般的には,少なくともトラウマ被害から1か月が経過し,それでもなお強いPTSD症状が持続している患者が適応となる
    • トラウマのタイプは不問
      • 明らかなPTSD症状が存在しており,苦痛や生活への障害が生じており,トラウマ体験を十分に記憶しており語ることができ,また切迫した自殺または他害行動ないし自傷行為の恐れがない場合に適応
    • 精神病性障害の診断がある者は,適切な薬物療法によって状態が安定している場合には治療が行われてきたが,体系的な研究はされていない
    • 現在もまだ被害に遭うリスクが高い場合,PEは有効であるが,まずは安全を確保し,危険な状況から引き離すことを介入の中心とすべき
      • 安全がすべてに優先する
    • トラウマの明確な記憶がない,もしくは記憶が不十分である場合に,患者にトラウマを思い出させたり,記憶を取り戻させたりするための手段としてPEを用いてはならない
    • 以下の問題のある患者には,実施は可能だが要検討
      • 薬物・アルコールの乱用や依存
      • 危険な住環境・労働環境
      • 第Ⅱ軸障害の存在
      • 重度の解離症状
      • 罪悪感や恥辱間が顕著なPTSDの場合
  • 評価
    • PE開始前に詳細なトラウマの病歴を取り,index trauma(そのために症状を引き起こしていると考えられ,治療上で第一に扱う必要のあるトラウマ)を決める
    • PTSDの診断(または重要な症状の存在)を確認し,その重要度を評価し,PTSD以外のすべての現在の併存疾患の重症度を確認し,その併存疾患に対して直ちに介入が必要かどうかを決定する
    • 症状評価
      • 治療前後(そしてフォローアップ)の時点で面接評価尺度と自記式尺度を用いる
      • 治療の進行中に自記式尺度を定期的に実施
  • 対人暴力の被害者を治療する際の留意点
    • 被害者が故意による他人からの重大なトラウマを体験したことを忘れてはならない
      • 極度の恐怖を体験し,誰も信頼できないという悲観的な世界観を持っているはず
      • 患者から信頼されて被害体験の情動処理を助けていくためには,強力な治療同盟を結ぶことが不可欠
  • 治療の基礎
    • 恐怖を引き起こす状況と向き合うことは非常に難しい
    • 恐怖を上手に克服するためには,以下の点に留意して治療の土台を築き,患者を助けることが必要
      • 概念モデル
        • PEの基礎概念である情動処理理論モデルを明確に理解することで,治療の経過や進展の予測が助けられ,治療の節目や新しい変わった問題が生じたときの決断,患者の進歩や治療の終結を決定することができる
      • 治療同盟
        • 治療に参加した患者の勇気を認め,患者のトラウマ体験について価値判断をせずに,暖かく受け止める
        • 患者自身の恐怖や症状に即した例を使って治療原理の説明をする
        • 治療者のPEの効果への確信と,実施への自信を示す
      • 治療原理
        • 患者のエクスポージャーの大部分は,診察室の外で,つまり治療者の見ていない場所で行われる
          • 患者が治療原理をしっかりと理解していることがPEの成功の決め手となる
  • トラウマ被害者の治療の難しさ
    • 患者によっては,PEが終わった後で,必要に応じて別の援助手段の紹介も重要
    • PEは人生の問題の一部分を扱っているに過ぎない
  • 治療への動機づけ
    • 恐怖のために避けてきた記憶やその想起刺激に向き合うことは大変難しい
      • 20%-30%の患者が途中で脱落する
      • 回避はPTSDの症状の一部なので,治療そのものを回避したいと思うことがある
    • 治療を開始した直後や,治療を回避したいという葛藤が生じたときには,常に回避について話し合い,治療への動機づけを高める
    • 被害前の生活を覚えている場合には,被害前後の生活を比較することで,患者がPEによってどのように変わりたいのか,どのような生活を取り戻したいのかを具体的に明らかにするのも良い
  • 治療者自身のケア

セッションの進め方(抜粋)

  • 治療内容の説明
    • この治療では,恐怖と,その恐怖に対応できていないことの2つを扱うこと
    • 症状が長引く原因が回避にあること
    • 治療は想像エクスポージャーと現実エクスポージャーによって行われること
    • PTSDが長期化するもう1つの原因が,自分自身や世の中に対する,自分の役に立たない思い込みであること
  • 情報収集
    • 標的となるトラウマを定める
  • SUDS: Subjective Units of Discomfort Score
    • 現実エクスポージャーは,中等度のSUDSレベル(40-50)の状況から開始し,徐々に高いレベルへと進める
      • 現実エクスポージャーの際には,30-45分,あるいは不安が十分に低下するまで,その場面に居続けるよう指導する
        • SUDSが最低50%低下するまでとどまることが目標
  • 現実エクスポージャーを終えることができたら,その経験を踏まえ,記憶に対するエクスポージャーへと導入する
    • 回避の欲求を当然のことと認め,記憶に触れることによって恐怖の馴化と記憶の整理(記憶と現実の被害の区別など)が生じること,そのことのもたらす意味を想像エクスポージャーの後で検討(処理)することによってトラウマ記憶の苦痛が軽減し,PTSDが改善することを伝える
      • 対話的に必要に応じて比喩を使うなどの工夫をし,患者の理解を促進する
  • 想像エクスポージャーの治療原理
    • 記憶を処理し,整理する
    • トラウマの出来事を「思い出す」ことと,「再びトラウマ被害を受けること」の区別を促進すること
    • 馴化を促進すること
    • トラウマの出来事とそれに類似する事柄の区別をさせること
    • 自己制御とコントロールの感覚を強化すること
  • 想像エクスポージャーの実施
    • 45-60分間,中断を入れずに患者にトラウマ記憶を語るように依頼する
      • 時間が余ったら同じ話を反復させる
      • 話すことそれ自体に対する否定的な認知が生じているので,患者を勇気づけ,話したいという事実に基づいて患者の自主性を賞賛し,記憶と現実の危険が違うことに注意を向ける
      • 5分ごとにSUDSについて尋ねる
    • 感情のレベルの調整のために,開眼-閉眼,過去形-現在形などの使い分けを指示する
    • 促しや指示的なコメントで治療を順調に進める
    • 患者を支持するために,共感的なコメント及び想起の作業を評価するようなコメントを与える
    • 記憶への感情的なかかわりを強めるために,感覚(体感,視覚,嗅覚,聴覚など),思考,などについて簡単なopen questionを用いる.治療者との応答にならないように注意
  • 想像エクスポージャーでトラウマ記憶の処理を促す方法
    • PEが進むにしたがって,治療者は患者がトラウマ記憶を語っている間,トラウマが起こった時に患者に生じた思考,感情,身体反応について短く具体的な質問をしながら調べていくようにする
    • SUDSを高めに評定し続ける患者については,回復の指標となる別の変化に注意を払う(PTSD抑うつ症状の改善,または治療の初期よりも苦痛がかなり少なくなっているなど)
  • 想像エクスポージャーの処理
    • つらい記憶と向き合う患者の勇気と能力を認め,誉め,励ます
    • 必要に応じて指示を与え,落ち着かせる
    • 今終えたばかりの,想像の中のトラウマ体験に立ち戻るという治療についての,患者の考え,感情を話してもらう
    • トラウマの最中とその後の患者の反応や行動が,誰にでも起こり得ることを理解させる
    • セッション中または,全体を通して観察された馴化についてコメントする(十分でなかった場合は今後の見通しを与える)
    • 思い出された記憶についての考えや感情の変化,あるいは治療者が観察したことを取り上げる
    • PTSDを長引かせる原因となるような考えや信念への自覚が深まった場合には,そのことを取り上げる
    • 患者が考えていることを自由に話してもらう.治療者の見解を伝えることは控える
  • リスクへの対応
    • 治療室の中では治療者がいて安全であること,それは記憶であり,今起こっているわけではないことを言葉で話して思い出させる
  • 中間セッション
    • セッション3はやや短い時間で行う.また感情のレベルを徐々に上げ,記憶を明細化するような促しを行う
    • 想像エクスポージャーは中断せずに30-45分間続ける
    • トラウマを思い出して話す時間の長さやそれを反復する回数は,トラウマに向き合うことに要する時間やSUDSレベルのパターンによって異なる
      • 一般論として苦痛のレベルが下がるまで繰り返して話させるが,処理のための時間は必ず確保する
    • ホットスポットの手続き
      • 第5もしくは第6セッションでホットスポットを始める
      • ホットスポットでは,トラウマ記憶の中で今現在最も苦痛を感じている部分を抜き出し,繰り返してその記憶に触れて話す方法
        • これによって,最も苦痛の強い部分に対する馴化,記憶の整理が効果的に生じる
      • 最も苦痛を感じる箇所が複数あり,すべてを取り上げることができない場合も,治療効果の汎化によって,直接取り上げていないものに対しても効果が広がると期待される
  • 最終セッション
    • 想像エクスポージャーの実施
      • 20-30分間でトラウマ記憶を話してもらう
      • ホットスポットだけでなく,トラウマ記憶の全体を話すようにする
      • PEを終えるにあたって,新しく再構成されたすべての記憶を患者が語ることが重要
    • 治療プログラムで学んだスキルをまとめる
      • 改善したことや学んだこと,そしてこの治療で始めた取り組みを今後も続けていけるかどうかについて,対話を通じて患者自身が気づくようにする
    • 現実エクスポージャーにおける患者の進歩を振り返る
      • SUDSレベルが大きく下がっていることについて,なぜ,どうやってそうなったか尋ねる
    • 治療の終結

患者に応じた治療修正

  • 期待したほどに回復しない原因
    • 回避
    • 情動的関わりが不足または過剰
    • 苦痛の情動に耐えられない
    • 苦痛以外の否定的な情動(たとえば怒り)にとらわれていて,そのために改善が妨げられている
  • 治療モデルの重要性
    • 恐怖構造に近づく
    • 修正的な情報を提供する
      • 恐怖構造の過剰で非現実的な側面をやわらげるような「安全な経験」を提供する
  • 現実エクスポージャーの修正
    • 階層表の場面をさらに細かい不安の段階に応じて設定し直すとよい
      • 時間帯や場所など
    • 現実エクスポージャーの最中に実際に何をしているか詳しく見る
    • 無意識の回避がないか確かめる
  • 想像エクスポージャーの修正
    • 患者の興奮または苦痛のレベルを加減する
  • under_engagiment
    • 短い質問
    • 質問しすぎないようにする
    • 治療原理を話し合う
    • 想起と実際の被害の違いを確認する
  • over_engagiment
    • 解離している
    • 感情に圧倒されている
    • 苦痛をコントロールしながら現在という時間に足をつけて踏みとどまるようにすることと,今は安全な治療室にいることを理解したうえで,トラウマ記憶の一部でもよいから話せるように助けることが目的
    • 開眼,過去形にしたり,治療者からの発言を増やすことも役に立つ
    • 患者に共感し,努力を認めて誉めるような短いコメントによって,患者をそのまま記憶にとどまらせるようにする
    • 患者がトラウマを乗り越えて進んできたことや,トラウマ記憶を物語るときは片方の足だけを過去に入れればよく,もう片方の足は現在の治療室に置いたままで良いことを,思い出させるのも役に立つ
    • 声に出して語るのではなく,書いてもらう方法もある
    • 自分が支えられ,現在に足をつけていると感じてもらうためには,治療者は何をすればよいのかを患者に聞くことも推奨される

『ビヨンド ソフトウェア アーキテクチャ』学習メモ

前書き

  • solutionをうまく構築し維持するという目的
    • business 課題を理解し,受け入れていく
    • 幅広いbusiness上の課題とarchitecture上の選択との関係について議論する
    • 誰かに価値をもたらし,持続的に利益を上げる
  • techniqueとbusinessの相互関係をmanagement

Ch01 software_architecture

  • software_architectureの定義
    • important module, process, data, structure, component間の正確な相互関係を積み上げたもの
      • どのように拡張できる・されるべきか,どのようなtechnologyに依存しているかも含まれる
    • systemの正確なcapabilityと適応性が決まる
    • → systemの構築や改修のための計画が立てられるようになる
    • 全体的な観点でみることがimportant
  • software_architectureに関する一考
    • 上記の定義と異なり,「人間」や「business」に焦点を合わせる.
    • subsystemは依存性を管理するために設計される
      • developers groups間の依存関係を管理しやすくすることを優先
    • subsystemは人間のやる気や願望に応じて設計される
      • architectureの構築の始まりはやる気や願望の考慮が必要
    • column: 全体感を生み出すsubsystemの設計
      • 自分の仕事に「全体性」や「網羅性」を感じたいという強い願望
    • より上位のarchitectureへの屈服
      • 問題領域のフォースのなすがままになることはbestではない
      • 自身の経験からの影響も重要
    • 美は見る者の目に宿る
      • 設計上の決定に関する美学から一歩引いて考えられるdeveloperはごくわずかしかいない
  • なぜsoftware_architectureが重要なのか
    • 良いarchitectureが長期的な成功には欠かせない要素のため
    • 寿命
    • stability
      • architecture levelで安定していれば,基本部分の手戻りは最小限で済むことが補償される
        • → 全体として実装コストは減少する
    • 変更の度合いと性質
      • architectureにより,systemに生じる変更の性質が左右される
        • 変更や機能追加が容易 → architectureが優れている
    • 採算性
      • technical architectureの採算性は,architecture自体とほとんど無関係
        • marketing, 流通, brandingなどが影響
      • 簡潔で洗練されたarchitectureの方が採算性の高いsolutionの基盤には向いている
    • 社会的構造
      • good architectureは構築しているteamにも影響を与える
      • どのようなprogramming languageを選んでも,それを使えるようにdevelopment_teamを作っていくしかない
      • architectureはdevelopment_teamよりも長生き
    • column: architectureを置き換えるのにどのくらい工数がかかるか
      • 今のteamの半分の人数で1年以内に以降ができそうなら,新しいarchitectureへの置き換えを真剣に検討した方が良い
        • teamを分割し,旧systemの維持と新systemの構築をそれぞれで担うことで,costの増加を最小限に抑えられる
      • 旧architectureにかけたコスト全体の40%~60%はかかる
    • boundaryを定める
      • architectureが最終的に成功するうえで極めて重要
      • business固有の要求を満たすため技術的な境界を構築する
    • 持続可能で圧倒的な優位性
      • most important
      • good architectureならば,技術的に洗練されていて,真似もしにくく,競合に対する持続的な優位性を得られる
      • good architectureならば,usabilityや性能面などにおいてもadvantageを得られるという点もある
  • architectureの構築
    • 振り返りの分析を通じて,deliveryされた現実に合わせて当初の設計を更新し,architectureを説明できるようになる
    • user/developer両方が制限を理解し管理することで,architectureのcapabilityについての自信を深めていく
      • 本物のfeedbackを受け取ることと,それに対して成功に欠かせない変更を行うことを約束することが特徴
    • architectureの最適解を見つけるために代替architectureを探すことは現実的ではない
      • 金銭的余裕がない
        • team_memberの選定時に,十分に経験を積んだ人を選び,代替案の調査をしなくても正しい決定ができるようにすることで対応する
      • 問題の性質や周囲の環境
        • 実用的な意味でのarchitectureの選択肢が限られる
        • 標準的なarchitectureを選択することになる
        • より小規模でより特化したものを調査することは,役立つことが多い
      • 実際にsystemを使用しないとわからないarchitectureの良さ
        • このprocessには長い時間がかかる
    • column: 失敗しそうなことに気づくのはいつか
      • さまざまなarchitectureの経験を積むことで,実装する前に,大きな失敗をしそうな選択肢がわかるようになる
  • pattern, architecture
    • 上記のforceが絡み合うため,初期のarchitectureを構築する際には,完全に実用的なapproachをとらなければならなくなる
    • software_pattern: あらかじめかみ砕かれた知識
    • architecture_pattern: software_systemの基本的な構造を表現
      • まず,architectureの技術的側面を扱う
        • subsystemについて説明し,それぞれの責務を定義し,特定の問題を解くためにどうやって相互作用するのかを明らかにする
      • 問題の特定の側面に的を絞れば,architecture_patternによって,architectureの種類や形式が正しいかどうか判断できる
    • software_architectureを構築する際の実用的なapproachは,文書化されたあらゆるpatternを調査し,状況に合うものを選択すること
      • 必要に応じてarchitectureをテーラリング(仕立て直し)
      • 最終的には,それを動作するsystemの中で実現する
      • systemとarchitecture_patternのgapを埋める
        • たとえば,あらゆるsoftware_architectureは,適切に設計されたinstall/upgrade process,上手く構築された設定ファイルによる恩恵を享受できる
      • これらのapproachをすべて駆使して,成功するsolutionを構築し維持することが目標
  • architectureの進化と成熟: featureをとるかcapabilityをとるか
    • clientの要望するfeatureや自分たちが望むfeatureと,それをサポートするために必要なcapabilityとの相互作用は,時とともにarchitectureがどのように進化していくかを説明する
      • この相互作用は,technologyの継続的な進化とともに起こる
        • clientからのfeedbackは,自分たちの役に立ちそうなtechnologyを見つけたことに起因することがあり得る
        • development_teamがtechnologyを見つけることもある
    • feature(または機能): productが何をするのか・何をするべきなのかを規定する
      • 要求されたfeature全体によって,productの要件が規定される
      • usecaseとしてfeatureを記述すると,featureを特定のcontextに当てはめて表現できる
        • 最も役に立つcontextは,usecase中のactorの目的に基づくもの
        • actorの目的が分かり,systemでその目的を達成できるか分かれば,product managementが価値のある提案をするために必要なデータが手に入る
          • この提案が,business model, license model. price modelの根拠になる
    • featureはmarketingによってはっきりと優先順位づけされているときが1番管理しやすい
    • feature間の技術的な依存関係がdevelopment_teamによってきれいに整理されているときが,1番上手く実装できる
      • 優れたarchitecture: 求められたfeatureを比較的容易に実装できるようにするもの
    • 関係する一連のfeatureを実装できるようにするarchitectureの基本的な能力: capability
    • architectureの成熟と進化の間に起きる相互作用: 時間とrelease cycleを変数とする関数で表現できる
    • 負債の元本: 本来あるべきcapabilityを利用して構築した場合と比較したコスト
    • column: architectureのcapabilityをとるか,featureのagilityをとるか
    • column: entropyの縮小(ER: Entropy Reduction) ~リリースの後に必ず技術的負債を支払う~
  • architectureへの配慮と手入れ
    • 技術動向
    • 技術的負債
    • 既知の不具合
    • licenseの遵守
      • vendorの更新情報は忘れずにreview
  • 一に原則,二に原則,三に原則
    • encapsulation
    • interface
      • 具体的な実装を超えた抽象化
        • e.g. ファイルへの書き込みを抽象化して,抽象interfaceに出力する
        • vendor固有のAPIに存在する「使い勝手の良さ」を諦めている
    • 疎結合
    • 適切な粒度
      • componentが関連するタスクに応じて
    • 高凝集 1つのcomponentやcomponentのgroup内で行われる活動が,どのくらい深く関係しあっているか
    • parameter化
      • IoC(Inversion of Control)
        • componentの制御を外部に任せる
        • frameworkやplugin architectureでよく使われる
    • delay
      • 決定をできる限り遅らせる
  • architectureへの理解を深める
    • development_teamにとって重要な基準: architectureについての知識の確認,説明,communication,修正を,いくつかのやり方で,それもソースコードを読み返すことなくできること
    • teamが「全体像」レベルの抽象度で作業するには,少なくとも1つはモデルが必要になる
    • Rational社の4+1 model
      • logic view
        • 時系列上の1点で,システム開発に登場するobjectやentity間のあらゆる関係性を静的な視点で捉える
        • 概念モデルと,概念モデルをDB schema上で実装したもの
      • process view
        • 並行性や同期化にかかわる設計を説明
      • physical view
        • softwareとそれが配置されるhardwareの対応を記述するもの
        • 高可用性,信頼性,耐障害性,性能といった目的を達成するよりcomponentの分散も含む
      • development view
        • 開発組織におけるsoftwareの静的な構造を表す
    • → n+1 model
      • 各viewを考慮しながらarchitecture上の決定を進める
      • viewがもたらすcommunication上の特性を理解し,必要に応じてviewを使用することが水晶
    • 時間・労力・お金を費やすに足るarchitectureは,比較的安定した問題,問題領域,business modelこれらすべてに関連する技術的solutionの固有の側面などを解決するもの
  • team
    • 初期開発を担当するteam
      • teamの経験が大きな影響
      • できる限り小さいteam
        • communicationのoverheadを最小化し,team内のまとまりを最大化
        • 3~5人まで
    • teamが成長するprocessは,teamとarchitectureが安定するか,経営陣が定めた限界が来るまで継続
    • 問題に合わせてteamの規模と構成を決定
    • teamとsystemのarchitectureが結びついていることが最も重要
  • まとめ
    • software_architectureは全体像に焦点を合わせている
    • team構造とsystem構造は相互に結びついている
    • architectureは技術的な課題にも技術的ではない課題にも関係する
    • architectureが上手くいくための主な要因
      • 長寿
      • 安定性
      • 競合優位性
      • architecture_patternは新しいarchitectureを構築する際の出発点として最適
    • architectureはfeatureとcapabilityとともに進化する
    • architectureには配慮と手入れが必要(庭のように)
    • 一度releaseを終えただけでarchitectと名乗る人間には注意
  • checklist
    • subsystem間の依存関係が明確
    • 同じteamでsubsystemを担当しているmemberは互いに仲が良い
    • 同じteamのメンバーは,誰もが生産性を改善できると考えるやり方で働いている
    • 採算の取れるarchitecture
    • 今のreleaseで取り組んでいる課題が進化のためなのか成熟のためなのか理解している
    • systemにどれだけの技術的負債があるのか理解している.負債が特定できている
    • licenseを遵守してcomponentを使っている
    • architectはarchitecture上の選択を推進するためにarchitecture原則をまとめている
    • teamの規模は,目的を達成するために大きすぎず小さすぎず適切

Ch02 product_development 入門

  • product_managementとは何か
    • 成功するsolutionを構築・維持するために欠かせない包括的な一連の活動
    • software_architectureの全体像より大きなもの
  • なぜproduct_managementが重要か
    • 技術的な正しさだけでなく,価格モデルの決定から有用なパートナーシップの構築まで,相互に関係する数々の複雑な活動が,productを全体として成功させるために必要
    • 成功するproduct_managementは,本当の意味で利益を生み出すproductと企業を作り出す
    • 何よりもclientの声を代表しているために重要
  • product_development_process: 1.0版を作る
    • product_development_process: productに関する1番大きな全体俯瞰図
    • concept提案
      • productを製造するのに十分な動機付け
        • marketの正当性を証明するうえで十分なbusiness dataと,feasibility(faisible: できる)を証明するうえで十分なtechnical dataが含まれる
    • product 提案/ business_plan
      • productの正当性を証明するために作られる主要document
        • きわめて重要
    • development plan
      • marketing_team
        • marketの要望を明確化し,優先順位をつけて,開発するproductが備えるべきfeatureとして表現する
      • development_team
        • feature間の依存関係を分析してarchitectureに求められるcapabilityを見極め
        • さまざまなタスクを完了させるのに必要な時間のざっくりとした見積もり
        • 技術solutionの評価
        • 必要なresourceの整理
    • development
      • すべてを1度に開発するわけではない
    • 最終品質保証
      • すべての基本はテスト
      • column: 自動化の目隠しに注意
        • 自動テストと最終品質保証は共に必要
        • multi platform developmentには,慎重なresourceの割り当てが必要
          • 最も主流で重要なplatformをdevelopment_teamが2・3選んで,それに基づいてsoftwareを作り,テストする
          • 最終品質保証がそのほかの環境でsoftwareの動作を確認する
            • 環境を再構築し直すコストの節約
            • 顧客の実際の環境を再現するための投資を避けて,資金の節約
        • 最終品質保証によりセキュリティテスト
    • 稼働準備
    • 本番稼働
  • よくある誤解への回答
    • waterfallと比べて,productを修正するかどうかを判断するための厳格な評価基準がある
      • stagegate
    • concept提案とproduct提案/business_planは決して欠かせないstage
  • business_plan
    • productに関係するあらゆる作業の基礎
    • 最初のarchitectureを構築するよりも前に策定する
    • すべてのreleaseに必要というわけではない
    • 表2.1: business_planの書き方
  • product_development_process release n.n.nの構築
    • product_development_processは,初回release語に一番変化する
    • conceptやproduct提案は省略されることが多い
    • business_planは,せいぜい,新規releaseの内容を反映するだけ
    • MRDはreleaseに関する中心的なdocumentになる
    • 稼働準備phaseや本番稼働phaseに求められることが,releaseによって全く異なる
  • product_development_processの補強
    • 段階的な凍結
      • 凍結: 正式な変更管理processを通じてのみ変更できるようにする
    • 変更管理protocol
      • 変更が行われる前に適切な人物に情報を与え,しっかりと準備できるようにすることが目的
      • 変更から影響を受けるstakeholderを絡める
        • 変更内容について理解し,承認し,正しく処理するため
      • 変更管理meetingは,product_management_teamが準備して仕切る
        • product中心でない組織では,project_managerやprogram_managerが準備して仕切る
    • column: document作成のバランス
      • 初期releaseは,できるだけagileなprocessで構築する
      • 成熟したproductを持つようになった開発組織は,agile_processよりも適切な,形式的なprocessへと以降
    • recycle_box
      • 有用かもしれないideaは,将来余裕ができたときのために蓄えておくrecycle_boxに入れる
      • 求められたfeatureをすべてreleaseしなければならない,というdevelopment_teamが感じるpressureを軽減する圧力弁になる
  • product_managementの重要な概念
    • marketingの4つのP
      • product
      • price(およびbusiness_model)
        • business_model: productやserviceでclientから対価を得る方法
        • business_modelに紐づく価格決定モデルによってpriceが決定
        • product_managementの中で最もやりがいのある課題
        • 効果的な価格設定は,心理学的な側面が強い
      • place(販売channel)
        • bitの集合であるsoftwareをどのように提供するか
        • productやserviceを提供するk十を誰が承認するか
        • system_architectureに影響を与える
      • promotion(広告とmarketing communication)
    • 有効市場(total_available_market),有効市場規模(total_addressable_market),market_segment
      • total_available_market: 利用する可能性のあるすべてのclient
      • total_addressable_market: 有効市場において対象にできる市場規模
      • 効率的なmarketing programは,total_available_marketを明確なmarket_segmentに分割する
      • market_segment: 共通する特別な性質を有するclientのgroup
        • client簡易交流がある
        • 効率を追及するなら,market_segmentをニッチ市場に分割
    • 受け入れのS字カーブ
      • カテゴリを理解することで,product_managementや関連するmarketing活動によってカーブの形を調整できる
      • カーブの形はinnovationの性質に応じて大きく異なる
      • innovator
        • 限界を超えることを好む
        • 動かすために必要なresourceを自由に使えることが多い
      • early_adopter
        • 限界を超えることを好むが,やや保守的
        • より完璧なproductを期待する
        • より多くの要素を望む
        • 全体的な成功を収められるかどうかの試金石
        • meritを納得させられれば,成功するsolutionの基礎が完成といえる
        • innovatorとearly_adopterの間のギャップを埋める: chasmを越える
      • early_majority
        • 価格性能比が争点
        • clientの成功事例やROI分析などの実証を求める
      • late_majority
        • 無視できない経済的圧力がかかるときに受け入れる
        • early_majorityに受け入れてもらったときに比べると,経済的利益ははるかに少ない
      • laggards(lag: 最後の人)
      • innovationを受け入れる理由: innovationがclientの抱える問題に対して何らかの効果をもたらすと感じるため
    • whole_product
      • 汎用製品,期待製品,拡張製品,潜在的製品の4つの概念が合わさったもの
      • target_productが上の4つを遷移していく
    • 技術的優位性と市場優位性
      • 市場優位性の方が強力
    • position, positioning
      • position: clientがproductを現在どのようにcategorizeし,認識しているかを,冷静に客観的に正確に算定したもの
      • positioning: clientの気を惹いて記憶に残るような独自の印象を生み出すための,戦略的に管理される活動
        • 未来のことが対象
        • 潜在顧客がproductを自然と思い浮かべるようにする
        • 長期的,戦略的,防衛的で所有可能なもの
        • 1つのconceptにだけ集中できるようにするもの
      • 技術的marketでは,positioningはpositionより重要
      • positioningを設定したら,何度もその目標に向かってpositionを作り直していく
      • column: effective positioningが購買動機に与える影響
        • positioningは,development_teamを含む全員にとって,魅力のある未来を創らなければならない
        • 記述形式
          • <魅力的な購買動機>を持つ<target client>のために,このproductは<主なメリット>を持つ<product category>だ.
          • <主な競合>と違って,<主な差別化要因>である.
    • brand
      • clientと交わす約束
        • → 重視される
      • partnership, customer support, 企業のWebサイトの性質や構造,clientに提供される商品やserviceの品質,利益を管理する方法などが,どれもbrandに反映される
      • 用語,symbol,slogan,名前など様々な要素を通じて表現され伝えられる
      • 知的財産として保護されていることが多い
    • main_message
      • positioningをcreativeに表現する短い(1,2 phrase)の文章
      • positioningを強化し,かつclientは確実に手に入るものを表す
      • press releaseから広告まで,あらゆるcreativeなmarketing communication活動を駆動するために重要
      • client中心
      • 重要な利益を表現する
        • なぜ注意を払う必要があるか,またはproductが問題をどうやって解決してくれるかをclientに伝える
      • 正確で,productが実際にsupportしているもの
  • まとめ
    • product_management: 成功するsolutionの構築と維持に必要な活動の包括的なまとまり
    • 初版のsoftware productの構築は,productを正当化するconcept提案に始まり,本番稼働に終わる
      • より幅広く包括的
      • そのあとに続くreleaseを構築するprocessはより軽量で,最初のreleaseの間に作られた素材を元に構築される
    • product_development_processがうまく運営されているかどうかは,各stageに厳格な「可/不可」の判断があるかどうかでわかる
      • そのあとに続く凍結が変更管理protocol,recycle_boxの考え方などによって強化され,改善される
    • business_planは,product_developmentを進めることを正当化する中心的なdocument
    • marketingの4つのP
    • 最大有効市場
    • 最大標的市場
    • market_segment
    • 受け入れのS字カーブ
    • whole_product
    • position, positioning
    • brand
  • checklist
    • 要件を表現するための何らかの仕組みを定義している
    • product_management_teamはclientの声を代表している
    • 企業にはproject, productを打ち切る方法がある
    • 競合他社が何を行っているか理解している
    • 勝つためには何を行うべきか理解している
    • productを誰のために構築しているのか,誰に売り込んでいるのかを理解している
    • 便利な変更管理protocolがある

Ch03 marketecture, tarchitecture

  • systemのmarketing的側面と技術的側面が一緒になってbusinessの目的を達成するさまを見る
  • 誰が何に責任を負うのか
    • tarchitect
      • software_architect, chief_technologist
    • marketect
      • product_marketing_manager, business_manager, program_managerなどシステムに責任を持つ人
    • tarchitecture: developerがsystem architectureを検討するときに参考にする主要な枠組み
      • software_systemを成立させるためのsubsystem, interface, 処理要素への責務の分割, thread modelなど
    • marketecture: system architectureに関するbusiness的な観点
      • business_modelに関するあらゆる物事を含む
        • license_model, 販売 model, value proposition, clientに関係する技術的な詳細, data sheet, 競合他社との差別化要因, brand要素, marketing_teamがclientのために用意しようとしているmental_model, systemに固有のbusinessの目的など
        • MRDやusecaseも含む
      • whole_productで説明されていたもの
    • column: 5万ドルのboolean_flg
      • marketecture, tarchitectureの違いを活用し,product_management_teamもengineering_teamも,さまざまな技術的な課題やbusiness的な課題を解決するのに最善と思われるapproachを柔軟に選択できる
  • solution_developmentの初期に現れるフォース
    • 図3-1: software_architectureを形作るフォース
    • 非機能要件
      • architectureに関する様々な品質や特性
      • 実行時にシステムを観察して見て取れるかどうかで二分
        • performance, usability
          • target_clientの意向が直接反映
        • testability, 修正可能性
          • target_clientとの将来の関係を左右
          • 明示されないので規律がきわめて重要
      • 技術的な妥協がもたらす潜在的な危険度を測るためには経験以外にない
        • tarchitectは少なくとも2回は完全releaseを経験する必要
        • productの整合性に対して長期的に関わり続けなければ,妥協を取り除いたことを確認できない
    • technology base
      • super tarchitecture
        • applicationの基本構成を規定
      • 問題領域から導かれるtarchitectureに対応したものである必要
    • 問題領域
      • 成功するsolutionを構築するための中心的フォース
      • marketect: market needsを明確化し優先順位をつける
      • tarchitect: そのneedsを満たす技術的なsolutionを構築
        • 領域における経験も設計に組み込む必要
        • 広範囲な領域の知識がほぼ必須
          • 特定の領域でsystemを構築した十分な経験と,成し遂げる十分なskillが必要
    • column: 時には難しいやり方でやるしかない
      • clientと長期間ともに過ごす
    • column: バグの深刻度,優先順位,標準化
      • bug review meeting
      • 品質の基準をあらかじめ決めておく
  • 長期的に稼働しながら短期間で結果を出す
    • clientが18か月から24か月先に求めるものをイメージするため,さまざまなデータを検証する
      • それ以前は現在なども過去のこととして捉える
    • 未来を想像できることはmarketectにとって重要な指標
    • tarchitectも同様
  • 将来像を示す
    • market_map
      • feature/merit map
      • market event/market rhythm
    • tarchitecture_map
      • 既存のtarchitectureではサポートできないだろう重要なfeatureを,核心的featureとして記録
        • 導入のために必要な変更を管理する必要
  • feedbackを利用する
    • marketect
      • user conference, technical/product support review, featureへの要望のreview, 販売担当者にinterview, main clientなどとmeeting, analystなどとmeeting
    • tarchitect
      • conference, magazine, mailing list, 自宅のPC, 好奇心
    • mapをメンテナンスし続けることでcommunication
    • column: 言ってはいけないことを言ってしまったら?
      • 本当に心配ならguidelineを示す
        • リスト
  • はっきりさせる
    • marketectの一番の目的は,development_teamのメンバが何を構築するべきかを正確に理解することで,その責任を負う
    • teamの規模と必要不可欠な外部とのやり取りの数によって,適切な構造・process・成果物を決定
    • marketectは,潜在顧客に対しても,systemが彼らの環境に与える影響をはっきりさせる必要がある
    • column: software developmentにおける文化的差異を管理する
      • 文化的差異に注意して,特定の文化でうまくいくapproachやprocessを選ぶ
    • marketectはtarchitectからの適切な情報の流れに強く依存する
  • 一致団結して作業する
    • tarchitectの創造的なenergyを,現実の顧客の現実の問題を解決することに向けられるようにすればよい
    • 合意形成
      • projectを推進するための原則を決め,それらについて合意する
    • dataが手に届くようにする
      • map, featureの可視化
  • context_diagramとtarget_product
    • context_diagram
      • marketect, tarchitectが協調するうえできわめて有用なtool
      • 重要な要素間の関係を表現することに注力する
  • まとめ
    • marketectはmarketectureに責任を持つ
    • tarchitectはtarchitectureに責任を持つ
    • marketecture/tarchitectureはそれぞれ異なるが関連し合っている
    • solution_developmentの初期ステージにおいて,特に影響力のある3つのフォース
    • architectになるための経験
    • bugの分類
    • productとその発展を示す戦略的なビューを作る
    • context_diagram
  • checklist
    • marketectがいる
    • tarchitectがいる
    • bugを深刻度と優先順位に従って分類できるDBがある
    • market_map, feature/merit map, market event/market rhythm map, tarchitecture_mapを作っている.誰もが簡単にみられるところにある
    • clientと対面する機会のあるdeveloperは,言っていいことと悪いことについて適切に訓練されている
    • marketectがsystemのcontext_diagramを作成した

Ch04 businessとlicense_modelの共益関係

  • business_model: product/serviceに関してclientに料金を請求する方法
    • あらゆるbusiness_modelにlicense_modelが結びついている
  • license_model: 利用規約,business_modelにより規定される
  • 同じphraseで両者を説明する短い文章を簡単に作れると,2つのmodelの共存を示せる
    • 2つのmodelは同じものではない
  • それぞれのtarget_marketに対して,market_shareと収益を最大化するための組み合わせを検討するべき
    • business_model, license_modelについての原理と,所定のtarget_marketでそれがどのように機能するか理解が必要
  • controlを手放さないためにlicenseが必要
  • business/license modelはmarketectureの重要な要素を体現したもので,tarchitectureにも大きな影響がある
  • column: business_modelの境地
  • 一般的なsoftware_business_model
    • column: application?suite?bundle?feature?
    • 時間ベースのアクセスや利用
      • 恒久license
        • supportや保守に関する全体的なコストが増えるため注意
        • 潜在的な欠点があるにもかかわらず一般的
      • 年間license
        • enterprise systemで一般的
        • target_marketに最適な期間を定義して,business_modelとlicense条項を適切に施行できるようにすることが難しい
      • rental_license
        • licenseが与えられた時点で使える時間が設定されているもの
        • 年間licenseもこれの一部
        • 重要な課題
          • いつから期間が始まるか
          • 期間が終わったらsoftwareはどう反応するべきか
          • 価格
      • subscription
        • upgrade, supportの権利がある
        • 何らかのbackend_serviceと結び付けられていることが多く,比較的簡単に強制できる
      • 後払い
        • tarchitectureに対して複雑なことを要求するが,softwareが利用された分のお金を必ず受け取れる
        • modelの成熟に伴い一般的になっていくもの
      • 利用者単位のlicense
        • volume_license
          • enterprise向けのapplicationには適切
      • OEM(Original Equipment Manufacturer)
        • business_modelはsoftwareへのアクセスに基づく
        • royaltyとして正当な金額を設定
    • transaction
      • あらかじめ定められた計測可能な処理の単位
      • 主にenterprise_softwareにおけるbusiness_modelで使う
      • marketectがtransactionを定義して,target_marketに対して最適なtransaction料金を組み立てる
      • tarchitectは,transactionの定義に関する法的な要素と,business_model的な要素の両方の理解が必要
      • column: good, but how to claim?
        • product/serviceの価格設定は,marketectの最も難しい課題の1つ
        • 原則
          • 価格には価値を反映
          • 価格にはかかった労力を反映
          • 価格にはpositioningを反映
          • 価格には市場勢力図を反映
          • 価格モデルはclientを混乱させてはいけない
          • 価格モデルはmarketの成熟度を反映
          • 同じproductの価格は下げるよりも挙げる方がm図鵜香椎
          • 価格モデルはtarget_marketの特徴を反映する必要
    • metering_model
      • 明確に定められたresourceやapplicationの処理内容に関する制約,あるいはそれらを消費することに基づくbusiness_model
      • 制約model
        • 既定の量のresourceにしかアクセスできないようにする
      • 消費model
        • 消費可能なresourceのpoolを作り出す
        • 消費しきると使えなくなる
      • 並行resource_management
        • e.g. user, session
        • 同時並行resource_management_model
          • @enterprise_software
      • 個別resource_management
        • systemが認証した場合にのみアクセス許可
        • 制約: resource
        • 同時並行resource_management_modelとの組み合わせ多い
        • 管理上の負担
          • 既存のdirectory infrastructure, user management infrastructureにより軽減
      • 消費resource_management
        • 課題
          • 時間の定義
          • softwareがresourceの消費を追跡する方法
          • licenseする時間の単位
        • subscriptionにも〇
        • 重大な要件
          • reporting
          • 補給
    • hardware
      • softwareにかかる料金をhardwareに結びつける
    • service
      • open_source_licenseが使われることが多い
        • marketは未成熟で未検証
    • 得られた収入/節約できたコスト
      • 歩合制
      • 本当はいくら支払うべきか追跡するのが困難で,not popular
    • column: open_sourceだからといって無料なわけではない
      • business_modelとlicense_modelの分離の恩恵の例
  • business_modelに関連する権利
    • 権利と制約ができるだけ多くなるように区別することで,より大きな価値を生み出せる
    • 図4-1: license_modelのsubsetの検討
      • 1.競合に対する優位性が得られたり,technical supportやproduct supportのコストを削減できたり,またはclientとの関係を強化できたりするのであれば,businessにこの権利を関連付ける
        • 逆にclientに関心がなかったり,厄介ごとを負わせてしまうものはやめる
      • 2.transactionに基づくbusiness_modelに含まれるべき権利
        • upgrade, bug fix, patch
      • 3.clientに受け入れられた場合は権利を関連付ける
        • hardwareではclientの権利を制限する理由がある
  • business_modelに対するtarchitectureのsupport
    • 一般的な課題
      • 必要なデータの収集
        • direct
          • systemは,business_modelに必要なデータをすべて収集し,管理している
          • 要自己完結
        • indirect
          • 必要なデータから全体像を組み立てるには,1つ以上のほかのシステムと統合が必要
      • 請求.送金に関する要件
        • 送信内容に関する書式,セキュリティ,監査の要件を定義することで簡単になる
      • business_modelの強制
        • license違反をした場合について
      • 品質特性に注力する
        • 品質特性: trustness, stability, scalability, ease of support, usabilityなど
        • 実現するための努力が,business_modelにとっての主要な目標と一致していれば理想的
        • softwareの使われ方はtradeoff
      • 収益の増加,あるいは,削減したコスト
      • 複製の防止・著作権侵害行為への対策
      • business_model, license_modelに関するparameterの妥当性検証
        • いつどこでどのように設定されるか,誰が変更できるか,妥当性をどのように検証したのか理解
    • 時間ベースのアクセスや利用
      • tarchitectureに課せられる特別な要件はそれほど多くない
      • ただし,厳密に強制する場合は,期間を過ぎたらsoftwareを無効化する仕組みが必要
      • ほとんどはupdateを受け取れなくなるだけ
    • transaction
      • transactionを定義
        • business_modelの基礎.明確さが必要
        • 定義後は,tarchitectureがそのbusiness_modelに対応できること,そしてlicenseに明記してあることを確認する
        • transactionに対して各componentがどのような役割を果たしているか考慮
      • transactionとbusiness_modelの関係を定義
        • 完了した個々のtransactionを確実にbusiness_modelへ対応付ける
      • 監査証跡を残す
      • transactionが一意に識別できるようにする
        • DBに任せず,信頼できるalgorithmで本当の一意の識別子を生成する
          • UUID, GUIDなど
          • 短縮も〇
      • transaction state, lifecycle, 継続期間を理解する
        • 請求のタイミング
    • metering
      • どうやってユーザを認証するか
        • 多額のお金を引き出すものであれば,LDAPなどユーザ認証のための確立されたinfrastructure technologyを組み合わせるべき
      • ユーザは何人いるか
        • 設定値の管理
      • 同時並行ユーザをどう数えるか
      • ユーザはいなくなったことにするのか,または非活性にするのか
        • session_management
        • 消費resource_managementを実施する場合は,tarchitectureに厳しい制約
          • ある種の状態の記録
      • hardware
        • 定義と強制方法が必要
  • license_modelを強制する
    • 自己申告制
      • 権利を放棄しているわけではない
      • 要因の注意深い分析が必要
      • enterprise_softwareでは,licenseを更新するたびにclient担当者が直接clientと話す機会があるので,購入を促すこともでき〇
      • consumer_softwareでは×
    • 自家製license_manager
      • licenseの費用に応じて専用のsolutionと比較する
      • sessionに基づくlicenseの場合は,自家製のlicense_managerのような仕組みが必要
      • column: 絶対に突破できないものでなくてよい
        • 正直者に嘘をつかせない仕組み
    • third_partyのlicense_manager, 専用のlicense_manager
      • license_generator
      • client
      • server
      • injection方式
      • API方式
      • license_managerの評価における課題
        • business_modelのsupport
        • platform, OSのsupport
        • solutionの強度を判断するために脆弱性情報を調査
        • backendとの結合,および処理量のcapabilityを確認
        • 運用環境との適合性を確認
        • brandingとuiの統制を確認
          • 国際化など
        • licenseの内容と形式を調査
          • 電子的署名
        • licenseの配布方法を調査
  • marketの成熟度がbusiness_modelに与える影響
    • target_marketの成熟度は,business_modelの選択や管理に一番影響する要因の一つ
    • business_modelの強制度合いも,target_marketの成熟度と足並みを揃える
    • business_modelを選択する
      • marketectが直面する最も困難な課題の1つ
      • target_marketは何か?その価値は?
        • どのように使ってもらいたいか
      • target_marketにおける目的は?
        • shareの確保,維持など
      • business_modelは何か?
      • どのような権利を与えたいか?
      • business_modelはどのような影響をarchitectureに与えるか?
      • 価格モデルはどうか?
  • まとめ
    • business_modelとはお金を生む方法
    • business_modelとlicense_modelは結びついている
    • license_modelとは,softwareの使用にかかわる条項,条件
    • software_business_modelがお金を生み出す方法一覧
    • userに関係するbusiness_modelによって,ユーザを管理する企業システムとの統合が促進
    • business_modelに関連する全ての権利を理解
      • 権利を分割することで,利益を生む可能性が高まることもある
    • license_modelを強制するには,自家製のlicense_managerか,third_partyの専用license_managerを使う
  • checklist
    • development_teamのメンバー一人一人が,現在のbusiness_modelや将来に向けて真剣に検討されているbusiness_modelを説明できる
    • license_contractがbusiness_modelと一致している
    • license_contractによって,clientに提供される権利が一式定められている
    • business_modelを強制するための,適切な仕組みを選択している
    • 別のbusiness_modelをsupportするためにtarchitectureを変更するcostにすいて,marketectと話し合い,理解してもらえている

Ch05 in_license technology

  • license_contractのriskと見返り
    • (merit)
      • (risk)
    • 複雑さやリスクの削減
      • 責任がproviderに移り,依存性が高まる
    • component化
      • technologyとsolutionとの結びつきが強いと変更が難しくなる
    • system構築がはかどる
      • 設定が複雑になりうる
      • 互換性の問題
      • license上の制約が増える
    • 特許によって保護されたlicenseにより,法的に保護
      • 補償からの免責を勝ち取ることが難しい
    • technologyのreuseによるmarket投入までの時間短縮
      • 必ずしも短くはならない
    • 品質
      • 必ずしも高くはない
    • 軽量,最適化
      • そうでない場合も多い
      • 調整困難
    • technologyの流行を追う苦労の軽減
      • 必ずしも素早く更新してくれるわけではない
    • 費用
      • 不要な費用になるかもしれない
    • service/support cost
      • 外部から導入したことによる新しいエラーへの対処が難しい
      • 適切にsupportできるか確認する必要
    • column: 他人の書いたコードを修正してもらう
      • vendorとの協力が重要
  • contract: どこで何を約束したのか
    • technologyのlicense取得の核心: 使用に伴う規約を定義した契約を交わすこと
    • contractの基本
      • 申し込み
      • 受諾
      • 約因
        • 両者の間で取り交わされるあらゆる価値
    • license条項
      • 定義
        • licenseの契約書に記されたあらゆる重要な項目や条項に関する正確で法的な説明
      • 使用あるいは許諾
        • 外部から導入したtechnologyの使い方に関するもの
      • 期間や条項,その他の重要な日付
        • 契約の開始と終了に関すること
        • 有効期間
        • 期日
        • 支払日
        • 試用期間
        • 解除通知
        • その他
      • column: 高くついた更新費用
        • 更新期限の意識が重要
      • 領域
        • 特に地理的な制約
      • 特定の用途
      • 独占権
        • ほとんどの場合では不要
      • sub_license
        • 組込technologyで必要
      • 終了,解除
        • 予告期間はできるだけ長い期間にするよう交渉する
          • 置き換えに時間がかかるため
      • 更新
        • 自動更新は非推奨
      • 料金または支払条項
        • tarchitectureが必要な支払条項をsupportしていることが重要
      • deploymentの制限事項
      • その他の一般的な制限事項
        • できないことも慎重に定義されている
        • いずれもtarchitectureに影響を与える
      • 競合禁止条項
      • source_codeへのアクセス
        • 三者機関がsource_codeの複製を委託されていても,結局管理できなくなっていれば意味はないことが多い
      • marketingの要件
        • 注意深く読む必要
        • tarchitectureにとって好ましくない影響を与える可能性もある
  • business_modelの衝突→交渉の始まり
    • 自分たちのbusiness_modelがvendorのbusiness_modelと整合していることをlicense取得前に確認
    • 不整合 → 妥協点を交渉
      • tarchitectureに重大な影響
  • license_contractの遵守
    • tarchitectureに影響を与えるもの
    • technical用語の定義
      • license_contractを遵守するうえで最も重要
      • 実際のproductを反映
      • version number
      • OSや運用環境の定義
      • business_planに従って,productを利用する権利がある
    • API
      • 公開できるかどうか
    • support
    • branding
  • in_license technologyの管理
    • wrapperのコスト
  • open_source_license
    • licenseの詳細の確認
    • productへの統合の仕方を定めている部分の確認: 最も重要
      • open_sourceの定義のバージョンを確認
  • license_cost
    • vendorのbusiness_modelが反映されていることを考慮する
    • 先払い
      • tarchitectureへの影響は最小限
        • technologyをsystemに統合するうえで最大限の柔軟性があるため
    • 使用量
      • tarchitectureに影響がある
      • 実現しやすい
    • 収益に対する割合
      • tarchitectureには景況が小さいが,marketectureには影響が顕著
    • 交渉の戦略
      • productを陳腐化させない
      • 価格付けを守る
      • milestoneごとの支払い
      • column: 価値に基づく費用交渉
        • moduleごとに価格設定を別にする
        • system全体の費用を体系化
      • 研修コストと開発コスト
  • licenseの収益構造
    • 収益構造を理解してリスクを事前に検知
    • in_license契約のコストをproduct planやbusiness_planに組み込むことの重要性
  • まとめ
    • どんなシステムでも,in_license契約のtechnologyを含む場合がある
    • 効果的なin_license契約のためには,marketectとtarchitectの両者が,リスクと対価について完全に理解する必要がある
      • 強い立場で交渉に臨める,より有利な契約を結べる
    • in_license契約はどれも,marketectureとtarchitecture両方に,direct/indirectな影響を与える
    • あらゆるbusiness_modelと整合させて,solution全体を組み立てる
    • in_license契約したtechnologyの管理には,さまざまなtechniqueが必要
      • 本質的: tarchitectureとtechnologyを分離する
    • 費用の取り決めと,license_contractに関連するコストの理解が必要
    • open_source_licenseのtechnologyの進化
  • checklist
    • licenseを取得したcomponentやtechnology全てについて,妥当な契約を交わしているか
    • in_license契約に関する主要な利用規約を理解しているか
      • 契約違反の原因になる行為を全て確認し,気づかないうちに破ってしまうことがないことを確認
    • licenseを取得したcomponent, technologyを置き換えることの影響を評価したか
    • licenseを取得したcomponent, technologyと,productのbusiness_modelは互換性があるか

Ch06 portability

  • portabilityのmerit
    • 〇複数のplatformに対応すれば,新しいmarketに参入できる
      • segment分割を上手くやることが長期の成功のために重要だが,これはplatformでのsegment分割ではなく,clientの問題を基準にするべき
      • 普通はbusiness課題によってplatformが選択される
    • そのほかはportabilityを追及するための根拠となるmotiveが適切なことはあまりない
    • 本当にportable applicationなら,platformに依存したfeatureが生み出されないように設計される
  • portabilityに関連するbusinessの事例
    • cost大きい
    • target_marketが十分に大きいときのみ,コストを正当化できる
    • cross_platformの条件
      • market分析の結果,複数のplatformに対応したproductを開発・サポートし続けていくコストを正当化するだけの十分な収入が見込める
      • supportするすべてのplatformについての開発・テスト・サポートにかかるコストの合計が考慮済み
      • 対応する複数のplatformについて,構築・テストするための人員を確保できている
      • supportしなければならないさまざまなplatformの開発活動に与える相対的な影響を理解し管理できる
    • applicationを移植可能にするより,technologyを移植可能にする方が説得力がある
      • technology: より大規模なsolutionを構成するための部品として設計されているsolution
    • 結局はtarget_marketがはっきりしているかどうかが重要
      • → development_teamがapplicationをどのように作るべきか決める
    • column: portabilityはお金のためでしかない
      • 単独のplatformでしか動かなくても素晴らしいsolutionであることが重要なcase
      • core technologyとしてportabilityが重要なcase
  • portabilityのあるapplicationの構築
    • interpreter_languageを使う
      • 実行環境との結合を疎にする豊かな絶縁層があるため
      • compiler_languageの場合は,条件付きinclude/compileが必要
    • 標準的なpersistence_storageを使う
    • business_logicを移植可能にする
    • 利用者へ寄り添うことで失われる可能性
      • portabilityに最大限の投資をするなら,backendやinfrastructure
    • subsystem間の相互運用性と標準化のためにXMLを使う
    • portabilityの名のもとにplatform固有の能力を埋もれさせるのは×
  • 苦痛のmatrix
    • 苦痛の最小化のために,developerや品質保証チームにmarketにおけるportabilityの相対的な優先順位を伝える
    • 優先順位づけのtechnique
      • developerや品質保証チームが利用する,marketありきの構成のmatrix(苦痛のmatrix)を作ること
        • all pair法の変形でもある
      • step1: 構成を減らす
      • step2: 組み合わせをランク付けして並びかえる
        • 理由となるもののリスト
        • red/yellow/blueに背景を分ける
      • step3: final_cutを決める
        • clientの環境の分布について情報収集し,パレート図にする
      • 初期段階における組み合わせと優先順位を,marketの特徴から自動的に算出する方法が必要 → all pair法
        • marketからの要求を満たしているかreviewは必要
  • 約束には用心する
    • 契約上の管理とサポートする対象にはくれぐれも用心する
      • 「以降」などは×
      • 販売した後のことも配慮する
      • 対応するversionとplatformは具体的に明確にするべき
  • まとめ
    • portabilityを求めるためには適切な理由が必要
    • portabilityのあるapplicationが欲しい理由も,それを構築したい理由も,実際は大したことではないことが多い
    • portabilityのあるapplicationを作るためにbusiness上の正当な理由があるとしたら,それは利益が出るということのみ
      • costを正しく見積もる
    • portabilityのあるapplicationを作るのは考えているよりもずっと困難で,長い時間がかかる
    • 苦痛のmatrixはtestしなければならない組み合わせを網羅
      • 無意味な組み合わせ,対応しない組み合わせを取り除く
      • 優先順位をつける
      • reviewを実施してfinal_cutを決める
    • supportする構成を常に明確にする
      • 新しい構成をサポートする場合は慎重にすすめる
  • checklist
    • 対応しているそれぞれのplatformについて,開発,品質管理,技術サポート,営業のresourceが足りているか
    • 対応しているそれぞれのplatformをテストするのに十分な時間をかけているか
    • productが動作するplatformのvendorによって提供された重要なreleaseが,technology loadmapに追加されているか
    • テストに費やす労力を最適化するため,market_drivenな構成matrixを作っているか

Ch07 deployment_architecture

  • deployment_architecture: clientが自分の手でsystemをdeploymentするやり方のときに使う
  • deploymentの選択肢
    • client site
      • clientのmachineにinstall
      • client自身が設定,運用,保守
    • application_service_provider(ASP)
      • 限定されたサービスを提供.完全なsolutionを提供することはほぼない
    • managed_service_provider(MSP)
      • ASPの拡張
        • 提供だけでなく運用も行う
        • ASP: 汎用/期待product
        • MSP: 期待/拡張product
      • 非常に特殊なhardwareを必要とするニッチなmarketに焦点を合わせている
      • ASP/MSPとも,SLAの締結が一般的
      • 少なくとも何らかのclient dataはservice providerの所有する機材に格納されてしまう
    • transaction(Web service)
      • 単一の完全なtransactionで応答を算出
      • Web service protocolを介して実行されることが多い
      • 個々のユーザに向けてサービスを提供
    • column: hybrid deployment_architecture
  • deployment_architectureにおけるclientの影響力
    • clientの期待に見合うdeployment_architectureの選択は重要
    • management, integration
      • systemをonsiteで運用しているのと変わらない水準で管理できることが重要な場合
      • 長期間にわたるデータの保全と管理
      • marketectが,clientが最も重要と考える管理面での課題を理解する必要
      • integrationへの要求が増えると,systemがclient siteにdeploymentされる可能性も高くなる
    • security, privacy, peek_load(ピーク負荷)
      • systemの扱うデータの性質に応じてdeployment_architectureに対するclientの印象は異なる
    • cost, vendorへの信頼
      • solutionの販促素材は,単にsolutionの利点を示すだけでなく,marketにおける長期的な生存可能性を示す必要がある
        • 生存可能性テスト
      • clientのデータをどのように保存し維持していくかが関心の的
        • いつでも古いデータが取り出せるとclientに安心してもらうことは,solution全体を設計するうえで重要
    • clientのskillと経験,地理的な分布
      • applicationとそのdeployment_architecture次第で,client企業に求められるskillや経験が変わる
      • clientの要求だけでなく,client企業の目的もよく理解できるようにつとめることがとても重要
    • column: credit card informationを粗末に扱わない
      • 運用管理の手順について慎重なreviewと監査を要求する権利がxSPに対してある
    • column: riskが大きくなり過ぎたときは
      • 諦めて成功するsolutionをしっかり構築するべき
  • 企業がdeployment_architectureに与える影響
    • 持続可能な成功するsolutionのためには,marketectが利用する企業の様々な事情を理解する必要がある
    • sales_cycle
      • 売り上げを算出するまでにかかる期間や手順
      • 価格やsoftwareの複雑さと相関
      • もしsales_cycleの短縮に取り組むなら,xSPとしてdeploymentすることや,正式な審査の元にlicenseすることを検討する
    • infrastructureへの投資
      • 長期的なサービスを提供し続けるためにどれだけの投資が必要になるか注意深く考える必要
      • 投資額の計算には技術的resourceと非技術的resourceをともに含める
      • 信頼できるinfrastructureを構築するための資金がない場合は,xSPやWebサービスの運営は×
    • cash_flow
      • 余剰資金を管理するための確実なアプローチが必要
    • 柔軟性
      • xSPやWebサービスでは管理の主導権がある
        • upgrade scheduleなどをかなり柔軟に予定できる
      • 新規市場では政調のためにrelease_cycleを素早く回すことは欠かせないし,必要なときに必要なだけupgradeすることもできる
    • 地理的な広がり
    • 価格よりサービス
  • softwareのdeployment_architectureを選択する
    • 図7-1: clientと企業が及ぼす影響とdeployment_architectureとの関係性
  • deployment_architectureと作業の分担
    • 図7-2: deployment_architectureと作業の広がり
  • information_appliance(ance: していること)
    • 明確なtarget_marketにおける包括的なsolutionをより良いものとするために設計された専用のdevice
    • Linux OSが受け入れられている → 発展
    • 複雑なsolutionを単純化することが求められている
  • deploymentの選択がsoftware_architectureに与える影響
    • 柔軟でparameter化されている,または統合の選択肢がない
      • xSPこそ標準化に取り組むべき
        • 構築も管理も単純になり,運用コストdown
      • 機能と比較的単純な境界がうまく定義されている場合は,統合の選択肢を一切与えないことはうまくいく
    • upgrade policy
      • systemを開発する初期の時点でupgradeを容易にする変更を行うことで,MSPなどは頻繁に安全に本番システムを変更している
    • data保護とアクセス
      • application dataの保守は,applicationや利用者,データのsensitibity,重要さに応じて,適切に行う必要
    • 移行手段の選択肢
      • 移行の与える影響は,architectureの全体的な設計においても考慮されるべき
  • 一般消費者向けsoftwareの未来
    • softwareのlicenseはrental, subscriptionが望まれる
      • 持続性があり,信頼性も高く,高速なインターネット接続を経由してWebサービスへ接続するようになる
    • 一般消費者向けsoftwareの環境も,enterpriseクラスのsoftwareと同じように複雑になっていく
  • まとめ

    • deployment_architectureとは,顧客の使用するシステムがどうやってデプロイされるのかを説明するもの
      • 一般的な選択肢
        • client siteへのdeployment
        • application_service_provider
        • managed_service_provider
        • 様々な種類のservice provider(xSP)
        • Web service(transaction応答型サービス)
      • 今後は,hybrid形態が一般的になっていく
    • deployment_architectureの選択におけるclientへの影響
      • 管理統制に関する要望
      • ほかシステムとの統合
      • dataのsecurity/privacy
      • peek_loadを捌く処理能力
      • 初期コストと保守コスト
      • 信頼関係
      • systemを運用するスタッフのスキルと経験
    • deployment_architectureの選択における自分たちの所属する会社からの影響
      • 理想的なsales_cycleと実際のsales_cycle
      • infrastructureへの投資
      • cash_flowに代表される財務モデル
      • 効果的で素早いclient基盤の管理
      • client側拠点に合わせた地理的な広がり
    • どのdeployment_architectureを選択しても,うまくシステムを管理するために必要な作業の全体量は変わらない.変わるのは作業の分担
    • information_applianceは,幅広い環境におけるdeployment_architectureにおいて,成長し続けている分野
      • open_sourceの契約モデルは所有者にとっての全体コストを下げてくれており,成長を支えている
  • checklist

    • 自分たちのdeployment_architectureはtarget_marketにおける次のいずれかの要望に合致している
      • 管理
      • 統合
      • データのsecurity/privacy
    • 有用な性能モデルがあり,自分たちのdeployment_architectureが期待されている仕事量を処理できる
    • 適切な運用policyを定めている
    • 自分たちのdeployment_architectureでは,次の事項についてどのような選択をしたのか説明できる
      • sales_modelとsales_cycle
      • infrastructureへの投資
    • clientにやってもらう作業の量を定義している

Ch08 integration, extention

  • integration: systemがどれくらいほかのsystemと連携できるか,またはどれくらいほかのsystemと連携しなければならないかを表す度合
  • extention: systemを元にしてextended_productを作り出すとしたら,どれくらいextendできるかを表す度合
  • clientをやる気にさせる--原動力
    • integration/extentionとも,複雑なシステムならどちらでも,より優れたproductを作る能力が得られるという同期
    • 自分たちが管理しているという感覚から,作業が増えても満足度が上がるケースがある
    • integration/extentionの動機
      • 予測はできないが計画はできる
        • 統合や拡張のための方法をclientに提供することで,未来を予測できなくても未来に備えることができる
      • clientはできませんと言われるのを嫌う
        • 統合したり拡張したりする戦略が必要
      • 大規模なsolutionは複数のより小さいsolutionから構成される
    • 自分のsystemにはない情報がほしい
      • 興味を引くreportや分析結果のために,別のシステムの情報と組み合わせる必要があることがある
    • 切り替えコストを増やしたい
    • productのecosystemを作りたい
    • column: 何かと組み合わせなければならない
      • 他システムとの統合が前提のケース
    • 一般常識
      • 優れたtarchitectは,どんなときでも何らかのAPIをシステムに追加して,自動かテストframeworkによる厳格なregression_testを容易に行えるようにしている
      • 優れたmarketectは,この技術的な資本を活かす方法を考える
      • featureをproductに追加するために必要なのはdocumentを用意することだけ
      • APIを提供することをclientに対するcommitmentとして,初めから開発活動に含めるべき
      • APIを利用する関係者との信頼関係は長期間続く
  • layered_business_architecture: logic_structure
    • business_applicationのsystem_architectureとして最も一般的な物の1つに,subsystemを論理的にも物理的にもlayer化するというものがある
    • ui layer
      • userに情報を提示するとともに,情報に対するuserのinteractionを管理する
      • applicationの国際化に関する作業のほとんどを引き受ける
      • simpleなcommand_line interfaceがおすすめ
        • 自動化テストが容易
    • service layer
      • application固有のさまざまなserviceを提供
      • serviceとusecaseは似ている
        • 1つのusecase全体が1つのserviceとして表現されることもあれば,1つのusecaseのなかの1つの手順がserviceに相当することもある
    • domain_model layer
      • businessの重要概念やapplication domainの規則を表現
      • enterprise applicationにおいてこのlayerは付加的なもの
      • このlayerが必要になるのは,単純なサービスでは表現しきれないほどbusiness ruleが複雑だったり,構造化されたobjectをメモリ上で表現した方がより効率的な場合くらい
      • domain_modelが必要とされるときは,applicationの中核として生まれ出ることが多い
        • 正確性が重要
      • domain_modelとpersistence_data_modelは実際はほとんどのapplicationのtarchitectureにおいて同一
      • domain layerをuiやtransaction管理layerから分離しておくと,system開発はかなり柔軟になる
        • 基盤となるapplication logicに手を入れることなく,service agent向けに表示する画面を,interactiveな音声対話システムやWebページに置き換えることもできる
        • 凝集度も高まる
          • architectureを構成するそれぞれのlayerは関連する操作の集まりに責任を負う
      • 先だって設計しておけば,uiを設計する際に役立つ
      • domain_modelの提供する公開interfaceに従ってuiを実装
    • persistence_data layer
      • ほとんどのbusiness_applicationは,persistence_storageに格納したobjectの管理をDB管理システムに任せている
      • domain layerのobjectとrelational_DB内のobjectの間のmappingを管理するlayerを別に設けるやり方が一般的
      • 基盤となるDB schemaとの連携を効果的に,かつ簡単にするために,domain_modelを構築した方がよいことも珍しくない
      • DB schemaが以上に複雑だったり,性能要件があまりに厳しいときは,domain_modelは取り払ってservice layerとDB schemaを単純に結びつける方が良い
      • business_logicをDBの中に移す
        • portabilityを損なう
        • persistence_data layer teamがSQLを効率的に使えていないことにもなる
        • それでも,慎重を期した上で移す方が適切な場合もある
          • 性能
            • 巨大なDBのときは特に
          • 高度な制約付きdataを扱う場合
            • 条件付きでデータを削除する場合など
          • dataの操作がどうあれ,何らかのアクションを行われることを保証したい場合
            • DB layerでシステムを統合することを許すような場合は特に重要
    • themeに応じた変化形
      • distributed_computing, legacy_systemの統合, 構造的な関係性, 特別なDBのサポート, 特別なhardwareのサポートなどを考慮する場合
  • layered_business_architectureの構築
    • ほとんどのlayerの基本的な部分は,スパイクと呼ばれるprocessで構築
      • スパイク: 利用者の目に見える機能をtarchitectureに含まれるすべてのsubsystemやlayerを通して適切に実装するprocess
        • すべてのsubsystemをまたぐ特定の機能を「通す」という特徴
        • subsystem間のつながりのための釘
        • incremental_developmentのための手法
        • 最初のスパイクはarchitectureの基本的な部分を検証し,risk_managementの土台となる
        • 開発の起点はservice layerかuiのどちらか片方で決める
    • serviceの定義が重要
      • service interfaceを正しく決められれば,残りのtarchitectureを正しく組み上げていくのはずっと簡単になる
      • すでに存在しているserviceを元に,新しいserviceの実装もできる
    • DB設計から始める場合もある
      • 既存の膨大なデータを扱う必要があったり,persistence_storageの要件が極端な場合など
    • 並行開発
      • architectureにおける中心的なsubsystemを早い段階で確立することが重要
        • subsystemのinterfaceについて合意
        • subsystemの同期を保証するために日次または週次でビルド
      • service/domainどちらかのレイヤから始めることに合意する必要
    • column: 全layerをスパイクする
      • 機能がすべてのレイヤを通ることが重要
  • business_logic layerにおける統合と拡張
    • technologyと制御ポイント
      • technology
        • service architectureやmodelを上手く設計し,target_marketの必要とするtechnologyをサポート
      • 制御ポイント
        • 呼び出し元が主導権
          • applicationは結果を生成
        • システムが主導権
          • 登録モデル,callback modelで呼び出し元が何らかの機能をシステムに登録できるようにする
    • APIによる結合
      • ほかのapplicationから統合したいという要望のために使われる
      • service layer自体の公開が直接的なやり方
      • 考慮
        • platformの傾向
        • market_segmentの傾向
        • partnerの傾向
        • 命名規約
        • security. session information
        • clientが必要なものだけを公開
          • security access controlで内部向け/拡張向けを管理
      • column: timingがすべて
        • session_managementの動作をclient向けに明確に表現する必要
      • releaseを重ねるごとに安定
      • できることを明確にする
    • registrationによる拡張
      • registration: developerが何らかの方法で自分のcomponentやcallback_functionを登録して,applicationのcapabilityを拡張する処理のこと
      • 制御ポイントはシステム側
      • e,g, web_browserのplugin
      • callback, listener, plugin, event_notificationなどの仕組み
      • 検討事項(伝えるべきもの)
        • registration modelを定義する
          • registration可能なcomponentを構築するためのprogramming_languageについて,詳細な技術情報をdeveloperに提供する
        • event modelを定義する
        • 実行制御semanticsを定義
          • timingに関する要件
        • resource_management policyを定義
        • error/exception protocolを定義
  • persistence_dataの統合と拡張
    • view
      • DB_schemaのデータの使われ方と,実際の定義を橋渡しする中間層
    • column: business_logicをDBに組み込む
      • 必要な場合もある
        • より単純で効果的な場合
        • clientに統合オプションとして提案できる安全な方法がほかにないとき
    • user_definition_field
      • 些細な利便性に対して,本当にapplicationにとって適切なのか判断が必要
    • table_hook
      • 関連の完全性の強制は難しい
      • 遅延の可能性があるのでできるだけ小規模にする
    • 表計算ソフトのpivot_table
      • dynamicなreport生成のためのcapabilityが必要なときの例
    • ETL(Extract, Transform, Load) script
      • DBに格納されている構造化データを操作しやすくするために設計された,utility program
      • tarchitecture的な見方として,clientが確実に正しいデータを得られるようにできる
      • marketecture的な見方として,ETL_sctiptを製品化して利益を得られる
        • product全体の価値を大幅に高められる
      • column: ETL_sctiptに課金する
    • 何が起きているのか伝える
      • data dictionary, data, table, 命名規則, 特定のカラムの値の大事な意味などを詳細に記したドキュメントを公開する
  • businessへの影響
    • 専門サービス部門
      • clientが統合によって目標を達成するのを手助けしたり,質問に回答したり,環境で動いているシステムを統合するのにかかる時間を短縮したりする
      • marketectが価格付けを支援する
      • marketectは専門サービス部門から上がってきた要望をdevelopment_teamに連携する
      • 開発部門は,APIの使い方を示すsample programを作成する
    • 研修program
      • target userの具体的な目的に合わせる
      • clientの満足度を高め,サポート負担を軽減
      • tarchitectはbest practiceを捉え表現して伝える研修教材を作る
      • systemの設計や統合拡張の方法の理解を深める
      • stakeholder全員への考慮が必要
      • column: どうやってdocumentを追加するか?
        • documentの重要性
    • 資格認定
      • market shareが十分に大きいときのみ
      • 検討事項
        • product ecosystem
        • 競合優位性
        • 流行
        • professional認定
        • 独立した資格認定
        • 学術的な信用
    • user_community
      • 一次情報源
      • marketectが健全で活発なuser_communityを探して支援する必要
      • 手掛かりとなりそうな活動
        • community_Web_site
          • 企業が用意する
        • 教育素材
        • column: ありがとう,でも自分たちのuiは自分たちで作るから・・・
          • userが好みのuiを作ることもある
          • uiへのニーズはそれぞれある
        • mailing_list
        • user_conference
    • 使用許諾契約
      • APIの仕様を必要以上に制限する文言がないことを法律部門に確認
      • column: testにlicenseは要らない
        • 同上
  • 複数回のreleaseに向けてAPIを管理する
    • 統合や拡張のtechniqueを用いているclientが,どんな変更に対してもそれに向けて計画し適応するための時間を取れるようになる必要
    • technique
      • 十分すぎるくらいに警告を出す
        • n+1回目のreleaseの内容をn回目のreleaseで周知
      • 1 release分の共存期間を設ける
      • 後方互換性layerを設ける
      • 廃止されたAPIの呼び出し箇所を特定したり置き換えたりする自動ツールを用意する
  • まとめ
    • integration: systemをprogram的にほかのシステムと接続するprocess
    • extention: plugin architectureのように,明確に定義されたやり方でsystemに新しい機能を追加するprocess
    • integration/extentionによって,clientが探し求めているproductを構築できるようになる
      • 副次的な効果として,clientとの関係性がより密になり,競合他社への乗換リスクが軽減
    • layer化architecture_patternとは,論理的,物理的なlayerによってシステムのさまざまな機能を構成するもの
      • enterpriseクラスのsoftware_systemにおける統合や拡張に際して非常に優れた選択肢
      • main layer
        • ui
        • service
        • domain_model
        • persistence_data
    • architectureがどんな構成でも,スパイクが必要
    • service layerやdomain_model layerに統合や拡張の口を設けるやり方はいくつもある
      • 公開されたAPIを利用
      • Web_browserのようなplugin architectureでcomponentを登録
    • persistence_dataの統合・拡張を実現する手段
      • view
      • table_hook
      • 表計算ソフトのpivot_table
      • ETL_sctipt
    • 統合や拡張が可能なapplicationがbusinessに与える影響
      • clientを誘導する専門サービス部門
      • clientが自分たちが何をすればよいのか理解するための研修program
      • applicationのecosystemを作るための資格認定program
      • applicationを取り巻くuser_community
      • integration/extentionを明示的にサポートする使用許諾契約
    • applicationの統合や拡張に際してclientと接することになる方法はすべて,慎重に管理
      • それらの安定性について公にcommitmentしているため
  • checklist
    • system integration/extentionを可能にするやり方それぞれについて,clientが期待した結果を得られるよう,support資料を備えている
    • applicationがどのように外部のapplicationと統合されるのかをcontext_diagramで示している
    • 一貫したAPIを提供するための命名規則がある
    • APIの性能や呼び出しごとに消費されるresourceについてdocument化されている

Ch09 brand, brand_element

  • brand_element
    • 名前
      • system_componentの物理的配置
        • 会社名/product name/sub component nameが〇
        • product name/sub component nameとなることもある
        • 認知や拡張について〇
      • 主要componentの名前
        • 重要な戦略
        • marketectやmarketingの知見を持つ人が命名するべき
        • 何をするものか技術的に正しく伝わる必要がある
        • 実装と名前の乖離は正当化できる
          • 変更にはコストがある
          • marketectureと関わる名前の変化は技術的な面よりも遅い
        • column: developerが名前をつけるべきなのは変数名くらいで,product名をつけさせてはいけない
          • 良いproduct nameは成功の可能性を高める
          • enterprise marketでは,product名以外の要素が支配的
            • 提供元企業に興味がある
      • 名前の国際化の必要性
      • brand_elementは設定ファイルやログファイルにも潜んでいる
      • brand_elementはerror_message, diagnostic_message, information_messageにも潜んでいる
      • 名前は変わりやすい,最初のreleaseならなおさら
        • codenameのようなもので当面は呼んでいた方が良い
    • 見た目,スローガン,その他のbrand_element
      • icon, splash_screen
      • brand_color
      • 音声のbranding
    • trademark(™)記号を使うべきタイミング
      • 法律上の権利を保護
      • 注意を促す
      • 商標記号は形容詞としてだけ使う
      • productを配布するときや,productを利用しているときは,登録商標を表示する
      • 法律上の制限はあるものの,internet domain nameはtrademarkにできる
  • in_license_brandの管理
    • 適切に扱う必要
    • column: 続行するためにOKをクリックしてください
      • splash_screenを扱う必要があったとき
  • brand_elementのカスタマイズ
    • marketectは開発サイクルの早い段階で要件を具体化する必要
      • どの要素が変更可能/変更すべきかを把握することが最重要
        • 前者は常識的な初期値を決定,後者はカスタマイズの手続きの定義が必要
    • 正確で詳細な情報の伝達
      • bitmap画像の大きさ,サポートする画像形式,brand_elementとしての既定値など
      • brand_elementをカスタマイズするための特別な契約が必要な場合もある
  • brand_elementの変更
    • 困難な理由
      • brand_elementの変化は大変ゆっくりしたもので,変更できるようになっていない
      • brandがproductやarchitectureに与える影響が分かりにくい
    • productの関連要素への影響
      • subsystemの名前
      • source_code repository
        • product nameそのものが使われていなければ問題ない
        • product nameに合わせている場合は必ず同期する
      • 品質保証と技術サポート追跡システム
        • categoryについて,実際のproductとの差異を小さくするよう保守
      • componentの物理的配置
      • APIの名前と構造
      • error_message, log file, diagnostic_message
      • 品質保証processと自動化テストのinfrastructure
      • 販促品
    • 変更と品質保証
      • brand, brand_elementの変更にあたって,品質保証は非常に大きな役割
  • まとめ
    • brand_elementは,tarchitectureに対して,すぐにはわかりにくい影響を広範囲に与える
      • icon~install先にまで及ぶ
    • product nameを考えるのはmarketectの仕事
    • brand_elementの国際化は難しい
    • product nameに関するさまざまな法的表示の使い方の理解
    • in_license technologyはbrand_elementとしての要件を強制する場合がある
    • product nameを変更する際は,あらゆる観点のclient experienceを総合的にreviewする
  • checklist
    • 必要なbrand_elementはすべて整理したうえで合意できているか
    • すべてのbrand_elementが必要に応じて国際化されているか
    • error_message, diagnostic_message, log fileに,合意済みのbrand_elementがきちんと反映されているか
    • 登録商標やtrademarkなどの記号が適切に使われているか
    • partner企業や技術license供与者による変更など,置き換えられる可能性のあるbrand_elementが明確になっているか

Ch10 usability

  • 性能と拡張性について
  • tarchitectureがusabilityに与える影響,特に性能を改善する要因としての影響を見る
  • usabilityはお金になる
    • usabilityはuiよりもはるかに奥が深い
    • ほとんどの場合tarchitectureが影響している
    • user自身と,systemを利用する状況の両方の理解が必要
      • marketectにとっては,システムの競争上の優位性を保証するため
        • userにとって最も重要なニーズを確実に満たし,長期にわたって友好関係を築くために必要な基礎を整えるためでもある
      • tarchitectにとっては,性能や国際化などをより一層追及したcapabilityを構築するため
      • usabilityの量的,質的な指標になる
          • 性能やデータ入力エラー率など
          • 満足度や理解のしやすさ
    • userを理解するための手法
      • 観察,interview,質問,〇直接体験
        • 直接体験: 経験的な要件
    • usabilityはproductの生涯にわたって見返りをもたらす
      • merit
        • 研修コストの削減
        • support, serviceコスト削減
        • error発生時のコスト軽減
        • userの生産性の向上
        • client_satisfactionの向上
        • 保守性の向上
    • column: market needsとusability
      • usabilityのmeritは社内でもmarketと同じように受け入れられるはず
  • mental_model, metaphor, usability
    • userがどのようにタスクに取り組むかについて理解が深まれば,そのタスクについてのmental_modelを理解できるようになる
    • mental_model: 世界の物事を説明したり,simulation,予想,制御したりするうえで,心の中に抱く一連の考え方や構造のこと
      • taskやそれを達成するためのツールに応じて形成される
      • 時間とともに変わっていく
    • 概念モデルはmental_modelの表現の1つ
    • mental_modelを理解し,概念モデルの役割を明確にする → metaphorを生むための基盤
      • metaphor: systemを作ったり修正するために使える,ある物事の理解を助けるために別の言葉で表現するもの
      • tarchitectは,application architectureを説明するのにmetaphorを使うことが多い
      • よいmetaphorは,tarchitectureとuiの両方を具体化してくれる
      • tarchitectが選んだmetaphorが,明確に定義されたmarketに対して適切なやり方で伝えられる必要がある
      • metaphorはbrand_elementや価格モデルにも影響する
        • systemが最大の価値をもたらす特定のmarket_segmentがmetaphorによって強調 → 価格モデルに影響
      • 完全に新しいproduct: productの機能や提供の仕方を伝えられるかどうかmetaphorによる
      • これらのすべての理由から,metaphorはmarketect/tarchitectが密に連携して開発する必要がある
    • metaphorはusabilityに影響を与える点で特に重要
      • training cost激減,満足度急上昇,システム全体が快適になる
  • ui設計におけるtarchitectureの影響
    • 影響範囲
      • cardinality(濃度)
        • あるrelationに参加しているentityの数
        • tarchitecture全体とui設計それぞれで必要
        • 増加し続ける大規模なデータを可視化するツールは幸運にもたくさんある
      • feedback
        • 最も重要なheuristic(探したり発見するのに役立つ → 発見的(手法))の1つ
        • e.g. progress bar
          • tarchitecture上の課題がいかにしてui設計に影響するかの例
        • validationなど,最高のusabilityを得るにはそれぞれのdeviceごとのcapabilityを理解する必要がある
      • 明示的なuser_model
        • systemの振る舞いをmental_modelにあうように調整する
        • e.g. word processor
      • workflow support
        • workflow: ある種の目に見えるuser_model
          • mental_modelへの理解の上に成り立つ
      • transaction support
        • transactionはuiに特有のcapabilityをsupportするように設計されている
        • e.g. 情報の表示方法など
      • error_response
        • errorの表現方法に関する選択も,基礎となるtarchitectureに影響する
      • globalization/localization
        • OSやplatformはuserが言語を指定するためのinfrastructureを備えている: 大きな利点
        • development_teamの設計上の選択がglobalizationを困難にすることがある
          • e.g. 部品を固定サイズにしてしまうこと
        • userの目に触れる情報はsource_codeには埋め込まず,何らかの識別子を参照する必要がある
        • development processのできるだけ早い時期に,対象言語を定めるべき
        • column: 詳しく,もっと詳しく,もっともっと詳しく
      • requestの中断
        • requestを区別するための識別子が必要
        • かなりのコストがかかるが,見合うだけの成果がでることもある
      • requestの取り消し
        • transaction managementやpublish_subscribe protocolなど洗練されたtarchitecture設計では,状態が共有されていても適切に取り消せるcapabilityを提供できることもある
        • 高機能なuiがありapplicationの永続状態が適切に反映されていれば,操作の取り消しに意味があるかどうかを判断するための情報をユーザに提供できる
      • transactionの相殺
        • 設計の早い時期に追加することでusabilityは劇的に改善する
      • timeout
        • 初期値の選択は非常に繊細な判断が必要だが,うまくやればusabilityが改善する
        • sessionに関するparameterをsystem administratorが変更できる必要がある
      • network_availability, network_speed
        • userの置かれる状況を考える
      • shared_resource
      • 障害回復
        • systemが障害を制御して,妥当なやり方でそれを復旧するのが望ましい
        • systemに関連することはユーザに注意を促す方が好ましい
  • speedの必要性
    • 話している対象をはっきりさせよう
      • 性能用語
        • throughput
        • performance
          • throughputの逆数
        • latency
        • capacity
          • entity数
        • scalability
        • reliability
        • response_time
      • 最小限未満,最小限,平均,理想,最大限
      • ますはシステム構成を特定(「固定」)
      • 次に,テストしたいtransactionあるいは操作を特定し,利用するデータを用意する
      • systemの性能は線形増加しない
      • queueの上限を知ることは重要
        • serverが処理できる最大のバーストがわかる → 信頼性を構成する要素の1つ
      • systemの応答に関する心証は性能値と必ずしも一致しない
      • response_timeはできるだけ短いほうが良い
        • 5s~10s以内である必要
      • 故障への適切な対応 → 信頼性の一因
      • user_modelの定義が重要
        • 多様な操作のsupport
        • 本番環境で取得したシステムの操作に関連したログファイルを使うと,優れたuser_modelを導ける
      • testの複雑さについて,性能の見積もりは控えめを心がけるべき
    • marketectが性能について心から望むこと
      • 性能に関連した質問について,自信に満ちた,信頼できる,正しい回答をしたい
      • 新しいreleaseや推奨hardwareの変更があった場合は,性能を計算しなおす必要がある
        • 性能改善が期待される
    • userに応答を返す
      • 本当に一瞬で応答できないなら何らかのfeedbackが必要
      • feedbackの仕組み
        • 即時的(1s~2s)
          • 共通objectの見た目を変える
          • 音声で応答
        • 継続的(2s~)
          • 共通の「繰り返し」animationが〇
          • progress indicatorを,中断できないタスクはステータスバーに,できるなら別のdialogue windowに表示する
          • 時間の見積もりは精度が重要
        • column: feedbackは不要なタスクを軽減
          • response_timeとfeedbackはシステムの性能に対する定性的で心理的な認識
          • 心理的に許容できる応答を返すことは低コストで効果がある
    • 性能とtarchitecture上の影響
      • hardware任せの問題解決
        • 最も簡単
        • tarchitectureのscalabilityが理解されている場合だけ,適切に機能する
      • 粗粒度transactionを使う
      • thread処理が性能に及ぼす影響
      • profilerで計測
      • 通常の処理と異常時の処理を分離
        • 通常時は高速,異常時は適切さが必要
      • 結果をキャッシュする
        • 誤った結果を返してはいけない場合を特定しておく必要
        • dynamicにcacheの有効無効を切り替えできるarchitectureが必要
      • background_processing
      • self_serviceで使えるように設計
      • platformのidiomを学ぶ
      • taskを減らす
  • まとめ
    • usability: systemが備える属性で,ユーザが必要なタスクを完了させるうえで簡単に,効率よく,最小限のエラーで済むようにするためのもの
      • 使いやすさ: 目的を達成するためにfrastrationを全く感じないか,ごくわずかで済むこと
    • usability: product brandingにとって中心的feature, productのあらゆる面に関係する
    • 成功するsolutionのusabilityは優れている.長期的な利益に貢献
    • mental_model: 観測しているものを説明,模擬,予想,制御するための考え方や構造の集まり
    • 概念モデル: mental_modelの何らかの表現
      • 言葉/図,形式的/非形式的
    • metaphor: あるものを別の観点から理解するためのモデル
    • uiをtarchitectureから分離することで保守性が高まる
      • 絶対確実な方法はない
    • 性能は重要
    • marketectは性能に関する質問に対して,自信をもって正確で信頼できる回答をしたいと思っている
      • especially, enterprise_software
    • 性能改善のためのtechnique
      • cache, background_processing, 空いているprocessorへ処理を渡す,処理自体をなくすなど
  • checklist
    • 主要なタスクのusabilityをテストしている
    • 概念モデルを描いており,userのmental_modelを理解したり,システムのmetaphorを作るのに使っている
    • systemの設計や実装を見れば,systemのmetaphorが分かるようになっている
    • 性能を定義する合意された用語集がある
      • marketing部門や販売部門が構成を見積もるための方法を提供している
    • 問題解決をhardwareに任せるのはいつなのか,どうやるのか理解し,それによりどうなるか理解している

Ch11 install

  • 設計が拙いと経済的な損失が大きい
  • OOBE(Out of box experience)
    • computerなどの端末を初めて使うときの経験を表現
    • installに関連するわかりやすい目標をmarketectがtarchitectのために設定していると有用
      • e.g. 平均的なユーザがtechnical supportに電話しなくてもinstallできるようにするというもの
    • column: installが拙いことのコスト
  • 痛い!きっと怪我をしたに違いない
    • clientが恐れていること
      • 難しすぎる
      • 複雑すぎる
      • 簡単に何かを壊してしまう
      • どのくらい時間がかかるか分からない
      • 入力する情報が多すぎる
  • installとarchitectureの関係
    • forceと選択
      • sub_componentの管理
        • installerを用意するのが自分かユーザか決める必要
          • どちらのケースもある
      • in_license_contractの要件
      • license_contract
        • EULA(End User License Agreement)
          • license_contractの一部または全てをinstall programに含めておく
      • column: 準備ができたら引き継ぎます
        • install準備programで,softwareに必要なcomponentがあること,適切に設定されていることを保証
      • business_model
        • business_modelはinstallerの作り方に影響
        • install processがbusiness_modelを実現する助けになる
      • installの責任分割
        • InstallShieldなどのinstall programにどれだけのことができるのか学習しておく
      • install先の環境
        • target_marketの環境によって望ましいprocessが異なる
      • installの役割
        • 複雑なinstallも役割ごとに対応してまとめておく
      • developerに気づかせる
        • developerにやってみてもらう
  • installのやり方
    • installのための情報を収集し,事前条件を検証する
      • 必要不可欠なすべての構成情報と,重要なcustomize情報を出しておく
      • 検証内容
        • 空き領域
        • network_connection
        • 必須entityの設定
        • access権限
          • 必要な場面を限定する
    • install
      • 進行状況を示す
      • 視覚的な見取り図を提供する
      • 進行状況をログファイルに書き出す
      • installを中断できるようにする
      • platformのガイドライン西潟宇
      • 強制的な再起動を避ける
      • 不必要な質問を避ける
      • column: cross_platformなガイドラインは存在しない
    • install後に確認する
      • softwareの実際の動作に注目
      • ログを記録
      • 後始末
      • manual
      • user registration
  • 仕上げ
    • userはmanualを読まない
      • 一目でわかるロードマップを提供する
    • install/uninstallをテストする
      • installerは最初のiterationでテストする
        • 自動ビルドprocessに組み込める
      • あらゆるoptionを試す
      • 自動化する
      • platformのガイドラインに従う
      • install処理をscript化する
  • まとめ
    • installはお金そのもの
    • ほとんどのユーザはinstallを恐れている
    • installはarchitectureの構造によって決まる
      • すべてのcomponentとcomponentの依存関係は適切に管理が必要
    • 検討中のinstall processがすべてのlicense条項を満たしているか確認する
    • softwareをinstallする典型的なalgorithm
      • installに利用する情報を収集し,事前条件を検証
      • install
      • install後に確認
    • 内部でテストするため,install processを自動化する
      • enterprise環境のために自動化しやすくする
    • とにかくテスト
  • checklist
    • install processによって,sub_componentがそれぞれどのように扱われるのかを明らかにしている
    • install processが全てのlicenseされたtechnologyの要件を満たしている
    • software_architectureのinstall担当者に求められるスキルレベルを明らかにしている,レベルは妥当である
    • installの正しさを検証する方法がある
    • install processは対象platformのガイドラインに完全に従っている
    • 平均的なユーザならdocumentを見なくてもinstallできる
    • install/uninstallをともにテストしている

Ch12 upgrade

  • upgradeはinstallよりも問題になることが多い
    • clientにとって深刻な被害を引き起こすことがある
      • dataの喪失,統合の問題,元のfeatureの振る舞いの変更など
    • 最初のreleaseの売上よりもupgradeの売り上げの方が多い,marketingの主な役割はclientの発見と関係性の維持
  • installと同じように悪いことしか思い当たらない
    • upgradeに伴う恐れ
      • 手戻り
        • 特に統合の問題
      • upgradeの連鎖
        • upgradeに関連する依存関係を全て明らかにする必要がある
      • data移行
        • DB_schemaについて,めったに変更されないもの,一度作成したら変更すべきでないもの,頻繁に変更され得るものを分離することが重要
          • 労力が大きく減る
      • data保全
      • 認証process
      • new API
        • clientのニーズに基づいて慎重な管理が必要
      • column: 一度統合したものは二度とupgradeしない
      • 新しいfeature
        • 学習コスト
      • systemにアクセスできない
      • 切り戻し
        • upgrade processの手順を入念に計画して理解を深められれば,簡略化できる可能性がある
      • column: 私はもっと違うことで困っている
        • upgradeに伴う苦痛の一覧を作る必要がある
  • upgradeの苦痛を取り除く
    • 苦痛のないupgradeのための選択肢
      • 回数とtiming
        • marketに起きるevent, rhythmを理解する必要
      • upgradeの準備
        • Ch11と同じ
        • clientが現在利用しているversionの確認
      • data移行
        • column: yesよりnoが簡単
          • featureを取り除けるのはupgrade processの間だけ
          • featureはapplicationのpersistence_dataと何らかの関連を持っていることが多い
            • 調査 → featureが使われているかどうか突き止められる
          • 最適なupgrade方法を決めるため,現在のinstall状態を評価するprogramを書くのは良い考え
            • upgradeでできること,やるべきことがわかる
          • featureを取り除く
            • development_team全体への調整が必要
            • featureの追加と同じくらい大変,たいていはそれ以上に大変
        • 移行processの間のみ移行できる
        • ツールを使う場合
        • ファイルのデータを変換するときは警告が必要
      • 設定情報とcustomize情報のupgrade
        • あわせてupgradeする
      • old version
        • clientがすべて同じold versionではない
        • 一段階移行
          • すべてを最新に直接upgrade
        • 多段階移行
          • 最新のversionへupgradeできるいくつかのold versionを部分集合として抽出する
      • 共存,または置き換え
        • 可能な限り置き換えが〇
          • ほかに削除するタイミングはないため
        • column: どのversionを使えばよいのだろう
          • 共存はテストの複雑さやサポートコストが象か
  • upgradeとmarketの成熟度
    • innovatorはほかのprocessとは異なりデータ移行についてはかなり重要視している
    • 欠陥のあるupgrade processはmarket_segmentによらず将来的に重大な問題を起こす
  • まとめ
    • upgradeは,相当数のclientにとて実に様々な形で頭痛の種となる
    • 継続的なtechnologyの進化によって,upgradeの連鎖が発生する
      • 前提となる条件を詳細に調べる必要
    • upgradeの間にclientのdataを削除しないようにする
    • clientにとって,どのくらいの頻度ならupgradeを受け入れられるのか理解する
    • upgradeの準備ができているか評価するtool
      • upgradeの影響が分かる
      • 不要な/未使用のfeatureを取り除けるか分かる
    • すべてのmarketのadopter segmentは優れたupgrade processを求めている
  • checklist
    • upgradeによって何かしら問題が生じる可能性のある分野が特定できていて,それを小さくしようと試みている
    • すべての移行パスをテストしている
    • どんなclientであろうとも,現在のversionへupgradeできるのは,以前のversionの中でも特定のversionを使用している場合だけであると定めている
    • upgradeに伴いどのくらいの停止期間が生じるのか定めている
    • upgradeを完全にuninstallし,すべてのdataを旧versionに戻すための詳細な手順を用意している
    • upgradeが正常に完了したかどうかを確かめ,もし失敗したならどこで失敗したか特定できるテストを用意している

Ch13 configuration

  • 設定しやすくすること自体が,marketectにとってもtarchitectにとっても価値ある目標
  • 設定可能性--usabilityの一因
    • costの問題
    • architectureの性質に左右される
      • module化を進めると影響も大きくなる
    • 設定に関するコストは増え続ける
    • 適切な設定parameterが必要
  • system_context
    • 設定parameterに反映する必要があるもの
    • systemを適切に機能させるために必要な,あらゆる側面におけるcontextの情報
    • 取得・設定できるようにすることで,developmentのときとdeploymentのときそれぞれで設定できるようになる
    • contextの情報
      • tarchitectが整理する
      • 主要なfile, directoryの配置
      • 起動するための情報
        • 情報が失われた場合も,必要最低限の機能を提供できるようにしておく
      • portability switch
      • 互換性の制御
        • clientと問題を共有して,いくつくらいの設定parameterを使って対応するか決めてもらう
      • 性能parameter
        • 高度に洗練されていれば自動調整もできる
        • いくつかの簡単なparameterは利用者が調整できるようにしておく
      • column: 過ぎたるは猶及ばざるが如し
        • 設定しないとシステムが動作しないものだけを設定parameterにするべき
        • 必要な場合は,変更可能なparameterとして妥当な初期値を設定しておく
  • 初期化と実行
    • 実行中にも設定を変えられるようにしておく必要があるもの
    • 透過的なparameter
      • 実際はapplicationを素通りしてin_license componentに引き渡されるparameter
    • tarchitectは,初期化中と稼働中それぞれのtimingでどの設定を扱うべきか検討が必要
  • 値を設定する
    • system administratorのような人間,system間の相互通信によって値をやりとりしたり指示を受け取ったりするような他システム,1つ以上の値を自動的に設定するように構成されたシステム自身の3つのentityが連携して設定する
    • それぞれにそれぞれの権限がある
    • marketを念頭に置いてどのentityによる変更を優先するか決定する
  • 適切な値を設定する
    • parameterの影響を受けるユーザのニーズと,それを設定するユーザのニーズの両方を満たす必要
    • 複雑になるほどusabilityを損なう
    • どんな値を,どうやって,なぜ設定するのか,システムの運用にどのような影響があるのかの理解が必要
      • 設定ファイル自身に記載する
  • 設定parameterのheuristics
    • 簡単に変更できるよう,そして,たとえシステムのほかの部分がダウンしていたとしても変更できるようにする
      • 単純で管理もしやすい平文のまま,システムの外部に配置する
    • 全ての情報を一か所に配置する
    • 分かりやすい場所に分かりやすい名前のファイルを配置する
      • 「システム設定情報」のような名前で,installしたapplicationのroot directoryに出力するなど
    • XMLは,単純で必要に応じて詳しく書け,管理もしやすい
    • Windows registryのようなものを使う場合は十分に注意する
      • 移植性がなく,技術に明るくないユーザが変更するのは困難
    • 設定情報の取得と技術サポートへの送信を簡単にできるようにする
    • 設定する値を間違いにくくする
      • 間違えたら,すみやかにユーザに伝えて,システムを停止するか,妥当な初期値に変更して続行する
    • 対故障性に優れた設計では,設定parameterを何らかのentityやobjectの属性を永続化したものとして扱う
      • ほかのobjectやsubsystemはこの設定objectを介して情報を取得できるようになる
        • file管理も関知不要
      • 検討すべきobject
        • system context objectでシステム全ての環境の情報を格納する
        • computer, service instance, user, user profileそれぞれを表すobject
        • 設定情報の意味を理解するobject
      • あとからつじつまを合わせるのはとても面倒
  • まとめ
    • 設定とは,usabilityにおけるきわめて重要な観点
    • 設定parameterはsystem_contextを表現できるように設計される必要
      • system_contextの定義
    • systemの設定が必要なtimingは,実行前と稼働中
      • 実行中に設定を変更できるようになっているとデバッグしやすい
    • clientが自ら適切な設定をするには支援が必要.労を惜しまないようにする
  • checklist
    • systemのすべての設定parameterを決定
      • それぞれのparameterについてsecurityと監査の要件を規定
      • 初期化中にだけ設定を使うのか,実行中に変更できるようにするのかも決定
    • それぞれのparameterの設定方法をdocument化し,正しい設定をするための手引きを提供

Ch14 log

  • column: たとえ後からでもやらないよりはマシ
    • logは掛けた手間に見合う成果ある
  • 何が起きているか知りたい
    • log category
      • debug, error
      • error recovery
      • performance tuning
      • capacity planning
      • 行動追跡と監査
      • system configuration
      • 運転状態
    • 正しいcategoryに出力する
    • logにはsystemが生成した情報だけを出力する
      • 付随的な処理に過ぎない
    • column: 2つに分けるくらいなら,分けない方がマシ
      • eventの種類ごとに適切な識別子をつけて,1つのlogファイルに出力
  • 事実だけではない
    • logの生成には,起きていることを表現するのに十分なcontextを含める
    • logはprogramのtraceをきれいに見せるためのものではない
      • developer用のデータを出力するログは別のファイルにするのが〇
  • logの書式と管理
    • logの書式
      • globalization
      • timestampを千t脳に出す
      • source_code中の位置を特定するための識別子を付加する
      • transactionを特定する方法を提供する
      • flatfile出力
        • 解析しやすい
        • 読みやすい
        • 常識的な場所に出力
        • 常識的な命名
        • ゴミや特殊文字を含めない
        • documentを書く
        • 突き合わせ,および監査のための識別子を付与する
    • logの管理
      • dynamic logging
        • logのparameter(詳細レベルや出力対象など)を実行中に変更できる機能があると〇
        • 必要に応じてlog出力
      • threadごとのlogging
      • log level
        • 開始と終了に加えて,詳細レベルの指定を可能にする
        • logに出力されるべきか表す数値の割り当て
        • 補完として,labelづけもある
          • e.g.
            • debug
            • information
            • warning
            • error
        • categoryに従う
      • API
      • 設定可能な構文
        • 異なる書式の方が処理しやすい場合もある
      • あらゆる例外をログに出力
      • 消せるようにする
        • ファイル名に日付があると消しやすい
      • security
        • 暗号化,権限
      • 転送の自動化
    • loggingの標準とlibrary
      • platformへの依存の有無
      • libraryは代替手段
      • column: logのreuseには十分に気を付ける
        • userが変更しやすいなどの問題になる
  • logの後処理
    • 圧縮サービス
      • 循環ログなども〇
    • 同期ツール
      • logの時間の同期を保証
    • log viewer
  • logging service
    • loggingをdevelopment_teamに提供するサービスとして考えることは有用
    • 賢いログを実装することに伴う複雑さを抽象化
    • ほとんどはsingleton
    • 中央集権的なサービスとして実装するmerit
      • globalization
      • 時間的な順序の統一
      • 柔軟な出力先の選択
      • 複数のinstanceやサーバを跨いだ統合
        • log file nameやその内容に,instanceやserverの情報を付加
          • e.g. processやthread id, machine IP address
  • まとめ
    • logが情報提供以外に支援する活動
      • debug
      • error recovery
      • performance tuning
      • capability planning
      • 行動追跡,および監査
      • system configuration
      • 運転状態
    • logは利用者目線で構成が必要
      • 文脈を表す情報を含めるべき
      • 分析しやすいように構成
    • log fileが運用や環境に与える影響を評価
      • disc領域が不足しているときの異常発生などにも適切に処置できるようにしておく
  • checklist
    • log fileそれぞれの目的が定まっている
    • log fileそれぞれについて,利用する立場になって有用性を確認した
      • 適切な情報が適切な書式で含まれているなど
    • log fileからdeveloper専用のdebug informationを注意して除去した
    • log fileはui部品のために用意されたglobalization guidelineに従っている
    • log fileはsystemのほかの部品のために用意された可搬性guidelineに従っている
    • log fileは分析しやすい

Ch15 release_management

  • release_management
    • clientに対して正しい成果物が出荷されることを保証する
    • 説明ラベルをつけて成果物を特定・整理・管理
    • SKUあるいは部品番号によってしかるべきback_office_systemに統合する
    • 構成管理と密接な関係
      • 構成管理
        • systemの構築中にさまざまなcomponentや関連する成果物を特定・整理・管理するprocess
  • 本当に必要なのだ
    • 変更管理が必要になる
    • 構成管理の影響
      • teamwork
      • componentの必要条件の理解
        • 問題発生を防いだり診断したりしやすくなる
      • messaging_systemでは,messageにversionの識別子が必要
        • 内容や処理条件の変更を管理
    • release_managementはclientに必要
      • どのversionを発注したのか,以前のversionと互換性があるのかどうかを知っておく必要
      • 利用可能なパッチやupgradeが自分たちの環境で自分たちの発注したversionに適用できるかどうかも知る必要
    • 複雑な問題
      • technology自体の観点もあるし,基盤となるtechnologyによっては選択肢がないこともある
  • baselineの確立
    • 用語
      • program family
        • すべてのcomponentのすべてのversion全体
      • component/成果物
        • system内部で個別に識別可能な最小単位
      • version
        • 固定・凍結したcomponent/成果物
        • source_codeと派生物(object code, API document)のバージョンの保守が重要
        • 内部用と外部用それぞれのバージョン識別子が必要
      • revision
        • component/成果物の新しいバージョン
        • 以前のバージョンの置き換えを意図したもの
      • variation
        • componentやその他の成果物の代わりになる実装
        • OSごとのsoftware componentなど
      • distribution
        • 特定のclient群に配布するために作られたバージョン
        • 1つ以上の保証されたcomponent/成果物から構成される
      • release
        • 命名されバージョンが払いだされたcomponent/成果物の集合
        • revisionとは違い,必ずしも線形ではない
    • 依存関係や前提条件の管理が重要
      • ほかのcomponentの特定のバージョンに依存するcomponentを内包していることが多いため
  • release_management
    • 何をreleaseするか
      • 完全なrelease: product全体のrelease
      • 部分release
        • base systemのcapabilityを拡張
        • option moduleなど
      • patch_release
        • install済みで既知の不具合がある1つ以上のcomponentを完全に置き換えるもの
        • 機能追加などは×
      • いずれも同じrelease process
    • 対象は誰か
      • alpha releaseは内部userが対象,ほかは外部user
      • 限定release, 管理releaseは特定のclientに対して行われるrelease
      • 誰を対象: scope, 何をrelease: size
        • 混同しないようにする
      • clientの利用状況などの理解が必要
    • なぜそれが必要か
      • アメとムチの使い分けでmarketectはclientにreleaseを受け入れてもらうようにする
      • install baseをできる限り最新に保つことが,marketectのメインタスクになる
      • どのversionからでも最新バージョンにupgradeできるようにする必要
        • 手順がややこしくなったとしても
  • releaseの識別子
    • clientがreleaseを識別できるようにするために使われる
    • 完全な識別子
      • product nameと,productの適切なrevisionやvariationを含むversion情報によって構成
      • 目的: 必要な情報をできる限り短い名称と識別子で表現 → 全体的な効率が改善
    • 完全release
      • product name + revision情報を表現するための4桁の数字文字列(x.y.z.ビルド番号) + 任意のvariation識別子
        • x: major
          • clientから見えるarchitecture, featureの変更
            • marketectが合意し,変更内容を定義
          • business上の理由もある
          • client全体にできるだけ早く配布する目的意識をmarketectは持つ
        • y: minor
          • 望まれるfeatureやその他の改善
          • marketectはバージョンをあげる契機となるイベントをすべて定義する必要
        • z: 保守, dot
          • x, yを共有するほかのdot releaseと互換性が必要
      • marketingのためには,clientにはmajor, minor numberのみ見せるのが〇
        • 管理コストを減らすため
    • 特別release
      • 識別子の形式は,ほぼ完全にmarketingの要因に依存する
      • 基本的な配布物のoptionになっていたりする場合は,4桁の数字文字列の識別子が〇
        • 命名規則が一貫
          • option componentに対するmental_modelを構築しやすくなる
          • 入手可能なproductすべての一覧の作成も容易になる
      • 一意の識別子があればよい
        • 特別に定義した名前と日付があれば十分
      • 課題
        • componentや機能の間の依存関係とそれらに対するproductの依存関係の管理
          • release_cycle識別子を管理するruleやarchitectureの設計を通じて表現
      • 互換性のruleを守る必要がある
    • patch_release
      • productのsubset
      • 既知の不具合を含むcomponentを正確にreplace
      • 識別子の採番方法の問題
        • どんな場合でも実際に使われている機能に関係がある
        • 既存のproductに強く依存しているので,patchの識別子からproductを参照できるようになっていると分かりやすい
        • 原因と紐づけるため,名前と日付の参照
        • product name-x.y(.z(.build number))-patch nameとなる
        • 複雑なproductの場合は,patchで影響を受ける領域を示すこともある
          • technical supportのWebサイトでどのパッチをダウンロードすればよいかclientが見つけやすくするため
          • patch nameの前にoption nameを入れるようになる
      • あるproductに関する大量のパッチがあるなら,すべての保守releaseにまとめるのが〇
        • service packというapproachも〇
          • documentにパッチを累積的に適用するものかどうかはっきりと記載する
      • patchをバージョン管理するとしても,どうしても必要になるまではバージョン識別子を含めない方が良い
      • → product name-x.y(.z(.build number))-patch name.patch versionとなる
      • 洗練されたarchitectureでは,patchをproductを一緒にpackagingできるし,何がinstallされ何がinstallされないかを追跡できる
        • softwareを内部で実行し自動更新できるようになっていることもある
        • ManageSoftのように企業の管理者の代わりにさまざまなPCのソフトウェアのスナップショットを取得するproductを開発している会社もある
      • architectureを拡張して,パッチ管理機能を持たせたいとき
        • 何がinstallされ何がinstallされていないかを判断できるくらい,洗練されたarchitectureが必要
        • internetを通じて更新データを取得 → remote serverと通信する仕組みが必要
        • 前提条件が整っているか判断が必要
        • 自動更新がシステムや何らかの設定を壊すことなく正しくインストールできるかどうかを判断する必要
        • これらは極めて複雑な要件なので,一般的にはおすすめできない
      • column: bug fixは無料でなくてもよい
    • variation
      • 命名してその名前を識別文字列の中に意味のある形で含めるのが最もよい
      • portability, globalization, 性能特性などが要因となり複雑になることもある
      • 冗長でも間違えにくければ〇
  • SKU(Stock Keeping Unit, 在庫管理単位)とserial_number
    • SKUの管理
      • SKUによりreleaseを一意に識別でき,社内の在庫追跡システムで1つのreleaseをその他の全てのreleaseと区別できるようになる
      • 識別子としてのSKUはreleaseとは独立したもの
      • 使用される状況
        • 特定のreleaseへの注文情報,価格情報
        • 物理的な商品の在庫数
      • guideline
        • scope, targetには関係なく,販売するreleaseにはすべてSKUを割り当てる
        • scopeに関係なく,一般releaseにはすべてSKUを割り当てる
          • 一般消費者が入手できるものを追跡しやすい
        • 取引先管理システムや頒布管理システムでSKUをキーとして用いているなら,すべてのreleaseにSKUを割り当てる
          • 誰がそのreleaseを入手したか追跡できる
        • technical supportや無料download siteなど,self serviceのWebサイトに置かれるだけのreleaseには,SKUを割り当てないようにする
          • 販売されるわけではないので,財務システム内でSKUを払いだす必要がない
          • 誰が入手したか基本的には追跡不要
        • ただし,企業のpolicyに従う
      • SKUの形式は口出しできないが,必要な量は伝えられるし,目的を達成できる形式についてともに考えることはできる
      • SKU,外部名称,完全なrelease識別子の3つの論理的なcomponentを使う例
      • productに関連するSKUの総数の見積もり(以下の合計)
        • 完全release数*完全releaseのvariation数
        • SKUを与えられる特別release数*特別releaseのvariation数
        • option component数*option componentのvariation数
        • そのほか何らかの理由で生成されるSKUの合計
    • serial_number, registration, activation
      • SKUは,個々のclientに販売したproduct 1つ1つを区別することはできない → serial_numberが必要
      • serial_numberをキーとしてclientと企業が紐づく
      • activation: 強制的なregistration
        • licenseの強制
      • 電子productへのserial_numberの埋め込みはコストをかけて開発processの変更が必要
        • license強制スキームを適用して,softwareの複製や改変を防ぐ
      • serial_numberにより貴重な統計情報を収集でき,marketing campaignを調整できる
      • serial_numberが適切に登録されれば著作権侵害行為も減らせる
        • activationも効果がある
      • activationの手順
      • activation processを採用するかどうかは戦略的判断
        • vendorの提供するサービスを利用するときは,既存・計画中のbackend_systemやworkflowを照合して評価する必要
        • backend_systemを管理する方がactivationのvendorを選ぶよりずっと大変
  • tarchitectureへの影響
    • release_managementの要件の理解 → release_managementをより簡単にする選択ができるようになる: tarchitectureの改善
    • 考慮点
      • すべて作り直す
        • 出荷するものは全て導出(ソースから実行ファイルをビルド)か構築(Framemakerで作ったマニュアルを印刷)する
      • できるだけ既存のsolutionとinfrastructureを利用する
      • できる限り早い時点でtarchitectureにバージョン情報を組み込む
      • 各componentは自身が依存しているcomponentを把握しておく必要がある
        • data_driven_approachが1番簡単
        • 設定ファイルに書き込まれた依存関係を処理する,特殊な依存性check componentを使う
      • message, protocolのversion_control
      • DB, tableはバージョン情報が必要
        • schema内の各tableのバージョン識別子を含むシステムテーブルを作る
      • update可能なあらゆるcomponentはversion_controlが必要
      • 内部のcomponentは自分が必要とする外部のcomponentのversionを把握する必要
      • version_controlされたすべての成果物について,バージョンを取得する方法を提供する
      • patchに伴うテストやサポートに注意
        • 複雑さは指数的に増大する
  • まとめ
    • release_managementとは,productを求めているclientに対して,正しい成果物の提供を保証すること
    • 考え方
      • program family
      • component/成果物
      • version
      • revision
      • variation
      • distribution
      • release
    • release_managementには3つの要因
      • 何を誰になぜreleaseするか
    • releaseは区別が必要
      • 4桁の数字文字列は識別子として実績がある
    • SKUは経理やfulfillmentなど,back_office_systemでrelease_managementするために使われる
  • checklist
    • releaseごとに,何をreleaseし,誰が対象なのかを定義している
      • releaseに対するclientの期待値を見積もっている
    • releaseを区別する仕組みを定義した
    • SKUが必要なreleaseには,SKUが振られている
    • serial_numberが必要なreleaseには,serial_numberが発行されている

Ch16 security

  • securityが根本的に違うところは,物事を簡単にするのではなく難しくするものだという点
  • 成功するsolutionにとってきわめて重要だが,完成する直前まで見落とされがち
    • 初めから入れておく必要がある
  • virus, crack, 海賊
    • identity_control
      • 利用者ごと,役割ごとに異なるcapabilityを定義できる仕組みや,公にユーザの行動を追跡する仕組み,ユーザが申告通りのユーザであることを検証する仕組みを構築する必要
    • transaction_security
      • 安全な通信
      • 未認可のcomponentと置き換えたり,メッセージに介入したり,変更したり,ハイジャックしたりできないようにする必要がある
    • software_security
      • 未承認の人は誰もsoftwareを変更できないようにするべき
      • 未認可の権限昇格を許さない
      • virusや著作権侵害行為から守ってくれる
    • information_security
      • 未認可のアクセスを防ぐ
    • applicationにとってsecurityのどの要さが重要か明確にすることが,成功するsolutionを構築するカギになる
    • risk_control
      • 安全性を高める難易度は指数関数的に上昇する
      • riskは無視はできないが管理はできる
      • securityはmarketectとtarchitectが連携する分野
      • marketect
        • riskを評価する活動を率先して行う
      • tarchitect
        • さまざまな問題を解決する方法をmarketectに説明する
        • 自身のriskを評価する
      • 対処すべきリスクや仕組みを明らかにし,潜在的な問題への対象について難しい決定を下す
    • 見ざる,言わざる
      • riskは大きい
  • identity_control
    • 認可,誰に何ができるのか定義
      • 静的な側面
        • systemの中で特定の操作を実行する権限や特定の部分にアクセスする権限,DBの特定の部分にアクセスする権限を,どの主体が持つか定めること
        • 信頼できるユーザの作成,ユーザや分類に応じて権限を定義
      • 動的な側面
        • 指定されたユーザ・主体が特定の操作を実行したり,システムやDBの特定の部分にアクセスするために必要な権限を持っているかチェックすること
        • 実行時にチェック
          • 認可ルールはさまざまな動的なパラメタに基づくため
            • アクセスしたときの役割,直前の振る舞い,システムの状態,システムを利用している別のユーザの振る舞いを同時に考慮
      • 認可とアクセス制御を提供するtechnologyや権限管理システムには,利用できるものが多くある
      • 認可制御のために利用するシステムを分離し,自前の認可制御レイヤで包み込むのが〇
    • 認証,身元を証明する
      • 主体が誰で,誰であると主張しているかsystemが保証する
      • 認可に先駆けて行う処理として重要,信頼されたtransactionに参加するだけであっても必要
      • 三者機関による同一性の証明が必要
      • 非公開システム
        • 三者機関による同一性の証明の必要はほとんどない
        • systemの持つ構造や操作だけで,妥当な水準の認証機能を提供する
        • 認証の要素
          • userだけが知っている情報
          • userだけが持っている情報
          • user自身の情報
          • いずれか2つを組み合わせると強力な認証になる
          • きわめてセキュアな環境では3つすべてから,複合的に応用が必要
        • 認証方式は抽象化が〇
      • 公開システム
        • 独立した第三者機関が必要
          • 電子署名の利用
          • root証明書にいたるまでのそれぞれの証明書が外部機関によって署名されていることで,認証が正当化される
        • 認証機関で証明書の取り消しもできる
          • 認証機関との直接のやりとりが必要
          • 認証の取り消しが本当に必要かどうかは慎重に検討すべき
            • 証明書に基づく認証をほかの情報と紐づけている場合は,必ずしも必要ではない
        • globalなsolutionとなる認証機関が探し出しづらくなっている
        • これらの技術面,運用面での課題に加えて,ユーザに複雑さを説明するという課題もある
      • hybrid_system
        • e.g. email
  • transaction_security
    • client-server application, Web serviceにおいて最重要
    • 目的: 監査可能性,一貫性,機密性,説明性の成立
    • 監査可能性,行為の証明
      • 振る舞いの追跡のために認証に仕組みが必要
      • 一般的には,監査情報の複製を信頼できる第三者機関によって管理されたオフサイト拠点に置く
        • 改ざんは不可能
      • motive
        • 受動的には,政府および業界の規制やガイドラインへの対応が必要
        • 能動的には,何らかのfeatureを構築するために監査情報が必要なことがある
        • 新発見を求める同期として,時間をかければ何か興味深い傾向が発見されるのではという期待もある
    • 一貫性,情報の改ざん,改変を防ぐ
      • digest_function
      • 一貫性はたいていの場合監査可能性に関係する
        • systemの振る舞いの記録が改変されていないことを保証するため
    • 機密性,権限のないものから情報を隔離する
      • 2段階のprocessを持つSSLで情報を案硬化
        • まず,共通鍵で暗号化を保証,とても高速
        • 次に,共通鍵を,送信者が受信者の公開鍵で暗号化
        • 速度と暗号強度のバランスで〇
        • RC4よりも暗号強度に優れたalgorithmであるRijndaelの方が望ましい
    • 説明性,人々に自分の取った行動の責任を負ってもらう
      • 否認防止の仕組み
      • 公開鍵や秘密鍵の操作だけは,否認防止の仕組みから除外されている
      • また,公開鍵や秘密鍵に基づく操作であれば,どんな操作であっても同じく除外されている
      • → 厳格な認証なしには責任を追及できない
      • 強固な説明性には厳格な認証が必要
      • 電子署名は厳格な認証とともに使用される
  • software_security
    • technique
      • serial_number, activation
        • softwareにlicenseの電子署名を含めるものもある
          • 正しいlicenseと正しい署名が同時に存在しないと動かない
          • 署名に必要な秘密鍵が他人には利用できないため〇
        • crackerがreverse engineeringによりserial_numberを生成するalgorithmを解読し,自分で実装してしまうケース
          • licenseの電子署名に対しては,program自体の改変か,内包している公開鍵を自分たちの秘密鍵に対応する公開鍵に置き換えるくらいしかない
      • 検証コードの保護
        • 単に真偽値を返すだけのコードでlicenseをチェックしてはいけない
        • applicationが動作するために必要な何らかの情報を暗号化して,署名されたlicenseに埋め込んでおく方法が〇
          • 初期化routineやapplicationにsub_componentを登録する機能と同じくらい,きわめて重要な機能
          • 高度なlicense_managerの実装の難しさ → Ch04
      • hardware_binding
        • machine_binding
          • 低コストで〇
          • machineのupgrade困難で×
          • crackerが最もcrackしやすいことも×
        • hardware_binding
          • softwareをserial_portやUSB_portに接続した専用の物理デバイスと紐づける
            • 一般にドングル度呼ばれる
          • portability, security強度の高さで〇
          • 金銭的・管理コストで×
    • software_securityのコストと恩恵
      • 正当なuserに面倒な思いはさせないようにする
      • 対策を実装するリスクと,潜在的な利益損失を比較する
      • crackerのWeb siteやUsenetのsoftware一覧にある場合は,強力な防護策を検討する
  • information_security
    • 1か所からしかアクセスできないようにすることが1番の対策
      • firewall, 侵入検知システム, password_policy_checkerなどのuser_control_systemが〇
    • password security
      • digest値をDBに保存
      • または,internetからはアクセスできないserverのlocal file system上にパスワードを保存
    • 情報の窃盗の問題
      • 権限昇格
    • systemのarchitectureを統制
      • 有用なツールを利用する
  • algorithmを秘匿するか,鍵を秘匿するか
    • 秘匿されたalgorithmは×
      • 知られていないことによって成り立つsecurityは最弱
      • 公開されて利用可能な優れたalgorithmのどれか1つを採用するのが〇
    • 標準的なalgorithmと秘密鍵が〇
  • backdoor
    • 窓が増えるほど安全の保証は困難
    • systemの重要部分は100%の安全性の確保が必要
    • backdoorを作るくらいなら,パスワードと鍵を管理する別会社を紹介する方が良い
    • column: client supportはbackdoorを使ってclientを盗み見してはならない
      • backdoorは断固反対
  • securityとmarketecture
    • securityは特定の分野で目に見える競合優位性
    • 影響のある領域
      • 認証,business_model,運用
        • 強力な二段階認証が重大な影響 → business_model, 運用モデル
          • userがid, passwordを共有を防ぐ
        • clientからの信頼
      • 規制の影響
        • FIPSなど
      • 業界の発展
        • internetの標準規格に従うように対策 → 受け入れられやすくなる
      • 信頼
        • securityの知識や仕組みを根拠に信頼 → 競合優位性
      • 論争の解決
        • 一貫性や説明性のテクニックがあれば,そのときどきの最適なやり方で論争を解決できる
        • security technologyで問題を回避できる分野について,法務部門に見極めてもらう
        • column: あなたの主張を証明しなければならないのはいつか
          • log fileが法的な根拠となり得るように確認していたことで〇のケース
  • まとめ
    • applicationの全体的なsecurity計画においては,適切なrisk要因を考慮する必要
    • security 4種類
      • identity_control
      • transaction_security
      • software_security
      • information_security
    • identity_controlの主張なtool, technique
      • 認可制御
        • 誰が何ができるか設定
      • 認証制御
        • 身元の証明
        • 公開/非公開システムによって仕組みが大きく異なる
    • transaction_securityの主要なtool, technique
      • 監査可能性
      • 一貫性
      • 機密性
      • 説明性
    • software_securityの主要なtool, technique
      • 著作権侵害行為を防ぎ,license条項の遵守を促す
      • softwareを,それが実行される機会やhardware tokenと結び付ける
      • information_securityの主張なtool, techniqueは,transaction_securityに用いられるものと同様であるが,少し効果は落ちる
        • 主なtechniqueは,情報が格納される環境の安全性を確保すること
    • 自分たちでsecurity algorithmを開発するべきではない
      • 適切な鍵を用意して公開されているalgorithmを使う
    • backdoorは×
    • securityが自分たちの長所となるようにする
      • 第一級のブランド要素は信頼,securityはそれを支える

Appendix A release checklist

  • product追跡用の情報
    • product name
    • version
    • FCS日付(FCS: client向け初回出荷)
  • engineering, development
    • version文字列は最終バージョン情報で更新されているか
    • debug codeやtest codeはsoftwareから除去したか
    • 埋め込まれた欠陥は全て取り除かれたか
  • 品質保証
    • すべての欠陥について最終的な処置や解決は住んでいるか
    • 最終ビルドに対する適切なテスト(完全な回帰テスト,clientによる確認テスト,スモークテストなど)が完了しているか
    • release mediaによるまっさらな対象マシンへのprogram installは完了しているか
    • program(file, registryなど)は正しくinstallできるか
    • target machineからprogramはuninstallできるか
    • upgradeのinstallは完了しているか
    • 最終版のhelp fileが含まれているか
    • 最終版のreadme fileが含まれているか
    • 移行scriptはすべて完了しているか
    • support対象のplatformはすべてテストし,検証されているか
  • 技術出版物
    • release_note
    • product内のinline help(readme, release_note, quick start)
    • tarchitectによってreview済みの最新のtraining教材
  • product_managementの必須事項
    • press release
    • 既存clientへのemail campaign
    • sales training
    • price
    • 公開plan
    • 販促物(white paper, 用語集, Web site)
  • 知識の移転-専門service
    • clientはsystemのinstall, upgrade, integrationができるか
    • systemのinstall, upgrade, integrationにどのくらい時間がかかるか
    • installしたものを機能させるために,何らかの統合をやり直す必要があるか
    • training素材はreleaseと合わせて最新化されているか
  • 知識の移転-販売と販路
    • 販売チームは既存clientに新規releaseのmeritを説明できるか
    • 販売チームは新規clientに新規productのmeritを説明できるか
    • 以前のreleaseからの変更を含むbusiness_modelを完全に理解できているか(価格の変更や販促用の値引きなど)
    • 企業に提供されるsolution全体というcontextの中でproductについて説明できるか
  • 知識の移転-technical support
    • technical supportはproductをsupportする準備ができているか
  • release活動
    • releaseされたproductに含まれる最終的なファイルの一覧は入手できるか
    • release fileのtimestampは同期しているか
    • 最終頒布media(golden master)は入手できるか
    • 頒布用mediaのvirus scanは完了しているか
    • 頒布用mediaに含まれるfileの最終確認は完了しているか
    • build environmentのbackupは変更管理課に置かれているか
    • Web siteは最新化されているか

Appendix B 戦略的product_managementのためのpattern_language

  • marketect, tarchitectにとってそれぞれの専門分野の間にまたがるgapを埋めるのに役立つ
  • patternを適用する
    • market_mapの構築 → 統合期 → feature, meritの計画 → tarchitectureの進化の管理
    • market_mapから: 狙っているtarget_marketについて,product_development_teamの中でもかなり混乱があるため
    • 1つのpatternを選んで初めて見ることが重要
      • patternは体系の一部でしかない
      • feedback loopの中で,1つのmarket_segmentを見定めることから始める
        • そのうえでmarket eventやfeatureを追加
  • 結果を表現して共有する
    • 誰にでもアクセスできる場所に専用のスペースを設けて,大きなchartを一式掲示が〇
  • market_map
    • context
      • 新しいproductのideaについて,潜在的な価値を理解しようとしている
      • 既存のproductのmarketingが効率よく行われることを確かめたい
    • 問題
      • marketをどのようにsegment分割するか
    • force
      • market_segment分割は難しい
        • 既存のmarket歯変化する
        • 台糖市場の予測は,科学的な取り組みであるのと同じくらいセンスが問われる
      • market_segment分割は極めて重要
        • まるごと相手にしては必ず失敗するだろう
        • market_segmentが異なればsolutionも異なる
      • うまくsegment分割できなければ,最も収益性の高いsegmentを見定めることもできない
      • marketのすべてのニーズを満たすことはできない
      • usabilityを考えるには,対象のmarketのことの理解が必要
    • solution
      • 同じ特徴や属性を共有するuserを分類したりgroupingしたりして,market_segmentを分割
      • 特徴
        • 決定的なニーズや購買パターン,そのほか重要な何らかの属性
        • 消費者市場の属性
          • 年齢,世帯収入,internet接続できるか,技術リテラシーなど
        • ビジネス市場の属性
          • 収益,従業員数,事業所の所在地
      • 初めは,現在のproductを実際に使っているuserに集中
        • userが直面する問題を見定める
      • できるだけうまくsegmentを定義
      • 妥当な数のsegmentになったら,featureを並び替え
      • market_mapはteam_member全員に渡す
    • 結果として現れるcontext
      • 次のproduct cycleで取り組むsegmentをより精密に分析できるようになるかもしれない
    • 関連するpattern
      • market event/market rhythm
      • feature/merit map
  • market event/market rhythm
    • context
      • 特定のreleaseや今後予定されている一連のrelease_cycleをmarketに投入する次期を見定める
      • market_segmentの調査に役立つmarket_mapが既存
    • 問題
      • 適切なrelease日を決めるにはどうすればよいか,今後のrelease_cycleを確立するにはどうすればよいか
    • force
      • たいていのclientはいつでもreleaseを受け入れてくれるわけではない
      • clientはreleaseがあまりに頻繁なことに耐えられないが,遅すぎても心配する
      • developerはrelease_dateが未定なことを嫌う
      • 販促活動には十分なリードタイムが必要
      • releaseまでの期間が短すぎるとほぼ間違いなく失敗する
      • releaseまでの期間が長すぎても失敗する
      • 長期間productをreleaseしていないと,組織から貴重なスキルが喪失
      • 長期間productをreleaseしない組織で働いていても楽しくない
    • solution
      • どんなドメインにもマーケットを動かす原動力となるようなイベントとリズムがある
      • 重要なevent
        • conference
        • 競合他社のpress release
        • productが関連するdomainに焦点を合わせた特集記事や,product/serviceに関連する特集記事
      • その他のrhythm: 歳末,新学期,夏季休暇など
      • 今後のreleaseをmarketに投入する時期やrhythmを決定する
        • 9~12か月の間でが定期的なrelease_cycle
      • market_segmentの成熟度もrelease_cycleに影響する
    • 結果として現れるcontext
      • developerは根拠を理解できる
      • release_dateの共有はdevelopment_team全体を活気づけ結びつける
      • 戦略レベルの計画の実現性を保証でき,clientが満足
    • 関連するpattern
      • market_map
  • feature/merit map
    • context
      • 重要なmarketing目標とdevelopmentで力を入れている部分の整合性の確認
      • 重要なmarket_segmentを見定めるためのmarket_mapがある
    • 問題
      • それぞれのmarket_segmentにとって魅力的なfeature, meritを表現するにはどうすればよいか
    • force
      • 特定のmarket_segmentにおける重要なfeatureとmeritを理解できていると誤認しがち
      • 1つのfeatureが複数のmarket_segmentにとってのmeritになることもある
      • 複数のmarket_segmentに訴求するfeatureがあっても,それぞれのmarket_segmentにとってのmeritは同じではない
      • developerはfeatureのことだけを考える傾向がある.marketing担当者はmeritのことだけを考える傾向がある
        • 相違をそのままにしておくと,marketで成功するはずもない粗末なproductになる
      • developerはfeatureのもたらす将来的なmeritについて,その性質や意図の質問が必要
        • tarchitectureの設計がそれらに見合ったものかどうか確かめるため
    • solution
      • 各market_segmentについて,productの購入を望む重要なfeature, meritを表現する
      • feature/meritは並べて書くことが重要
        • 省略は×
      • mapの並び順を整える
        • releaseまでの所要時間,featureの難易度や複雑さ,marketの要望の順など
      • treeでのfeatureの描画
        • productの成長の実感
        • product_development_teamの規模の拡大と関連
    • 結果として現れるcontext
      • target market_segmentの攻略のために必要な,主要なfeature/meritを表現
      • tarchitecture_loadmapを最新化するために必要な情報が技術担当チームに提供される
    • 関連するpattern
      • market_map
      • tarchitecture_loadmap
  • tarchitecture_loadmap
    • context
      • 今後も含めて複数回のreleaseを期待されたapplicationを開発している
      • market_segmentを見定めるためのmarket_mapと,market_segmentが求めているfeatureを見つけるためのfeature/merit mapがある
      • 複数のmarketに対応できるarchitectureがあるかもしれない
    • 問題
      • 技術的な変化をどのように管理し,どのように活用するか
    • force
      • applicationのarchitectureがどれほどうまく構成されていても,technologyが変化することで以前の目論見が無意味になる
      • たとえ計画していたとしても,十分な時間をかけて順応しなければtechnologyの全貌を捉えられない
      • developerは目標を知りたがる
      • developerは新しいことを勉強するのが大好き
      • developerは安易に実装されたfeatureやcapabilityをtarchitecture的に進化させる方法を追及している
        • みすぼらしいfeature/capabilityを明らかにし,改修案とともに記録する方法を求めている
      • marketing部門が望んでいる新しいfeatureは,technologyが変化することで実現できるようになるかもしれない
      • marketing部門が望むfeatureは新しいtechnologyでしか実現できないかもしれない
      • 競合他社が新しいtechnologyを採用すると,自分たちは不利な立場になるかもしれない
      • 技術脳の人間は核心的なtechnologyにあれこれ反論する
        • 時には議論を通じて課題を学ぶことになる
        • 合意のための唯一の方法は,議論に十分な時間を割くこと
    • solution
      • architectureの進化の歩みを示すtechnology loadmapを作る
      • 主要なmarket_segmentにmeritをもたらすtechnologyを示すことで,technology loadmapとmarket_map, feature/merit mapを関連付け
      • 重要なmilestoneを達成したときや,何も起きなくても少なくとも6か月ごとに,technology loadmapを見直す
        • 内部的なmilestone
          • code freeze,productの出荷,既存顧客の半分以上が最新versionへupgradeしたことなど
        • 外部的なmilestone
          • 競合他社による新しいproductのrelease発表,新しい特許の公開,技術スタッフが次世代のtechnologyを発見する,重要なmarket eventが生じる
      • technology loadmapを作成して維持していくには,少なくともチームの中の1人が外部の環境で新しい開発方法を実践する必要がある
      • needsを満たす新しいtechnologyが登場していないか定期的に確認できる → チームに集中力
    • 結果として現れるcontext
      • 将来productに搭載されるかもしれないfeatureを見通せるようになる
      • teamの規律があいまいだと,新技術渇望症候群(SNOS: Shiny New Object Syndrome)にかかってしまう
    • 関連するpattern
      • market_map
      • feature/merit map

訳者あとがき

  • Web baseのserviceの進化に伴い,licenseやinstall, upgradeに対する考え方は現在にそのまま当てはまらない

[学習記録]Ruby on RailsでのWebアプリケーション作成

勤務表作成アプリケーション

学習内容

  • Web application作成
    • ユーザ認証機能の実装
      • CRUD
      • validation
      • session
      • remember digest
      • friendly forwarding
      • activation
      • password reset
    • HerokuでのSSL
    • Herokuでのメール送信
      • Mailgun
    • 勤務表機能の実装
      • ユーザモデルとの関係づけ
      • berofe_actionでのアクセス制御
      • ルート設定
      • 複数データの一括CRUD
        • Formモデルの作成
        • parameterの取り出し
        • validation
      • クエリ
        • 環境ごとのクエリの使い分け
    • 画面作成
      • form_withでの引数を伴った画面遷移
      • Bootstrapの使用
      • 登録データに描画内容を対応させる
      • ユーザと描画内容を対応させる
      • 休祝日の対応
        • ヘルパーメソッドの使用

機能概要

  • ユーザまわりの機能
  • 勤務表まわりの機能

    • 一括登録機能は→ こちら を参考に実装
    • 登録済みの場合は登録画面を表示しないようにする
      • 作成ボタンを表示しない & 画面以外から入ろうとしてもredirect_toで返す
    • 日付は対象の年月から配列を作成して,valueに設定する
      • 編集しないように,readonly: true, tabindex: -1を設定する
    • 新規登録時は,年月と時間の既定値をフォームで送って設定できるようにする
    • 一括更新
      • 既存のデータのリンクのみ生成する
        • ユーザモデルにクエリを実行するメソッドを追加して,それを呼び出す
          • 各月の初日(1日)のデータのみ取得して,そこから年月を取得している
            • 本番環境ではpostgresqlでextractを使えるが,ローカルのsqlite3では使えないため,環境によって分岐させている
        • default_scopeでorderを設定し,勤務日について昇順で並ぶようにする
      • paramsをhashに変換して,eachで1つずつvalueを取得し,update_attributes
      • url, methodはyieldで取得するように変更
        • 登録フォームをパーシャルに切り出して,登録・更新・参照で共用
        • methodをputにすることでcontrollerのupdateを呼べるようになる
    • 一括削除
      • 対象のデータを取得して,1件ずつdestroy
      • 既存のデータの削除リンクのみ生成する
    • Formの基底を用意して,それを継承するcollectionクラスを作成する
      • 作成・更新・参照画面では,collection クラスのインスタンスを生成
        • form_for
        • fields_for
    • 曜日・祝日の取得
      • 祝日の取得
      • 休祝日の場合は,formに色をつけ,時間は00:00を設定する
        • class名, valueをhelper methodで取得する
    • flashでメッセージを1度だけ表示
  • 実装におけるtips

    • routeで階層は作る必要ない
      • modelで関係を設定済み.routeでは不要
    • rails routesで確認
    • debugger
    • rails db:seed --trace
    • form_with
      • local: trueにしないとdefaultがremoteなので画面遷移してくれない
        • serverを1度止めないと反映されない
    • ユーザに有効期間を追加するだけして使っていない
      • ブランチ切るべきだった
    • RailsはWebでの検索で出るノイズが多く感じた

『Ruby on Rails チュートリアル』学習メモ

Ch01 0からdeployまで

  • お手軽すぎるscaffold
    • 自動生成されたcodeは無駄に量が多く複雑 → 初学者には向かない
  • rails 5.1.6 new hello_app ← バージョン指定
  • direcroty 構成 → 表1.2
  • Gemfileのバージョン指定
    • ~>では,メジャーバージョンのアップデートはしない
  • list 1.5でGemfileの内容
  • root 'controller_name#action_name'
  • Git
    • git config --global user.name "自分の名前"
    • git config --global user.email your.email@example.com
    • git config --global alias.co checkout
    • git config --global credential.helper "cache --timeout=86400"
    • git init
    • git add -A
      • .gitignoreで指定していないすべてのファイルをバージョン管理に追加
    • git commit -m "Initialize repository"
    • git log
    • git checkout -f
      • 以前のcommitに復元できる
    • git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git
    • git push -u origin master
    • git checkout -b modify-README
    • git branch
    • github.com/settings/repositoriesをブラウザで開いて「Repository default branch」をmainからmasterに変更
    • 編集後に,git statusで確認
    • git commit -a -m "Improve the README file"
      • -a: 変更を一括でcommit
        • 慎重に使う
      • 新しいファイルはaddが必要
    • commit message: 現在形かつ命令形
    • git checkout master
    • git merge modify-README
    • git branch -d modify-README
    • git branch -D
      • topic branch上の変更を破棄
      • 変更をマージしていなくても削除できる
    • git push
  • deploy
  • まとめ
    • Ruby on Rails: Web developmentのためのframework, Rubyによる
    • rails new, rails server
    • controller_actionの追加やroot routingの変更だけで,hello, world applicationを作成できる
    • Herokuへのdeploy

Ch02 Toy application

  • application plan
    • 下準備: Ch01と同じところまで
    • 最初に,applicationの構造を表すためのdata_modelを作成する
    • userのdata_model design
      • minimum 表現
        • id, name, email
    • micro_postのdata_model design
      • id, content, user_id(associate)
  • Users resource
    • resource: data_modelとWeb_interfaceの組み合わさり
      • CRUDできるobjectとみなせるようになる
    • rails generate scaffold User name:string email:string
    • rails db:migrate
    • かつてはRake
    • ユーザーページを探検する
      • /users: index
      • /users/1: show
      • /users/new: new
      • /users/1/edit: edit
    • MVCの挙動
      • config/routes.rb
        • URL, actionの組み合わせを効率よく設定
        • resources :users
          • :usersはRubyのsymbol
      • app/controllers/users_controller.rb
        • 各ページは、Usersコントローラ内のアクションにそれぞれ対応
        • ページの数よりもアクションの数の方が多い
          • create、update、destroyアクションがあります。通常、これらのアクションは、ページを出力せずにデータベース上のユーザー情報を操作
        • URLには重複しているものがある
          • これらのアクション同士の違いは、それらのアクションに対応するHTTP requestメソッドの違い
        • REST
          • RailsアプリケーションにおけるRESTとは、アプリケーションを構成するコンポーネント (ユーザーやマイクロポストなど) を「リソース」としてモデル化することを指す
            • これらのリソースは、リレーショナルデータベースの作成/取得/更新/削除 (Create/Read/Update/Delete: CRUD) 操作と、4つの基本的なHTTP requestメソッド (POST/GET/PATCH/DELETE) の両方に対応
            • RESTfulなスタイルを採用することで、作成すべきコントローラやアクションの決定が楽になる。作成(C)・取得(R)・更新(U)・削除(D)を行うリソースだけでアプリケーション全体を構成してしまうことも可能
        • @記号で始まる変数をRubyではインスタンス変数と呼び、Railsのコントローラ内で宣言したインスタンス変数はビューでも使えるようになる
      • app/models/user.rb
        • 継承 (2.3.4および4.4) によって多くの機能が備わっています。特に、Active RecordというRubyライブラリのおかげで、リスト 2.9のUserモデルはUser.allというリクエストに対して、DB上のすべてのユーザーを返すことができます
      • ビューはその内容をHTMLに変換し (⑦)、コントローラがブラウザにHTMLを送信して、ブラウザでHTMLが表示
    • Usersリソースの欠点
      • データの検証が行われていない
      • ユーザー認証が行われていない
      • テストが書かれていない
      • レイアウトやスタイルが整っていない
      • 理解が困難
  • Micropostsリソース
    • マイクロポストを探検する
    • マイクロポストをマイクロにする
      • app/models/micropost.rb
        • validates :content, length: { maximum: 140 }
    • ユーザーはたくさんマイクロポストを持っている
      • 異なるデータモデル同士の関連付けは、Railsの強力な機能
      • app/models/user.rb
        • has_many :microposts
      • app/models/micropost.rb
        • belongs_to :user
      • 演習
        • <%= @user.microposts.first.content %>
        • app/models/micropost.rb
          • presence: true
        • app/models/user.rb
          • validates :name, presence: true
    • 継承の階層
      • ActiveRecord::Baseという基本クラスを継承したことによって、作成したモデルオブジェクトはデータベースにアクセスできるようになり、データベースのカラムをあたかもRubyの属性のように扱えるようになる
      • ActionController::Base
        • RailsのAction Packというライブラリが提供しているコントローラの基本クラス
        • モデルオブジェクトの操作や、送られてくるHTTP requestのフィルタリング、ビューをHTMLとして出力などの多彩な機能を実行できる
        • Railsのコントローラは必ずApplicationControllerを継承しているので、Applicationコントローラで定義したルールは、アプリケーションのすべてのアクションに反映
    • アプリケーションをデプロイする
  • 最後に
    • 良い
      • Rails全体を高度なレベルで概観できた
      • MVCモデル
      • RESTアーキテクチャに初めて触れた
      • データモデルの作成を初めて行った
      • データベースを背後に持つWebアプリケーションを本番環境で動かした
    • 弱点
      • レイアウトもスタイルも設定されていない
      • “Home” や “About” のような定番の静的なページがない
      • ユーザーがパスワードを設定できない
      • ユーザーが画像を置けない
      • ログインの仕組みがない
      • セキュリティのための仕組みがまったくない
      • ユーザーとマイクロポストの自動関連付けが行われていない
      • Twitterのような「フォロワー (following)機能」や「フォロー中 (followed)機能」がない
      • マイクロポストをフィードできない
      • まともなテストがない
      • 理解が困難
    • 本章のまとめ
      • Scaffold機能でコードを自動生成すると、Webのあらゆる部分からモデルデータにアクセスしてやりとりできるようになる
      • Scaffoldは何よりも手っ取り早いのがとりえだが、これを元にRailsを理解するには向いていない
      • RailsではWebアプリケーションの構成にMVC (Model-View-Controller) というモデルを採用している
      • Railsが解釈するRESTには、標準的なURLセットと、データモデルとやりとりするためのコントローラアクションが含まれている
      • Railsではデータのバリデーション (validation) がサポートされており、データモデルの属性の値に制限をかけることができる
      • Railsには、さまざまなデータモデル同士を関連付けを定義するための組み込み関数が多数用意されている
      • Railsコンソールを使うと、コマンドラインからRailsアプリケーションとやりとりすることができる

Ch03 ほぼ静的なページの作成

  • 静的なページを自分の手で作成することは良い経験になり、多くの示唆も得られる
  • セットアップ
    • rails 5.1.6 new sample_app
    • Gemfile
    • git
    • README
    • helloアクションをApplicationコントローラーに追加
    • ルートルーティングを設定
    • Herokuにプッシュ
    • RailsのデフォルトのページはHeroku上ではうまく表示されない仕様になっています。このため、hello worldのような変更を加えないとデプロイが成功したかどうかが分かりづらい、というのが本当の理由
    • heroku logsでerrorの確認
  • 静的ページ
    • コントローラとは (基本的に動的な) Webページの集合を束ねるコンテナのこと
    • git checkout -b static-pages
    • 静的なページの生成
      • rails generate controller StaticPages home help
      • git push -u origin static-pages
      • 元に戻す方法
        • rails destroy controller StaticPages home help
        • rails db:rollback
        • rails db:migrate VERSION=0
      • GETやその他のHTTPメソッドについて
        • クライアント (例えばFirefoxSafariなどのWebブラウザ) とサーバー (ApacheやNginxなどのWebサーバー) は、4つの基本操作(GET、POST、PATCH、DELETE)を互いに認識できるようになっています
        • ブラウザがこれらの操作のリクエストを送信しているかのように見せかける技術 (偽装) を駆使して、PATCHとDELETEという操作を実現
      • StaticPagesコントローラは一般的なRESTアクションに対応していないことに注意してください。これは、静的なページの集合に対しては、適切なアクション
      • ApplicationControllerクラスを継承しているため、StaticPagesControllerのメソッドは (たとえ何も書かれていなくても) Rails特有の振る舞い
        • /static_pages/homeというURLにアクセスすると、RailsはStaticPagesコントローラを参照し、homeアクションに記述されているコードを実行
          • 今回の場合、homeアクションが空になっているので、/static_pages/homeにアクセスしても、単に対応するビューが出力されるだけ
    • 静的なページの調整
      • 重要なのは「Railsのビューの中には静的なHTMLがある」という点
        • Railsの知識が無くてもHomeページやHelpページを修正できる
  • テストから始める
    • 何らかの変更を行う際には、常に「自動化テスト」を作成して、機能が正しく実装されたことを確認する習慣をぜひ身に付けましょう
    • 結局テストはいつ行えばよいのか
      • テストを行う目的
        • 機能停止に陥るような回帰バグ (Regression Bug: 以前のバグが再発したり機能の追加/変更に副作用が生じたりすること) を防止
        • 安全にリファクタリング
        • テストコードは、アプリケーションコードから見ればクライアントとして動作するので、アプリケーションの設計やシステムの他の部分とのインターフェイスを決めるときにも役に立つ
      • テストの手法やタイミングは、ある意味テストをどのぐらいすらすら書けるかで決まると言ってよい
      • 「テスト駆動」にするか「一括テスト」にするかを決める目安となるガイドライン
        • アプリケーションのコードよりも明らかにテストコードの方が短くシンプルになる (=簡単に書ける) のであれば、「先に」書く
        • 動作の仕様がまだ固まりきっていない場合、アプリケーションのコードを先に書き、期待する動作を「後で」書く
        • セキュリティが重要な課題またはセキュリティ周りのエラーが発生した場合、テストを「先に」書く
        • バグを見つけたら、そのバグを再現するテストを「先に」書き、回帰バグを防ぐ体制を整えてから修正に取りかかる
        • すぐにまた変更しそうなコード (HTML構造の細部など) に対するテストは「後で」書く
        • リファクタリングするときは「先に」テストを書く
          • 特に、エラーを起こしそうなコードや止まってしまいそうなコードを集中的にテスト
      • 不安定な要素が特に見当たらないアプリケーションや、(主にビューが) 頻繁に改定される可能性の高いアプリケーションのコードを書くときには、思い切ってテストを省略してしまうこともある
    • 本書における主要なテストは、コントローラテスト (この節より)、モデルテスト (第6章より)、統合テスト (第7章より) の3つ
      • 統合テストでは、ユーザーがWebブラウザでアプリケーションとやりとりする操作をシミュレートできるので特に強力
      • まずは取っ付きやすいコントローラテストから
    • 最初のテスト
      • test/controllers/static_pages_controller_test.rbの確認
      • rails test
      • テストの実行にはある程度時間がかかる
        • (1) Springサーバーを起動してRails環境を事前読み込みするのに時間がかかる
          • 最初の1回だけ
        • (2) Rubyそのものの起動に時間がかかる
          • 3.6.2で紹介するGuardを導入することで改善
    • Red
    • Green
      • get 'static_pages/about'
        • /static_pages/aboutというURLに対してGETリクエストが来たら、StaticPagesコントローラのaboutアクションに渡すようRailsに指示しています。この結果、自動的に次のようなヘルパーが使えるようになります
          • static_pages_about_url
      • Railsでは、テンプレートとはすなわち「ビュー」
      • touch app/views/static_pages/about.html.erb
        • touchコマンドは本来、ファイルやディレクトリのタイムスタンプだけを更新するためのコマンドなのですが、ファイルが存在しない場合には空ファイルを作成するという一種の副作用
    • Refactor
  • 少しだけ動的なページ
    • ページの内容に応じて、ページのタイトルを自ら書き換えて表示
    • タイトルをテストする (Red)
      • 典型的なWebページは、リスト 3.23のようなHTMLの構造
        • 1) document type (doctype)は使用するHTMLのバージョン (ここではHTML5) をブラウザに対して宣言
        • 2) headセクション。ここではtitleタグに囲まれた「Greeting」(=あいさつ) という文字
        • 3) bodyセクション。ここには「Hello, world!」という文字列
      • セレクタ
        • assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
    • タイトルを追加する (Green)
    • レイアウトと埋め込みRuby (Refactor)
      • 重複を取り除くテクニックの1つとして、ビューで「埋め込みRuby」(Embedded Ruby) が使えます
      • Railsのprovideメソッドを使ってタイトルをページごとに変更
      • ERBと呼ばれている、Rubyの埋め込みコード
        • ERBはWebページに動的な要素を加えるときに使うテンプレートシステム
        • <% provide(:title, "Home") %>
          • <% ... %>という記法が使われており、その中からRailsのprovideメソッドを呼び出し
          • "Home"という文字列と:titleというラベルを関連付け
        • <% ... %>と書くと、中に書かれたコードを単に実行するだけで何も出力しません。<%= ... %>のように等号を追加すると、中のコードの実行結果がテンプレートのその部分に挿入
      • HTMLの重複した構造をDRYにする
        • Railsにはそのためにapplication.html.erbという名前のレイアウトファイルがあります
        • <%= yield %>
          • レイアウトを使う際に、/static_pages/homeにアクセスするとhome.html.erbの内容がHTMLに変換され、<%= yield %>の位置に挿入
        • スタイルシートJavaScriptは、Asset Pipeline (5.2.1) の一部
        • csrf_meta_tagsは、Web攻撃手法の1つであるクロスサイトリクエストフォージェリー (Cross-Site Request Forgery: CSRF)を防ぐために使われるRailsのメソッド
        • レイアウトと重複するHTMLがまだ残っているので、それらを削除して、内部のコンテンツだけ残します
      • 演習
        • まずはテストを追加
          • urlを変えるのも必要
        • routesを追加
        • controller_actionを追加
        • erbを追加
    • ルーティングの設定
      • 演習
        • root_url
  • 最後に
    • 本章のまとめ
      • 新しいRailsアプリケーションをゼロから作成したのはこれで3度目。今回も必要なgemのインストール、リモートリポジトリへのプッシュ、production環境まで行った
      • コントローラを新規作成するためのrailsコマンドはrails generate controller ControllerName アクション名 (省略可)
      • 新しいルーティングはconfig/routes.rbファイルで定義
      • Railsのビューでは、静的HTMLの他にERB (埋め込みRuby: Embedded RuBy) が使える
      • 常に自動化テストを使って新機能開発を進めることで、自信を持ってリファクタリングできるようになり、回帰バグも素早くキャッチ
      • テスト駆動開発では「red ・ green ・REFACTOR」サイクルを繰り返す
      • Railsのレイアウトでは、アプリケーションのページの共通部分をテンプレートに置くことでコードの重複を解決
  • 高度なセットアップ
    • minitest reporters
      • minitest-reporters gemを利用
        • test/test_helper.rb
          • require "minitest/reporters"
          • Minitest::Reporters.use!
    • Guardによるテストの自動化
      • テストをしようとする度にエディタからコマンドラインに移動して、手動でコマンドを打ち込み、実行しなければならないという点が面倒
      • Guardは、ファイルシステムの変更を監視
        • 具体的には、「home.html.erbファイルが変更されたらstatic_pages_controller_test.rbを自動的に実行する」
      • bundle exec guard init
      • guard :minitest, spring: "bin/rails test", all_on_start: false do
        • GuardからSpringサーバーを使って読み込み時間を短縮しています (SpringはRailsの機能の1つです)
        • 開始時にテストスイートをフルで実行しないようGuardに指示
      • .gitignoreファイルにspring/ディレクトリを追加
      • Springのプロセスが起動したまま多数残留すると、テストのパフォーマンスが低下
        • テストの実行が異常に遅くなってきたと感じたら、プロセスをチェックし、必要に応じてSpringをkill
        • Unixのプロセス
          • ps aux
          • ps aux | grep spring
          • killコマンドでpidを指定し、Unixのkillコード(Cloud9の場合、シグナル番号は15) を発行
            • kill -15 12241
          • 特定の名前を持つプロセスをまとめてkill
            • spring stop
            • pkill -15 -f spring
      • bundle exec guard
      • テストを変更ファイルだけではなく、フルで実行したい場合は、guard>プロンプトでReturnキーを押します
        • (このとき、Springサーバーに接続できないなどのエラーが表示されることがあります。問題を修正するには、もう一度Returnキーを押します)
      • Guardを終了するにはCtrl-Dキー

Ch04 Rails風味のRuby

  • Railsにおいて重要となるRubyのさまざまな要素について探っていく
  • Rails開発者にとって必要な知識は比較的少なくて済みます
  • この章の目的は、「Rails風味のRuby」というものについての確固たる基盤を、皆さんのこれまでの言語経験に関わらず提供すること
  • 動機
    • 初歩的な作業をいつまでも続けるわけにはいきません
    • Rubyに関する知識と経験の限界に真正面から挑み、これを乗り越えるためにこの章を割り当てる
    • 組み込みヘルパー
      • <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        • Railsの組み込み関数stylesheet_link_tag (詳細はRails API参照) を使って、application.cssをすべてのメディアタイプで使えるようにしています
        • 少なくとも混乱を生じる可能性のあるRubyの概念が4つあります。Railsの組み込み関数、カッコを使わないメソッド呼び出し、シンボル、そしてハッシュ
    • カスタムヘルパー
      • app/helpers/application_helper.rb
  • 文字列とメソッド
    • Railsコンソールはirb (IRB: Interactive RuBy) を拡張して作られているため、Rubyの機能をすべて使うことができます
      • ~/.irbrc
        • IRB.conf[:PROMPT_MODE] = :SIMPLE
        • IRB.conf[:AUTO_INDENT_MODE] = false
    • rails console
    • Railsコンソールは素晴しい学習ツールであり、その中を自由に探索できます
    • コンソールの中で何をしようとも、何かを壊すことは (まず) ありえないので、ご安心ください
      • Railsコンソールが何かおかしな挙動になったら、Ctrl-Cを押してコンソールから強制的に抜け出すことができます。もしくは、Ctrl-Dを押して正常にコンソールを終了させることもできます
    • Rubyリファレンスマニュアル (通称: るりま) やるりまサーチが大変便利
    • コメント
      • Rubyのコメントはナンバー記号# (「ハッシュマーク」や「オクトソープ」とも呼ばれます) から始まり、その行の終わりまでがコメント
    • 文字列
      • 文字列 (string) は、Webアプリケーションにおいておそらく最も重要なデータ構造
        • Webページというものが究極的にはサーバーからブラウザに送信された文字列にすぎないため
      • 文字列リテラルと呼ばれ (面白いことにリテラル文字列とも呼ばれます)ダブルクォート " で囲むことで作成
      • 文字列を組み立てる他の方法として式展開 (interpolation) というものがあり、#{}という特殊な構文を使います
        • PerlPHPに精通した開発者であれば、"foo $bar"のようなドル記号による自動的な挿入を連想して比較することでしょう
        • first_name = "Michael"
        • "#{first_name} Hartl"
      • 出力
        • puts (putの三人称単数現在形ではなく「put string」の略なので、本来は「put ess」と発音しますが、最近は「puts」と発音されることも多くなってきました)
        • putsを使って出力すると、改行文字である\nが自動的に出力の末尾に追加されます (これはターミナルのechoコマンドと同じ振る舞いになります)
          • printメソッドも同様の出力を行いますが、次のように、改行文字を追加しない点が異なります
      • シングルクォート内の文字列
        • ほとんどの場合、ダブルクォートとシングルクォートのどちらを使っても実質的に同じ
        • Rubyはシングルクォート文字列の中では式展開を行いません
        • ダブルクォート文字列を用いた文字列で#のような特殊な文字を使いたい場合は、この文字をバックスラッシュでエスケープ (escape) する必要があります
        • シングルクォートは、入力した文字をエスケープせずに「そのまま」保持するときに便利
      • 演習
        • tab: \t
    • オブジェクトとメッセージ受け渡し
      • オブジェクトとは (いついかなる場合にも) メッセージに応答するもの
        • オブジェクトに渡されるメッセージは、一般にはメソッドと呼ばれます。メソッドの実体は、そのオブジェクト内で定義されたメソッド
      • メソッドがtrueまたはfalseという論理値 (boolean) を返すことを、末尾の疑問符で示す慣習
        • 論理値は、特に処理の流れを変更するときに有用
      • Rubyでは、あらゆるものがオブジェクトです。したがって、nilもオブジェクト
        • ほぼあらゆるオブジェクトを文字列に変換するto_sメソッドを使って、nilがメソッドに応答する例
        • nilに対してメソッドをチェーン (chain) して渡せることを確認
          • nil.to_s.empty?
      • puts "x is not empty" if !x.empty?
        • Rubyではこのように、後続するifでの条件式が真のときにだけ実行される式 (後続if) を書くことができ、コードが非常に簡潔になります。なお、unlessキーワードも同様に使えます
      • Rubyにおいてnilは特別なオブジェクト
        • Rubyのオブジェクトのうち、オブジェクトそのものの論理値がfalseになるのは、false自身とnilの2つしかありません
          • 「!!」(「バンバン (bang bang)」と読みます) という演算子を使うと、そのオブジェクトを2回否定することになるので、どんなオブジェクトも強制的に論理値に変換できます
          • その他のあらゆるRubyのオブジェクトは、ゼロですらtrue
    • メソッドの定義
      • メソッドの引数を省略することも可能です (カッコですら省略可能です)
        • 引数にデフォルト値を含めているから
      • Rubyのメソッドには「暗黙の戻り値がある」ことにご注意ください。これは、メソッド内で最後に評価された式の値が自動的に返される
    • titleヘルパー、再び
      • module ApplicationHelperという要素について
        • モジュールは、関連したメソッドをまとめる方法の1つで、includeメソッドを使ってモジュールを読み込むことができます (ミックスイン (mixed in) とも呼びます)
        • Railsでは自動的にヘルパーモジュールを読み込んでくれるので、include行をわざわざ書く必要がありません
  • ほかのdata_structure
    • 配列と範囲演算子
      • "fooxbarxbaz".split('x')
      • Rubyでは、角カッコ以外にも配列の要素にアクセスする方法が提供されています
        • first, second, last
        • a.last == a[-1]
          • true
      • 配列の内容を変更したい場合は、そのメソッドに対応する「破壊的」メソッドを使います。破壊的メソッドの名前には、元のメソッドの末尾に「!」を追加したものを使うのがRubyの慣習です
      • pushメソッド (または同等の<<演算子) を使って配列に要素を追加することもできます
      • 他の多くの言語の配列と異なり、Rubyでは異なる型が配列の中で共存できます
      • 文字列を配列に変換するのにsplitを使いました。joinメソッドはこれと逆の動作
        • a.join(', ')
      • 範囲 (range) は、配列と密接に関係しています。to_aメソッドを使って配列に変換すると理解しやすい
        • (0..9).to_a
      • 範囲は、配列の要素を取り出すのに便利
        • a[0..2]
        • インデックスに-1という値を指定できるのは極めて便利です。-1を使うと、配列の長さを知らなくても配列の最後の要素を指定することができ、これにより配列を特定の開始位置の要素から最後の要素までを一度に選択することができます
        • a[2..-1]
      • 文字列に対しても範囲オブジェクトが使えます
        • ('a'..'e').to_a
    • ブロック
      • 配列と範囲はいずれも、ブロックを伴うさまざまなメソッドに対して応答することができます
        • (1..5).each { |i| puts 2 * i }
          • メソッドに渡されている{ |i| puts 2 * i }が、ブロックと呼ばれる部分
          • |i|では変数名が縦棒「|」に囲まれていますが、これはブロック変数に対して使うRubyの構文で、ブロックを操作するときに使う変数を指定
          • ブロックであることを示すには波カッコ で囲みますが、次のようにdoとendで囲んで示すこともできます
            • 短い1行のブロックには波カッコを使い、長い1行や複数行のブロックにはdo..end記法
          • ブロックは見た目に反して奥が深く、ブロックを十分に理解するためには相当なプログラミング経験が必要
      • mapメソッドなどを使ったブロックの使用例
        • 3.times { puts "Betelgeuse!" }
        • (1..5).map { |i| i**2 }
        • %w[a b c].map { |char| char.upcase }
          • mapのブロック内で宣言した引数 (char) に対してメソッドを呼び出しています。こういったケースでは省略記法が一般的で、次のように書くこともできます (この記法を“symbol-to-proc”と呼びます)
          • %w[A B C].map(&:downcase)
            • 元々Ruby on Rails独自の記法でした。しかし多くの人がこの記法を好むようになったので、今ではRubyのコア機能として導入
        • mapメソッドは、渡されたブロックを配列や範囲オブジェクトの各要素に対して適用し、その結果を返します
      • 最後のブロックの例として、単体テスト
      • ('a'..'z').to_a.shuffle[0..7].join
      • 演習
        • (0..16).map {|i| i**2}
        • str.map {|s| s.upcase}.join
        • s.split('').shuffle.join
    • ハッシュとシンボル
      • ハッシュは本質的には配列と同じですが、インデックスとして整数値以外のものも使える点が配列と異なります (この理由から、Perlなどのいくつかの言語ではハッシュを連想配列と呼ぶこともあります)
        • ハッシュのインデックス (キーと呼ぶのが普通です) は、通常何らかのオブジェクト
      • ハッシュの波カッコは、ブロックの波カッコとはまったく別物
        • {"last_name"=>"Hartl", "first_name"=>"Michael"}
      • ハッシュでは要素の「並び順」が保証されない
      • ハッシュの1要素を角カッコを使って定義する代わりに、次のようにキーと値をハッシュロケットと呼ばれる=> によってリテラル表現するほうが簡単
        • user = { "first_name" => "Michael", "last_name" => "Hartl" }
      • key: Railsでは文字列よりもシンボルを使う方が普通
        • シンボルは文字列と似ていますが、クォートで囲む代わりにコロンが前に置かれている
        • 余計なことを一切考えずに、シンボルを単なる文字列とみなしても構いません
          • 余計なものを削ぎ落した結果、シンボル同士の比較を容易に行えます。文字列は1文字ずつ比較する必要がありますが、シンボルは一度に全体を比較できます。これはハッシュのキーとして理想的な性質です。
        • シンボルは、Ruby以外ではごく一部の言語にしか採用されていない特殊なデータ形式
        • 文字列と違って、全ての文字が使えるわけではない
        • 未定義のハッシュ値は単純にnil
        • ハッシュではシンボルをキーとして使うことが一般的なので、Ruby 1.9からこのような特殊な場合のための新しい記法がサポート
          • h2 = { name: "Michael Hartl", email: "michael@example.com" }
          • :name =>とname:は、ハッシュとしてのデータ構造は全く同じ
      • ハッシュの値にはほぼ何でも使うことができ、他のハッシュを使うことすらできます → ネストされたハッシュ
      • 配列や範囲オブジェクトと同様、ハッシュもeachメソッドに応答します
      • 便利なinspectメソッドを紹介します。これは要求されたオブジェクトを表現する文字列を返します
        • オブジェクトを表示するためにinspectを使うことは非常によくあることなので、 pメソッドというショートカットがあります
        • p :name # 'puts :name.inspect' と同じ
      • 演習
    • CSS、再び
      • <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        • Ruby では丸カッコは使用してもしなくても構いません
        • ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略できます
        • Rubyは改行と空白を区別していません
        • 最初の引数である文字列は、スタイルシートへのパスを示しています
        • 次の引数であるハッシュには2つの要素があり、最初の要素はメディアタイプを示し、次の要素はRails 4.0で追加されたturbolinksという機能をオンにしています
      • CSSファイル名の後に、?body=1のような行が余分に表示されていることがあります。これらはRailsによって挿入されているもので、サーバー上で変更があった場合にブラウザがCSSを再読み込みするのに使います
  • Rubyにおけるクラス
    • 参照
    • コンストラク
      • s = "foobar" # ダブルクォートは実は文字列のコンストラク
      • 暗黙のリテラルコンストラクタを使う代わりに、明示的に同等の名前付きコンストラクタを使うことができます。名前付きコンストラクタは、クラス名に対してnewメソッドを呼び出します
      • 配列のコンストラクタであるArray.new は配列の初期値を引数に取りますが、 Hash.new はハッシュのデフォルト 値を引数に取ります
    • クラス継承
      • クラスについて学ぶとき、superclassメソッドを使ってクラス階層を調べてみるとよくわかります
      • 文字列を引数に取るメソッドを作るためだけに、わざわざ新しいクラスを作るのは変です。単語は文字列なので、リスト 4.15のようにWordクラスは Stringクラスを継承するのが自然です
      • Stringクラスの内部では、メソッドや属性を呼び出すときのself.も省略可能
        • self == reverse
    • 組み込みクラスの変更
      • Ruby のクラスはオープンで変更可能であり、クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています
      • 真に正当な理由がない限り、組み込みクラスにメソッドを追加することは無作法であると考えられています
      • Railsの場合、組み込みクラスの変更を正当化できる理由がいくつもあります
        • Railsはblank?メソッドをRuby に追加しています
          • スペースが集まってできた文字列は空 (empty) とは認識されませんが、空白 (blank) であると認識されている
    • コントローラクラス
      • class StaticPagesController < ApplicationController
      • Railsのアクションには戻り値がありません。少なくとも、返される値は重要ではありません
        • home アクションはWebページを表示するためのものであり、値を返すためのものではありませんでした
      • 第3章では一度もStaticPagesController.newを実行しませんでした
        • Railsは確かにRubyで書かれていますが、既にRubyとは別物
    • ユーザークラス
      • Railsでは、インスタンス変数をコントローラ内で宣言するだけでビューで使えるようになる、といった点に主な利用価値があります
      • インスタンス変数は常に@記号で始まり、まだ定義されていなければ値がnil
      • initializeは、Rubyの特殊なメソッドです。これは User.newを実行すると自動的に呼び出されるメソッド
      • マスアサインメント (mass assignment)
        • initializeメソッドにハッシュを渡すことで、属性が定義済みの他のユーザを作成
  • 最後に
    • 本章のまとめ
      • Rubyは文字列を扱うためのメソッドを多数持っている
      • Rubyの世界では、すべてがオブジェクトである
      • Rubyではdefというキーワードを使ってメソッドを定義する
      • Rubyではclassというキーワードを使ってクラスを定義する
      • Railsのビューでは、静的HTMLの他にERB (埋め込みRuby: Embedded RuBy) も使える
      • Rubyの組み込みクラスには配列、範囲、ハッシュなどがある
      • Rubyのブロックは (他の似た機能と比べ) 柔軟な機能で、添え字を使ったデータ構造よりも自然にイテレーションができる
      • シンボルとはラベルである。追加的な構造を持たない (代入などができない) 文字列みたいなもの
      • Rubyではクラスを継承できる
      • Rubyでは組み込みクラスですら内部を見たり修正したりできる

Ch05 レイアウトを作成する

  • この章では、アプリケーションにBootstrapフレームワークを組み込み、そして、カスタムスタイルを追加します
  • 構造を追加する
    • カスタムCSSルールの他に、Twitter社によるオープンソースのWebデザインフレームワークとして公開しているBootstrapも利用します
    • コードそのものにもスタイルを与えます。つまり、散らかり始めたレイアウトのコードを、パーシャル (Partial) 機能を使って整えていくということ
    • Webアプリケーションを作成するときに、ユーザーインターフェイスの概要をできるだけ早いうちに把握しておくことがしばしば有用
    • ナビゲーション
      • RailsはデフォルトでHTML5を使います
        • 一部のブラウザ (特に旧式のInternet Explorer) ではHTML5のサポートが不完全である場合があります。そのため、次のようなJavaScriptのコード (通称: HTML5 shim (or shiv))3 を使ってこの問題を回避
      • headerタグは、ページの上部に来るべき要素を表します
      • すべてのHTML要素には、クラスとidの両方を指定することができます
        • これらは単なるラベルで、CSSでスタイルを指定するときに便利
        • クラスとidの主な違いは、クラスはページ内で何度でも使えるのに対し、idは一度しか使えない点
      • divタグは一般的な表示領域を表し、要素を別々のパーツに分けるときに使われます。特に古いスタイルのHTMLでは、divタグはサイト内のほぼすべての領域で使われていました
        • HTML5からはよく使われる領域ごとに細分化できるようになり、具体的にはheader要素、nav要素、section要素が新たに使えるようになりました
      • リンクを生成するために、Railsヘルパーのlink_to
        • link_toの第1引数はリンクテキスト、第2引数はURL
        • このURLは5.3.3で名前付きルート (Named Routes) に置き換えますが、今はWebデザインで一般に使われるスタブ用の (とりあえずのダミーとして使われる) URL「'#'」を置いておきます
        • 第3引数はオプションハッシュ
          • Railsヘルパーは、このようにオプションのハッシュを取ることがよくあり、これによりRailsのコードから離れることなく任意のHTMLオプションを柔軟に追加することができます
      • リストアイテムタグliと順不同リストタグulによって作られた、ナビゲーションリンクのリスト
        • navタグには「その内側がナビゲーションリンクである」という意図を明示的に伝える役割
      • yieldメソッドはWebサイトのレイアウトにページごとの内容を挿入
      • 今後のスタイル要素を利用するために、home.html.erbビューに特別な要素をいくつか追加
        • 第7章でサイトにユーザーを追加するときに備えて、最初のlink_toで次のような仮のリンクを生成
        • divタグのCSSクラスjumbotronや、signupボタンのbtnクラス、btn-lgクラス、btn-primaryクラスはすべて、Bootstrapにおいて特別な意味
        • image_tagヘルパーの能力が示されています。このヘルパーでは、シンボルを使ってalt属性などを設定できます
          • rails.pngというRailsのロゴ画像ファイルを加える必要
          • app/assets/images/ディレクトリにおいてください
          • image_tagヘルパーを使っているので、Railsは該当する画像ファイルを、アセットパイプラインを通してapp/assets/images/ディレクトリの中から探してくれます
          • src属性には "images" というディレクトリ名が含まれていない
            • 高速化のための仕組みで、Railsはassetsディレクトリ直下の画像をapp/assets/imagesディレクトリにある画像と紐付け
            • ブラウザから見るとすべてのファイルが同じディレクトリにあるように見えるようになります。そして、このようなフラットなディレクトリ構成を採っていると、ファイルをより高速にブラウザに渡すことができるようになります
          • alt属性は、画像がない場合に代わりに表示される文字列です。例えば視覚障害のあるユーザーが使うスクリーンリーダーでは、ここの属性が読み上げられて、そこに画像があることが示されます
      • BootstrapとカスタムCSS
        • 多くのHTML要素にCSSクラスを関連付けました。こうしておくことで、CSSベースでレイアウトを構成する際に高い柔軟性
        • Bootstrapを使うことでアプリケーションをレスポンシブデザイン (Responsive Design) にできるということです。これにより、どの端末でアプリケーションを閲覧しても、ある程度見栄えをよくすることができます
        • bootstrap-sass gemを使ってRailsアプリケーションに導入できます
          • Bootstrapフレームワークでは、動的なスタイルシートを生成するためにLESS CSS言語を使っていますが、RailsのAsset Pipelineはデフォルトでは (LESSと非常によく似た) Sass言語をサポート
          • bootstrap-sassは、LESSをSassへ変換し、必要なBootstrapファイルを現在のアプリケーションですべて利用できるようにします
          • gem 'bootstrap-sass', '3.3.7'
        • カスタムCSSを動かすための最初の一歩は、カスタムCSSファイルを作ること
          • touch app/assets/stylesheets/custom.scss
            • app/assets/stylesheets/は,Asset Pipeline (5.2)の一部
            • ファイル名のcustom.scssには.scssという拡張子も含まれています
              • この拡張子は「Sass (Sassy CSS)」と呼ばれるCSSを拡張した言語で、アセットパイプラインはこのファイルの拡張子を見て、Sassを処理できるようにしています
        • Bootstrap CSSを追加する
          • app/assets/stylesheets/custom.scss
            • @import "bootstrap-sprockets";
            • @import "bootstrap";
        • すべてのページに適用される共通のスタイルをCSSに追加する
          • app/assets/stylesheets/custom.scss
          • CSSでは /* … */ でコメントアウトできるので、調べてみたいコードをこれで囲い、表示がどのように変わるかを確認
        • CSSルールでは一般に、クラス、id、HTMLタグ、またはそれらの組み合わせ、のいずれかを指定します。そしてその後ろにスタイリングコマンドのリストを記述します。
        • .center冒頭のドット.は、このルールがクラスに対してスタイルを適用することを示しています
          • centerクラスに属している (divなどの) タグの内側にある要素が、すべて中央揃えになることを意味
        • 冒頭がポンド記号#で始まる場合は、そのルールがCSSのidに対してスタイルを適用することを示します
        • Bootstrapには洗練されたタイポグラフィーを利用できるCSSルールがあります
          • テキストの見栄えを変えてみましょう
        • いくつかのルールをサイトロゴに追加
          • テキストを大文字に変換し、サイズ、色、配置を変更
        • 演習
          • comment out
            • <%#= image_tag("kitten.jpg", alt: "Kitten") %>
          • すべての画像を非表示
            • img {
              • display: none;
    • パーシャル (partial)
      • app/views/layouts/application.html.erb
        • renderと呼ばれるRailsヘルパー呼び出しだけを使って、HTML shimのスタイルシート行を置換
        • app/views/layouts/_shim.html.erbというファイルを探してその内容を評価し、結果をビューに挿入
          • アンダースコアは、パーシャルで使う普遍的な命名規約であり、また、一目見ただけでディレクトリ中のすべてのパーシャルを識別することが可能になります
        • app/views/layouts/_header.html.erb
        • app/views/layouts/_footer.html.erb
        • footerの追加
          • styleも追加
  • Sassとアセットパイプライン
    • CSSJavaScript、画像などの静的コンテンツの生産性と管理を大幅に強化する「アセットパイプライン (Asset Pipeline)」
    • アセットパイプラインの概要と、素晴らしいCSS生成ツールである「Sass」の使い方について
    • アセットパイプライン
      • Rails開発者の視点からは、アセットディレクトリ、マニフェストファイル、プリプロセッサエンジンという、3つの主要な機能が理解の対象
      • アセットディレクト
        • 静的ファイルを目的別に分類する、標準的な3つのディレクト
          • app/assets: 現在のアプリケーション固有のアセット
          • lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
          • vendor/assets: サードパーティのアセット
          • これらのディレクトリには、それぞれのアセットクラス用のサブディレクトリがあります。例えばapp/assetsの場合、次のような画像用、JavaScript用、CSS用のサブディレクトリがあります
      • マニフェストファイル
        • 静的ファイル (アセット) を上記の場所へそれぞれ配置すれば、マニフェストファイルを使って、それらをどのように1つのファイルにまとめるのかをRailsに指示することができます
        • 実際にアセットをまとめる処理を行うのはSprocketsというgem
        • マニフェストファイルはCSSJavaScriptには適用されますが、画像ファイルには適用されません
        • Railsには実用的なデフォルトのマニフェストファイルが付属している
      • プリプロセッサエンジン
      • 本番環境での効率性
        • Asset Pipelineの最大のメリットの1つは、本番のアプリケーションで効率的になるように最適化されたアセットも自動的に生成されること
        • 具体的には、Asset Pipelineがすべてのスタイルシートを1つのCSSファイル (application.css) にまとめ、すべてのJavaScriptファイルを1つのJSファイル (javascripts.js) にまとめてくれます。さらに、それらのファイルすべてに対して 不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化してくれます。
          • 結果として、開発環境と本番環境という、2つの異なった状況に対してそれぞれ最高の環境を提供
    • 素晴らしい構文を備えたスタイルシート
      • Sass は、スタイルシートを記述するための言語であり、CSSに比べて多くの点が強化
      • SCSSは厳密な意味で、CSS本体を抽象化したフォーマットです。つまり、SCSSはCSSに新しい機能を追加しただけで、全く新しい構文を定義したようなものではない
      • Railsのアセットパイプラインは、.scssという拡張子を持つファイルをSassを使って自動的に処理
      • ネスト
        • Sassは、SCSSをCSSに変換する際に、&:hoverを#logo:hoverに置き換え
      • 変数
        • $light-gray: #777;
        • 定義されている変数はBootstrapページの「LESS変数一覧」で参照
          • このWebサイトでは、SassではなくLESSを使って変数が定義されていますが、bootstrap-sassというgemを使えば、Sassでも同様の変数が使えるようになります
      • リスト 5.20: ネストや変数を使って初期のSCSSファイルを書き直した結果
  • レイアウトのリンク
    • 名前付きルート
    • サイトリンクのルーティングとURLのマッピング
      • ページ名 URL 名前付きルート
    • Contactページ
      • 第3章の演習のとおり,Contactページについて追加
    • RailsのルートURL
      • 名前付きルートをサンプルアプリケーションの静的ページで使うために、ルーティング用のファイル (config/routes.rb) を編集
      • ルートURLのようなルーティングを定義することの効果
        • ブラウザからアクセスしやすくする
        • 生のURLではなく、名前付きルートを使ってURLを参照することができる
          • root_path: ルートURL以下の文字列
          • root_url: 完全なURLの文字列を返します
      • Railsチュートリアルでは一般的な規約に従い、基本的にはpath書式を使い、リダイレクトの場合のみurl書式を使う
        • HTTPの標準としては、リダイレクトのときに完全なURLが要求されるため
        • ほとんどのブラウザでは、どちらの方法でも動作します
      • get '/help', to: 'static_pages#help'
      • 演習
        • 名前付きルートは、as:オプションを使って変更することができます
          • get '/help', to: 'static_pages#help', as: 'helf'
    • 名前付きルート
      • link_toメソッドの2番目の引数で、適切な名前付きルートを使ってみましょう
    • リンクのテスト
      • 「統合テスト (Integration Test)」を使って一連の作業を自動化
      • rails generate integration_test site_layout
        • Railsは渡されたファイル名の末尾に _test という文字列を追加する
      • assert_selectメソッドの高度なオプション
        • 特定のリンクが存在するかどうかを、aタグとhref属性をオプションで指定して調べています
        • assert_select "a[href=?]", about_path
        • assert_select "a[href=?]", root_path, count: 2
          • リンクの個数も調べる
        • assert_selectは柔軟でパワフルな機能で、ここでは紹介し切れないほど他にも多くのオプションがあります
          • 経験的には、このメソッドで複雑なテストはしない方が賢明
          • 今回のようなレイアウト内で頻繁に変更されるHTML要素 (リンクなど) をテストするぐらいに抑えておくとよい
      • rails test:integration
      • 演習
        • test環境でもApplicationヘルパーを使えるようにする
  • ユーザー登録: 最初のステップ
    • Usersコントローラ
      • 2番目のコントローラであるUsersコントローラを作成
      • generateを実行して、現時点での要求である新規ユーザー用のユーザー登録ページ (スタブ) を持つ、最も簡単なコントローラを作成
      • Railsで好まれているRESTアーキテクチャの規約に従い、新規ユーザー用のアクションをnewとします。したがって、generate controllerの引数にnewを渡して、自動的にアクションを作成
        • rails generate controller Users new
    • ユーザー登録用URL
      • ユーザー登録URL用にget '/signup'のルートを追加(1つ上の演習と同じ)
        • get '/signup', to: 'users#new'
      • Usersコントローラのテストで名前付きルートを使うようにする
      • ボタンにユーザー登録ページへのリンクを追加する
      • 最初のユーザー登録ページ (スタブ)
      • 演習
        • get signup_path
        • assert_select "title", full_title("Sign up")
  • 最後に
    • この章では、アプリケーションのレイアウトを形にし、ルーティングを洗練させました
    • 本章のまとめ
      • HTML5を使ってheaderやfooter、logoやbodyといったコンテンツのレイアウトを定義
      • Railsのパーシャルは効率化のために使われ、別ファイルにマークアップを切り出すことができます
      • CSSは、CSSクラスとidを使ってレイアウトやデザインを調整します
      • Bootstrapフレームワークを使うと、いい感じのデザインを素早く実装できる
      • SassとAsset Pipelineは、(開発効率のために切り分けられた) CSSの冗長な部分を圧縮し、本番環境に最適化した結果を出力する
      • Railsのルーティングでは自由にルールを定義することができ、また、その際に名前付きルートも使えるようになる
      • 統合テストは、ブラウザによるページ間の遷移を効率的にシミュレートする

Ch06 ユーザーのモデルを作成する

  • 一番重要なステップであるユーザー用のデータモデルの作成と、データを保存する手段の確保について
  • 第6章から第12章を通して、Railsのログインと認証システムをひととおり開発
  • コラム 6.1. 自分で認証システムを作ってみる
    • ある実践的な実験によると、多くのサイトの認証システムは膨大なカスタマイズを必要とするため、サードパーティ製品を変更して導入する場合にはシステムをゼロから作成するよりも多くの仕事を要するという結果
    • 既成品のシステムは内部がわかりづらいことが多く、ブラックボックス
    • 最近のRailsへの変更 (6.3) により、カスタム認証システムを容易に作成できるようになりました
    • あえて最終的にサードパーティの認証システムを導入することになったとしても、自分自身で認証システムを構築した経験があれば、サードパーティ製品を理解して変更することがずっと容易になる
  • Userモデル
    • ユーザー登録でまず初めにやることは、それらの情報を保存するためのデータ構造を作成すること
    • Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデル (Model)
    • Railsでは、データを永続化するデフォルトの解決策として、データベースを使ってデータを長期間保存
    • データベースとやりとりをするデフォルトのRailsライブラリはActive Record
      • Active Recordは、データオブジェクトの作成/保存/検索のためのメソッドを持っています
        • これらのメソッドを使うのに、リレーショナルデータベースで使うSQL (Structured Query Language)2 を意識する必要はありません
    • Railsにはマイグレーション (Migration) という機能
      • データの定義をRubyで記述することができ、SQLDDL (Data Definition Language) を新たに学ぶ必要がありません
    • Railsは、データベースの細部をほぼ完全に隠蔽し、切り離してくれます
      • 実際、本書ではSQLiteを開発 (development) 環境で使い、また、PostgreSQLを (Herokuでの) 本番環境 (production) で使います (1.5) が、本番環境のデータの保存方法の詳細について考える必要はほとんどありません
    • データベースの移行
      • Railsでユーザーをモデリングするときは、属性を明示的に識別する必要がありません
      • nameやemailといったカラム名を今のうちに考えておくことで、後ほどUserオブジェクトの各属性をActiveRecordに伝えるときに楽になります
      • rails generate model User name:string email:string
        • データベースで使いたい2つの属性をRailsに伝えます。このときに、これらの属性の型情報も一緒に渡します
        • generateコマンドの結果のひとつとして、マイグレーションと呼ばれる新しいファイルが生成
          • マイグレーションは、データベースの構造をインクリメンタルに変更する手段を提供
          • マイグレーション自体は、データベースに与える変更を定義したchangeメソッドの集まり
            • リスト 6.2の場合、changeメソッドはcreate_tableというRailsのメソッドを呼び、ユーザーを保存するためのテーブルをデータベースに作成
            • create_tableメソッドはブロック変数を1つ持つブロック (4.3.2) を受け取ります
              • そのブロックの中でcreate_tableメソッドはtオブジェクトを使って、nameとemailカラムをデータベースに作ります
            • モデル名は単数形 (User) ですが、テーブル名は複数形 (users) です
              • モデルはひとりのユーザーを表すのに対し、データベースのテーブルは複数のユーザーから構成
            • t.timestampsは特別なコマンドで、created_atとupdated_atという2つの「マジックカラム (Magic Columns)」を作成
            • rails db:migrate
              • 初めてdb:migrateが実行されると、db/development.sqlite3という名前のファイルが生成
                • SQLite データベースの実体
                • development.sqlite3ファイルを開くためのDB Browser for SQLiteという素晴らしいツールを使うと、データベースの構造を見ることができます
      • 演習
        • ほぼすべてのマイグレーションは、元に戻すことが可能
          • rails db:rollback
            • drop_tableとcreate_tableがそれぞれ対応していることをchangeメソッドが知っている
            • あるカラムを削除するような不可逆なマイグレーションの場合は、changeメソッドの代わりに、upとdownのメソッドを別々に定義する必要があります
    • modelファイル
      • class User < ApplicationRecord
    • ユーザーオブジェクトを作成する
      • rails console --sandbox
      • 初期化ハッシュ (hash) を引数に取る
        • 同様の方法でオブジェクトを初期化するActive Recordの設計
      • Active Recordを理解する上で、「有効性 (Validity)」という概念も重要
        • user.valid?
          • ただオブジェクトが有効かどうかを確認しただけ
        • データベースにUserオブジェクトを保存するためには、userオブジェクトからsaveメソッドを呼び出す必要
          • モデルの生成と保存を2つのステップに分けておくと何かと便利
            • しかし、Active RecordではUser.createでモデルの生成と保存を同時におこなう方法も提供されています
              • User.create(name: "A Nother", email: "another@example.org")
              • User.createは、trueかfalseを返す代わりに、ユーザーオブジェクト自身を返すことに注目
            • destroyはcreateの逆
              • 削除されたオブジェクトは次のようにまだメモリ上に残っています
    • ユーザーオブジェクトを検索する
      • User.find(1)
      • recordなし → findメソッドは例外 (exception) を発生
        • 存在しないActive Recordのidによって、findでActiveRecord::RecordNotFoundという例外が発生
      • User.find_by(email: "mhartl@example.com")
        • find関連メソッドは、ユーザーをサイトにログインさせる方法を学ぶときに役に立ちます
      • User.first
      • User.all
      • 演習
        • User.allで生成されるオブジェクトを調べ、ArrayクラスではなくUser::ActiveRecord_Relationクラスであることを確認
        • User.allに対してlengthメソッドを呼び出すと、その長さを求められることを確認
          • ダックタイピング (duck typing)
    • ユーザーオブジェクトを更新する
      • user.email = "mhartl@example.net"
      • 変更をデータベースに保存するために最後にsaveを実行
      • 保存を行わずにreloadを実行すると、データベースの情報を元にオブジェクトを再読み込みするので、変更が取り消されます
      • user.update_attributes(name: "The Dude", email: "dude@abides.org")
      • 特定の属性のみを更新したい場合は、次のようにupdate_attribute
        • user.update_attribute(:name, "El Duderino")
        • 検証を回避
      • 演習
        • created_atも直接更新
          • 更新するときは「1.year.ago」を使うと便利です。これはRails流の時間指定の1つで、現在の時刻から1年前の時間を算出してくれます
  • ユーザーを検証する
    • Active Record では検証 (Validation) という機能を通して、こういった制約を課すことができる
      • 存在性 (presence)の検証、長さ (length)の検証、フォーマット (format)の検証、一意性 (uniqueness)の検証
      • 最終検証として確認 (confirmation)
    • 有効性を検証する
      • 具体的なテスト方法についてですが、まず有効なモデルのオブジェクトを作成し、その属性のうちの1つを有効でない属性に意図的に変更します。そして、バリデーションで失敗するかどうかをテストする、といった方針で進めてい
      • test/models/user_test.rb
      • setup
      • rails test:models
    • 存在性を検証する
      • @user.name = " "
      • assert_not @user.valid?
      • name属性の存在を検査する方法は、リスト 6.9に示したとおり、validates メソッドにpresence: trueという引数を与えて使うこと
      • validates :name, presence: true
        • validatesは単なるメソッド
          • presence: trueという引数は、要素が1つのオプションハッシュです。4.3.4のようにメソッドの最後の引数としてハッシュを渡す場合、波カッコを付けなくても問題ありません
      • user.errors.full_messages
      • 演習
        • u.errors.messagesを実行すると、ハッシュ形式でエラーが取得
        • u.errors.messages[:email]
    • 長さを検証する
      • @user.email = "a" * 244 + "@example.com"
      • :maximumパラメータと共に用いられる:lengthは、長さの上限を強制
      • validates :name, presence: true, length: { maximum: 50 }
      • 演習
        • u = User.new(name: "a"51, email: "a"244 + "@example.com")
        • :email=>["is too long (maximum is 255 characters)"]
    • フォーマットを検証する
      • valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org first.last@foo.jp alice+bob@baz.cn]
      • assert @user.valid?, "#{valid_address.inspect} should be valid"
        • assertメソッドの第2引数にエラーメッセージを追加していることに注目してください。これによって、どのメールアドレスでテストが失敗したのかを特定できるようになります
      • メールアドレスのフォーマットを検証するためには、次のようにformatというオプションを使います
        • validates :email, format: { with: // }
        • VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
          • / 正規表現の開始を示す
          • \A 文字列の先頭
          • [\w+-.]+ 英数字、アンダースコア (_)、プラス (+)、ハイフン (-)、ドット (.) のいずれかを少なくとも1文字以上繰り返す
          • [a-z\d-.]+ 英小文字、数字、ハイフン、ドットのいずれかを少なくとも1文字以上繰り返す
          • [a-z]+ 英小文字を少なくとも1文字以上繰り返す
          • \z 文字列の末尾
          • / 正規表現の終わりを示す
          • i 大文字小文字を無視するオプション
        • Rubularという対話的に正規表現を試せるWebサイト
          • Rubularで使って学ぶ場合、冒頭の\Aと末尾の\zを含めずに試してみてください
        • format: { with: VALID_EMAIL_REGEX }
        • 大文字で始まる名前はRubyでは定数
      • 演習
    • 一意性を検証する
      • メールアドレスの一意性を強制するために (ユーザー名として使うために)、validatesメソッドの:uniqueオプションを使います
      • 重大な警告
        • 一意性のテストのためには、メモリ上だけではなく、実際にレコードをデータベースに登録する必要があります
        • まずは重複したメールアドレスからテスト
          • duplicate_user = @user.dup
          • @user.save
          • assert_not duplicate_user.valid?
      • 通常、メールアドレスでは大文字小文字が区別されません
        • duplicate_user.email = @user.email.upcase
        • uniqueness: { case_sensitive: false }
      • Active Recordはデータベースのレベルでは一意性を保証していないという問題
        • データベース上のemailのカラムにインデックス (index) を追加し、そのインデックスが一意であるようにすれば解決
        • コラム 6.2. データベースのインデックス
          • データベースにカラムを作成するとき、そのカラムでレコードを検索する (find) 必要があるかどうかを考えることは重要
            • すべてのユーザーを最初から順に一人ずつ探していく
              • データベースの世界では全表スキャン (Full-table Scan) として知られており、数千のユーザーがいる実際のサイトでは極めて不都合
            • emailカラムにインデックスを追加することで、この問題を解決
        • 既に存在するモデルに構造を追加するので、次のようにmigrationジェネレーターを使ってマイグレーションを直接作成する必要があります
          • rails generate migration add_index_to_users_email
            • ユーザー用のマイグレーションと異なり、メールアドレスの一意性のマイグレーションは未定義になっています。リスト 6.29のように定義を記述する必要
              • add_index :users, :email, unique: true
        • テストDB用のサンプルデータが含まれているfixtures内で一意性の制限が保たれていないため、テストは red になります
          • → 今は削除
        • いくつかのデータベースのアダプタが、常に大文字小文字を区別するインデックス を使っているとは限らない問題への対処
          • 今回は「データベースに保存される直前にすべての文字列を小文字に変換する」という対策
          • Active Recordのコールバック (callback) メソッドを利用
            • before_save { self.email = email.downcase }
      • 演習
        • assert_equal mixed_case_email.downcase, @user.reload.email
        • email.downcase!
          • メソッドの末尾に!を付け足すことにより、email属性を直接変更できるようになります
  • セキュアなパスワードを追加する
    • セキュアパスワードという手法では、各ユーザーにパスワードとパスワードの確認を入力させ、それを (そのままではなく) ハッシュ化したものをデータベースに保存
      • ハッシュ化: ハッシュ関数を使って、入力されたデータを元に戻せない (不可逆な) データにする処理
    • ユーザーの認証は、パスワードの送信、ハッシュ化、データベース内のハッシュ化された値との比較、という手順
    • ハッシュ化されたパスワード
      • セキュアなパスワードの実装は、has_secure_passwordというRailsのメソッドを呼び出すだけでほとんど終わってしまいます
      • has_secure_password
        • セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる
        • 2つのペアの仮想的な属性 (passwordとpassword_confirmation) が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される
        • authenticateメソッドが使えるようになる (引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド)
        • 魔術的なhas_secure_password機能を使えるようにするには、1つだけ条件
          • モデル内にpassword_digestという属性が含まれていること
      • 専門用語としての「暗号」というのは、設計上元に戻すことができることを指します
      • 「パスワードのハッシュ化」では元に戻せない (不可逆) という点が重要
      • 「計算量的に元のパスワードを復元するのは困難である」という点を強調するために、暗号化ではなくハッシュ化という用語を使っています
      • まずはpassword_digestカラム用の適切なマイグレーションを生成
        • マイグレーション名は自由に指定できますが、次に示すように、末尾をto_usersにしておくことをオススメ
        • rails generate migration add_password_digest_to_users password_digest:string
      • has_secure_passwordを使ってパスワードをハッシュ化するためには、最先端のハッシュ関数であるbcryptが必要
        • bcrypt gemをGemfileに追加
        • gem 'bcrypt', '3.1.12'
    • ユーザーがセキュアなパスワードを持っている
      • has_secure_passwordには、仮想的なpassword属性とpassword_confirmation属性に対してバリデーションをする機能も(強制的に)追加されている
        • password: "foobar", password_confirmation: "foobar"
      • 演習
        • {:password=>["can't be blank"]}
    • パスワードの最小文字数
      • @user.password = @user.password_confirmation = "a" * 5
        • 多重代入 (Multiple Assignment)
      • validates :password, presence: true, length: { minimum: 6 }
    • ユーザーの作成と認証
      • authenticateメソッド
        • 間違ったパスワードを与えた結果、user.authenticateがfalseを返した
        • 正しいパスワードを与えてみましょう。今度はauthenticateがそのユーザーオブジェクトを返すようになります
        • authenticateがUserオブジェクトを返すことは重要ではなく、返ってきた値の論理値がtrueであることが重要
          • !!でそのオブジェクトが対応する論理値オブジェクトに変換できることを思い出してください。この性質を利用すると、user.authenticateがいい感じに仕事をしてくれるようになります
      • 演習
        • user.update_attribute(:name, "test")
  • 最後に
    • ゼロからUserモデルを作成し、そこにname属性やemail属性、パスワード属性を加えました
    • それぞれの値を制限する多くの重要なバリデーションも追加
    • 渡されたパスワードをセキュアに認証できる機能も実装
    • たった12行でここまでの機能が実装
      • Railsの注目に値する特長
    • 本番環境でUserモデルを使うためには、heroku runコマンドを使ってHeroku上でもマイグレーションを走らせる必要があります
      • heroku run rails db:migrate
    • 本章のまとめ
      • マイグレーションを使うことで、アプリケーションのデータモデルを修正することができる
      • Active Recordを使うと、データモデルを作成したり操作したりするための多数のメソッドが使えるようになる
      • Active Recordのバリデーションを使うと、モデルに対して制限を追加することができる
      • よくあるバリデーションには、存在性・長さ・フォーマットなどがある
      • 正規表現は謎めいて見えるが非常に強力である
      • データベースにインデックスを追加することで検索効率が向上する。また、データベースレベルでの一意性を保証するためにも使われる
      • has_secure_passwordメソッドを使うことで、モデルに対してセキュアなパスワードを追加することができる

Ch07 ユーザー登録

  • ユーザーを表示する
    • ユーザーの名前とプロフィール写真を表示するためのページを作成
    • デバッグRails環境
      • Webサイトのレイアウトにデバッグ情報を追加
        • ビルトインのdebugメソッドとparams変数を使って、各プロフィールページにデバッグ用の情報が表示される
        • <%= debug(params) if Rails.env.development? %>
      • コラム 7.1. Railsの3つの環境
        • Railsにはテスト環境 (test)、開発環境 (development)、そして本番環境 (production) の3つの環境がデフォルトで装備されています。
        • Rails consoleのデフォルトの環境はdevelopment
        • RailsにはRailsというオブジェクトがあり、それには環境の論理値 (boolean) を取るenvという属性があります
          • Rails.env.test?はテスト環境ではtrueを返し、それ以外の環境ではfalse
        • rails console test
        • rails server --environment production
        • rails db:migrate RAILS_ENV=production
        • console、server、migrateの3つのコマンドでは、デフォルト以外の環境を指定する方法がそれぞれ異なっており、混乱を招く可能性があります
        • heroku run rails consoleというコマンドを打つことで、本番環境を確認
          • Herokuは本番サイト用のプラットフォームなので、実行されるアプリケーションはすべて本番環境
      • デバッグ出力をきれいに整形
        • app/assets/stylesheets/custom.scss
        • Sassのミックスイン機能 (ここではbox_sizing)
          • CSSルールのグループをパッケージ化して複数の要素に適用
          • @include box_sizing;
      • デバッグ出力には、描画されるページの状態を把握するのに役立つ情報が含まれます
        • paramsに含まれている内容で、YAML5 という形式で書かれています
        • YAMLは基本的にハッシュであり、コントローラとページのアクションを一意に指定
    • Usersリソース
      • Railsアプリケーションで好まれているRESTアーキテクチャ (コラム 2.2) の習慣に従う
        • データの作成、表示、更新、削除をリソース (Resources) として扱う
        • HTTP標準には、これらに対応する4つの基本操作 (POST、GET、PATCH、DELETE) が定義されているので、これらの基本操作を各アクションに割り当てていきます
        • RESTの原則に従う場合、リソースへの参照はリソース名とユニークなIDを使うのが普通
          • ユーザーをリソースとみなす場合、id=1のユーザーを参照するということは、/users/1というURLに対してGETリクエストを発行するということを意味
        • RailsのREST機能が有効になっていると、GETリクエストは自動的にshowアクションとして扱われます
      • resources :users
        • この1行を追加すると、ユーザーのURLを生成するための多数の名前付きルート (5.3.3) と共に、RESTfulなUsersリソースで必要となるすべてのアクションが利用できるようになる → 表7.1
        • 表 7.1: リスト 7.3のUsersリソースが提供するRESTfulなルート
      • app/views/users/show.html.erb
        • <%= @user.name %>, <%= @user.email %>
      • ユーザー表示ビューが正常に動作するためには、Usersコントローラ内のshowアクションに対応する@user変数を定義する必要
    • debuggerメソッド
      • byebug gemによるdebuggerメソッド
      • Railsアプリケーションの中でよく分からない挙動があったら、上のようにdebuggerを差し込んで調べてみましょう
      • byebug gemを使ってシステムの状態を調査することは、アプリケーション内のエラーを追跡したりデバッグするときに非常に強力なツールになります
    • Gravatar画像とサイドバー
      • Gravatar (Globally Recognized AVATAR) をプロフィールに導入
      • app/views/users/show.html.erb
        • <%= gravatar_for @user %>
      • GravatarのURLはユーザーのメールアドレスをMD5という仕組みでハッシュ化
        • Rubyでは、Digestライブラリのhexdigestメソッドを使うと、MD5のハッシュ化が実現できます
      • app/helpers/users_helper.rb
      • ユーザーのサイドバーの最初のバージョンを作りましょう
        • asideタグを使って実装
      • SCSSを使ってサイドバーなどのユーザー表示ページにスタイルを与える
      • HTML要素とCSSクラスを配置したことにより、プロフィールページ (とサイドバーとGravatar) にSCSSでリスト 7.11のようにスタイルを与えることができるようになりました
      • 演習
        • オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数 (Keyword Arguments)」でも実現することができます
  • ユーザー登録フォーム
    • form_forを使用する
      • ユーザー登録ページで重要な点は、ユーザー登録に欠かせない情報を入力するためのform
      • Railsでform_forヘルパーメソッドを使います。このメソッドはActive Recordのオブジェクトを取り込み、そのオブジェクトの属性を使ってフォームを構築
      • Rails 5.1から推奨されているform_withメソッドを使って学びたい方は『第6版』
      • ユーザー登録ページ /signup のルーティングは、Usersコントローラーのnewアクションに既に紐付けられている
        • 次のステップは、 form_forの引数で必要となるUserオブジェクトを作成すること
        • newアクションに@user変数を追加
      • app/views/users/new.html.erb
        • <%= form_for(@user) do |f| %>
      • app/assets/stylesheets/custom.scss
    • フォームHTML
      • <%= form_for(@user) do |f| %>
        • doキーワードは、 form_forが1つの変数を持つブロックを取ることを表します。この変数fは “form” のf
        • fオブジェクトは、HTMLフォーム要素 (テキストフィールド、ラジオボタン、パスワードフィールドなど) に対応するメソッドが呼び出されると、@userの属性を設定するために特別に設計されたHTMLを返します
      • ユーザーの作成で重要なのはinputごとにある特殊なname属性
        • Railsはnameの値を使って、初期化したハッシュを (params変数経由で) 構成
          • このハッシュは、入力された値に基づいてユーザーを作成するときに使われます
      • 次に重要な要素は、formタグ自身
        • Railsはformタグを作成するときに@userオブジェクトを使います
        • すべてのRubyオブジェクトは自分のクラスを知っている (4.4.1) ので、Railsは@userのクラスがUserであることを認識
        • @userは新しいユーザーなので、 Railsはpostメソッドを使ってフォームを構築すべきだと判断
          • 重要な属性は、action="/users"とmethod="post"の2つだけ
            • この2つの属性では、/users に対してHTTPのPOSTリクエスト送信する、といった指示をしています
  • ユーザー登録失敗
    • 正しいフォーム
      • createアクションでフォーム送信を受け取り、User.newを使って新しいユーザーオブジェクトを作成し、ユーザーを保存 (または保存に失敗) し、再度の送信用のユーザー登録ページを表示するという方法で機能を実装
      • app/controllers/users_controller.rb
        • if-else分岐構造を思い出してください。この文を使って、保存が成功したかどうかに応じて@user.saveの値がtrueまたはfalse (6.1.3) になるときに、それぞれ成功時の処理と失敗時の処理を場合分け
    • Strong Parameters
      • マスアサインメント
        • 値のハッシュを使ってRubyの変数を初期化
        • @user = User.new(params[:user])
        • paramsハッシュ全体を初期化するという行為はセキュリティ上、極めて危険
      • Strong Parametersを使うことで、必須のパラメータと許可されたパラメータを指定することができます
        • paramsハッシュをまるごと渡すとエラーが発生するので、Railsはデフォルトでマスアサインメントの脆弱性から守られるようになりました
        • params.require(:user).permit(:name, :email, :password, :password_confirmation)
          • 戻り値は、許可された属性のみが含まれたparamsのハッシュ
        • これらのパラメータを使いやすくするために、user_paramsという外部メソッドを使うのが慣習
          • app/controllers/users_controller.rb
            • user_paramsメソッドはUsersコントローラの内部でのみ実行され、Web経由で外部ユーザーにさらされる必要はないため、リスト 7.19に示すようにRubyのprivateキーワードを使って外部から使えないようにします
    • エラーメッセージ
      • ユーザーのnewページでエラーメッセージのパーシャル (partial) を出力
        • form-controlというCSSクラスも一緒に追加することで、Bootstrapがうまく取り扱ってくれる
        • app/views/shared/_error_messages.html.erb
      • 'shared/error_messages'というパーシャルをrender (描画) している
        • Rails全般の慣習として、複数のビューで使われるパーシャルは専用のディレクトリ「shared」によく置かれます
        • app/views/shared/_error_messages.html.erb
          • pluralizeという英語専用のテキストヘルパー
            • 最初の引数に整数が与えられると、それに基づいて2番目の引数の英単語を複数形に変更したものを返します
            • このメソッドの背後には強力なインフレクター (活用形生成) があり、不規則活用を含むさまざまな単語を複数形にすることができます
          • エラーメッセージにスタイルを与えるためのCSS id error_explanationも含まれている
        • Railsは、無効な内容の送信によって元のページに戻されると、CSSクラスfield_with_errorsを持ったdivタグでエラー箇所を自動的に囲んでくれます
          • このラベルを使うことで、リスト 7.22のようにエラーメッセージをSCSSで整形
        • Sassの@extend関数を使ってBootstrapのhas-errorというCSSクラスを適用
    • 失敗時のテスト
      • まずは、新規ユーザー登録用の統合テストを生成するところから始めていきます
        • rails generate integration_test users_signup
        • assert_no_difference 'User.count' do
          • assert_no_differenceメソッドのブロック内でpostを使い、メソッドの引数には'User.count'を与えています
          • assert_no_differenceのブロックを実行する前後で引数の値 (User.count) が変わらないことをテスト
          • assert_no_differenceを使う方が明瞭で、Rubyの慣習的にも正しい
        • post users_path, params: { user: { name: "", ...
      • 演習
        • assert_select 'div#error_explanation'
        • assert_select 'div.field_with_errors'
        • post '/signup', to: 'users#create'
        • <%= form_for(@user, url: signup_path) do |f| %>
        • assert_select 'form[action="/signup"]'
  • ユーザー登録成功
    • 登録フォームの完成
      • ユーザー登録に成功した場合はページを描画せずに別のページにリダイレクト (Redirect) する
        • 新しく作成されたユーザーのプロフィールページにリダイレクト
        • redirect_to @user
          • redirect_to user_url(@user)と同じ
    • flash
      • Webアプリケーションに常識的に備わっている機能を追加してみましょう。
        • 登録完了後に表示されるページにメッセージを表示し (この場合は新規ユーザーへのウェルカムメッセージ)、2度目以降にはそのページにメッセージを表示しないようにするというもの
      • Railsでこういった情報を表示するためには、flashという特殊な変数
        • flash[:success] = "Welcome to the Sample App!"
        • Welcome to the Sample App!
          になる
      • Bootstrap CSSは、このようなflashのクラス用に4つのスタイルを持っています (success、info、warning、danger)
      • app/views/layouts/application.html.erb
      • 演習
        • "#{:success}" → "success"
    • 実際のユーザー登録
    • 成功時のテスト
      • assert_difference
        • assert_no_differenceと同様に、このメソッドは第一引数に文字列 ('User.count') を取り、assert_differenceブロック内の処理を実行する直前と、実行した直後のUser.countの値を比較します。
        • 第二引数はオプションですが、ここには比較した結果の差異 (今回の場合は1) を渡します
      • follow_redirect!
        • POSTリクエストを送信した結果を見て、指定されたリダイレクト先に移動
      • 演習
        • assert_not flash.empty?
          • テキストに対するテストは壊れやすい
          • flashが空でないかをテストするだけの場合が多い
        • <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
  • プロのデプロイ
    • 本番環境でのSSL
      • Webサイト全体で適用できるため、第8章で実装するログイン機構をセキュアにしたり、9.1.で説明するセッションハイジャック (Session Hijacking) の脆弱性に対しても多くの利点を生み出します
      • SSLを有効化するのも簡単です。production.rbという本番環境の設定ファイルの1行を修正するだけで済みます
      • Herokuではデフォルトの設定でもSSLを使用できるのですが、SSLの使用をブラウザに強制するわけではありません
      • Railsではありがたいことに、本番環境用の設定ファイルであるproduction.rbのコードをたった1行変更するだけでSSLを強制し、httpsによる安全な通信を確立
      • config/environments/production.rb
        • config.force_ssl = true
      • Heroku上でサンプルアプリケーションを動かし、HerokuのSSL証明書に便乗
    • 本番環境用のWebサーバー
      • Herokuのデフォルトでは、Rubyだけで実装されたWEBrickというWebサーバー
      • WEBrickは本番環境として適切なWebサーバーではありません。よって、今回はWEBrickをPumaに置き換え
      • Pumaは多数のリクエストを捌くことに適したRuby/Rackアプリケーション用のサーバー
      • Heroku内のPumaドキュメント (英語) に従ってセットアップ
        • config/puma.rb
        • Procfileと呼ばれる、Heroku上でPumaのプロセスを走らせる設定ファイルを作成
    • 本番環境へのデプロイ
      • Rubyのバージョン番号
        • 経験的には、本書のようなチュートリアルの段階では明示的に指定しない方がスムーズに進むことが多い
        • Herokuを使ったアプリケーションを動かす場合はGemfileでRubyのバージョンを明示しておいた方が賢明
        • 開発環境と本番環境の互換性を最大限に高めることができる
  • 最後に
    • 本章のまとめ
      • debugメソッドを使うことで、役立つデバッグ情報を表示できる
      • Sassのmixin機能を使うと、CSSのルールをまとめたり他の場所で再利用できるようになる
      • Railsには標準で3つ環境が備わっており、それぞれ開発環境 (development)、テスト環境 (test)、本番環境 (production)と呼ぶ
      • 標準的なRESTfulなURLを通して、ユーザー情報をリソースとして扱えるようになった
      • Gravatarを使うと、ユーザーのプロフィール画像を簡単に表示できるようになる
      • form_forヘルパーは、Active Recordのオブジェクトに対応したフォームを生成する
      • ユーザー登録に失敗した場合はnewビューを再描画するようにした。その際、Active Recordが自動的に検知したエラーメッセージを表示できるようにした
      • flash変数を使うと、一時的なメッセージを表示できるようになる
      • ユーザー登録に成功すると、データベース上にユーザーが追加、プロフィールページにリダイレクト、ウェルカムメッセージの表示といった順で処理が進む
      • 統合テストを使うことで送信フォームの振る舞いを検証したり、バグの発生を検知したりできる
      • セキュアな通信と高いパフォーマンスを確保するために、本番環境ではSSLとPumaを導入した

Ch08 基本的なログイン機構

  • ログインの基本的な仕組みとは、ブラウザがログインしている状態を保持し、ユーザーによってブラウザが閉じられたら状態を破棄するといった仕組み (認証システム (Authentification System))
  • このような制限や制御の仕組みを認可モデル (Authorization Model) と呼び、例えば本章で実装するログイン済みかどうかでヘッダー部分を切り替える、といった仕組みもこれにあたります
  • セッション
    • HTTPはステートレス (Stateless) なプロトコル
    • ユーザーログインの必要なWebアプリケーションでは、セッション (Session) と呼ばれる半永続的な接続をコンピュータ間 (ユーザーのパソコンのWebブラウザRailsサーバーなど) に別途設定
    • Railsでセッションを実装する方法として最も一般的なのは、cookiesを使う方法
      • cookiesとは、ユーザーのブラウザに保存される小さなテキストデータ
      • アプリケーションはcookies内のデータを使って、例えばログイン中のユーザーが所有する情報をデータベースから取り出すことができます
      • 本節および8.2では、sessionというRailsのメソッドを使って一時セッションを作成
    • セッションをRESTfulなリソースとしてモデリングできると、他のRESTfulリソースと統一的に理解できて便利
      • ログインページではnewで新しいセッションを出力し、そのページでログインするとcreateでセッションを実際に作成して保存し、ログアウトするとdestroyでセッションを破棄する
      • Usersリソースと異なるのは、UsersリソースではバックエンドでUserモデルを介してデータベース上の永続的データにアクセスするのに対し、Sessionリソースでは代わりにcookiesを保存場所として使う点
    • ログインの仕組みの大半は、cookiesを使った認証メカニズムによって構築
    • 本節と次の節では、セッション機能を作成する準備として、Sessionコントローラ、ログイン用のフォーム、両者に関連するコントローラのアクションを作成
    • Sessionsコントローラ
      • ログインとログアウトの要素を、Sessionsコントローラの特定のRESTアクションにそれぞれ対応付ける
      • ログインのフォームは、この節で扱うnewアクションで処理
      • rails generate controller Sessions new
      • Sessionリソースではフルセットはいらないので、「名前付きルーティング」だけを使います
      • テストを更新
      • rails routesで確認
      • 演習
    • ログインフォーム
      • 7.3.3ではエラーメッセージの表示に専用のパーシャルを使いましたが、そのパーシャルではActive Recordによって自動生成されるメッセージを使っていた
      • 今回は、フラッシュメッセージでエラーを表示
      • app/views/sessions/new.html.erb
      • セッションにはSessionモデルというものがなく、そのため@userのようなインスタンス変数に相当するものもない
        • 新しいセッションフォームを作成するときには、form_forヘルパーに追加の情報を独自に渡さなければなりません
        • form_for(:session, url: login_path)
    • ユーザーの検索と認証
      • ログインでセッションを作成する場合に最初に行うのは、入力が無効な場合の処理
      • 最初に最小限のcreateアクションをSessionsコントローラで定義し、空のnewアクションとdestroyアクションも作成
      • createアクションの中では、ユーザーの認証に必要なあらゆる情報をparamsハッシュから簡単に取り出せる
      • app/controllers/sessions_controller.rb
        • user = User.find_by(email: params[:session][:email].downcase)
        • if user && user.authenticate(params[:session][:password])
    • フラッシュメッセージを表示する
    • フラッシュのテスト
      • フラッシュメッセージが消えない問題は、このアプリケーションの小さなバグです。コラム 3.3で解説したテストのガイドラインに従えば、これはまさに「エラーをキャッチするテストを先に書いて、そのエラーが解決するようにコードを書く」に該当する状況
      • rails generate integration_test users_login
      • 手順をテストコードで再現
      • rails test test/integration/users_login_test.rb
      • flashflash.nowに置き換え
        • レンダリングが終わっているページで特別にフラッシュメッセージを表示することができます
        • flash.now[:danger] = 'Invalid email/password combination'
  • ログイン
    • ログイン中の状態での有効な値の送信をフォームで正しく扱えるようにします
    • cookiesを使った一時セッションでユーザーをログインできるようにします
    • app/controllers/application_controller.rb
      • include SessionsHelper
    • log_inメソッド
      • session[:user_id] = user.id
        • ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
        • cookiesメソッド (9.1) とは対照的に、sessionメソッドで作成された一時cookiesは、ブラウザを閉じた瞬間に有効期限が終了
      • app/helpers/sessions_helper.rb
        • def log_in(user)
          • session[:user_id] = user.id
      • sessionメソッドで作成した一時cookiesは自動的に暗号化され、リスト 8.14のコードは保護されます
        • 攻撃者がたとえこの情報をcookiesから盗み出すことができたとしても、それを使って本物のユーザーとしてログインすることはできない
        • ただし今述べたことは、sessionメソッドで作成した「一時セッション」にしか該当しません
          • cookiesメソッドで作成した「永続的セッション」ではそこまで断言はできません
          • 永続的なcookiesには、セッションハイジャックという攻撃を受ける可能性が常につきまといます
      • log_inというヘルパーメソッドを定義できたので、やっと、ユーザーログインを行ってセッションのcreateアクションを完了し、ユーザーのプロフィールページにリダイレクトする準備ができました
        • app/controllers/sessions_controller.rb
          • log_in user
          • redirect_to user
    • 現在のユーザー
      • if session[:user_id]
        • セッションにユーザーIDが存在しない場合、このコードは単に終了して自動的にnilを返します
      • @current_user ||= User.find_by(id: session[:user_id])
        • Rubyの慣習に従って、User.find_byの実行結果をインスタンス変数に保存する工夫
          • 1リクエスト内におけるデータベースへの問い合わせは最初の1回だけになり、以後の呼び出しではインスタンス変数の結果を再利用
          • こういった工夫がWebサービスを高速化させる重要なテクニックの1つ
        • コラム 8.1. 「||=」とは何か?
          • 「@foo = @foo || "bar"」は「@foo ||= "bar"」と等価
      • app/helpers/sessions_helper.rb
        • def current_user
          • if session[:user_id]
            • @current_user ||= User.find_by(id: session[:user_id])
    • レイアウトリンクを変更する
      • app/helpers/sessions_helper.rb
        • def logged_in?
          • !current_user.nil?
      • app/views/layouts/_header.html.erb
        • <% if logged_in? %>
        • <%= link_to "Profile", current_user %>
          • current_userを使う方が、Railsによってuser_path(current_user)に変換され、プロフィールへのリンクが自動的に生成できるので便利
        • <%= link_to "Log out", logout_path, method: :delete %>
        • <%= link_to "Log in", login_path %>
      • application.jsにBootstrapのJavaScriptライブラリを追加する
        • app/assets/javascripts/application.js
          • //= require jquery
          • //= require bootstrap
    • レイアウトの変更をテストする
      • テスト用データをfixture (フィクスチャ) で作成
      • Railsのsecure_passwordのソースコードを調べてみると、次の部分でパスワードが生成
        • BCrypt::Password.create(string, cost: cost)
          • costはコストパラメータ
          • コストパラメータの値を高くすれば、ハッシュからオリジナルのパスワードを計算で推測することが困難
            • 本番環境ではセキュリティ上重要
          • cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
      • fixture向けのdigestメソッドを追加
        • app/models/user.rb
      • ユーザーログインのテストで使うfixture
        • test/fixtures/users.yml
          • password_digest: <%= User.digest('password') %>
        • テスト用のfixtureでは全員同じパスワード「password」を使う
      • test/integration/users_login_test.rb
        • def setup
          • @user = users(:michael)
        • test "login with valid information" do
          • assert_redirected_to @user
          • follow_redirect!
          • assert_select "a[href=?]", login_path, count: 0
    • ユーザー登録時にログイン
      • ユーザー登録中にログインするには、Usersコントローラのcreateアクションにlog_inを追加するだけで済みます
        • app/controllers/users_controller.rb
          • if @user.save
            • log_in @user
      • テスト中のログインステータスを論理値で返すメソッド
        • test/test_helper.rb
          • def is_logged_in?
      • test/integration/users_signup_test.rb
        • assert is_logged_in?
  • ログアウト
    • ログインの場合 (リスト 8.15とリスト 8.25) と異なり、ログアウト処理は1か所で行える
      • destroyアクションに直接ログアウト処理を書く
    • app/helpers/sessions_helper.rb
      • def log_out
        • session.delete(:user_id)
        • @current_user = nil
    • app/controllers/sessions_controller.rb
      • log_out
      • redirect_to root_url
    • test/integration/users_login_test.rb
      • test "login with valid information followed by logout" do
  • 最後に
    • 本章では、サンプルアプリケーションの基本的なログイン機構 (認証システム) を実装
    • 本章のまとめ
      • Railsのsessionメソッドを使うと、あるページから別のページに移動するときの状態を保持できる。一時的な状態の保存にはcookiesも使える
      • ログインフォームでは、ユーザーがログインするための新しいセッションが作成できる
      • flash.nowメソッドを使うと、描画済みのページにもフラッシュメッセージを表示できる
      • テスト駆動開発は、回帰バグを防ぐときに便利
      • sessionメソッドを使うと、ユーザーIDなどをブラウザに一時的に保存できる
      • ログインの状態に応じて、ページ内で表示するリンクを切り替えることができる
      • 統合テストでは、ルーティング、データベースの更新、レイアウトの変更が正しく行われているかを確認できる

Ch09 発展的なログイン機構

  • ユーザーのログイン情報を記憶しておき、ブラウザを再起動した後でもすぐにログインできる機能 (remember me) を備えていることも一般的
    • 永続クッキー (permanent cookies) を使ってこの機能を実現
  • Remember me 機能
    • 記憶トークンと暗号化
      • セッションの永続化の第一歩として記憶トークン (remember token) を生成
      • cookiesメソッドによる永続的cookiesの作成や、安全性の高い記憶ダイジェスト (remember digest) によるトークン認証にこの記憶トークンを活用
      • パスワードとトークンとの一般的な違いは、パスワードはユーザーが作成・管理する情報であるのに対し、トークンはコンピューターが作成・管理する情報である点
      • cookiesを盗み出す有名な方法
        • (1) 管理の甘いネットワークを通過するネットワークパケットからパケットスニッファという特殊なソフトウェアで直接cookieを取り出す
          • Secure Sockets Layer (SSL) をサイト全体に適用して、ネットワークデータを暗号化で保護し、パケットスニッファから読み取られないようにしています
        • (2) データベースから記憶トークンを取り出す
        • (3) クロスサイトスクリプティング (XSS)
          • Railsによって自動的に対策
            • 具体的には、ビューのテンプレートで入力した内容をすべて自動的にエスケープ
        • (4) ユーザーがログインしているパソコンやスマホを直接操作してアクセスを奪い取る
          • 二次被害を最小限に留めることは可能
            • ユーザーが (別端末などで) ログアウトしたときにトークンを必ず変更するようにし、セキュリティ上重要になる可能性のある情報を表示するときはデジタル署名 (digital signature) を行う
      • rails generate migration add_remember_digest_to_users remember_digest:string
      • 記憶トークンとして何を使うかを決める
        • 基本的には長くてランダムな文字列であればどんなものでも構いません
        • Ruby標準ライブラリのSecureRandomモジュールにあるurlsafe_base64メソッドなら、この用途にぴったり合いそう
          • A–Z、a–z、0–9、"-"、"_"のいずれかの文字 (64種類) からなる長さ22のランダムな文字列を返します
          • トークンが衝突することはまずありません
          • base64はURLを安全にエスケープするためにも用いられる
      • ユーザーを記憶するには、記憶トークンを作成して、そのトークンをダイジェストに変換したものをデータベースに保存
      • トークン生成用メソッドを追加する
        • app/models/user.rb
          • def User.new_token
      • user.rememberメソッドを作成
        • 記憶トークンをユーザーと関連付け、トークンに対応する記憶ダイジェストをデータベースに保存
        • app/models/user.rb
          • attr_accessor :remember_token
          • def remember
            • self.remember_token = User.new_token
            • update_attribute(:remember_digest, User.digest(remember_token))
      • 演習
        • selfは、通常の文脈ではUser「モデル」、つまりユーザーオブジェクトのインスタンスを指しますが、リスト 9.4やリスト 9.5の文脈では、selfはUser「クラス」を指す
          • def self.digest(string)
          • class << self
    • ログイン状態の保持
      • user.rememberメソッドが動作するようになったので、ユーザーの暗号化済みIDと記憶トークンをブラウザの永続cookiesに保存して、永続セッションを作成する準備ができました
      • 実際に行うにはcookiesメソッドを使います
        • このメソッドは、sessionのときと同様にハッシュとして扱えます
        • 個別のcookiesは、1つのvalue (値) と、オプションのexpires (有効期限) からできています
        • cookies[:remember_token] = { value: remember_token, expires: 20.years.from_now.utc }
          • 20年で期限切れになるcookies設定はよく使われていて、今ではRailsにもpermanentという専用メソッドが追加されたほど
          • cookies.permanent[:remember_token] = remember_token
          • コラム 9.1. cookiesは今から20年後に切れる (20.years.from_now)
            • timeヘルパーはRailsによって、数値関連の基底クラスであるFixnumクラスに追加されます
        • ユーザーIDをcookiesに保存
          • 署名付きcookie
            • cookieをブラウザに保存する前に安全に暗号化
          • cookies.signed[:user_id] = user.id
        • cookies.permanent.signed[:user_id] = user.id
        • User.find_by(id: cookies.signed[:user_id])
          • cookies.signed[:user_id]では自動的にユーザーIDのcookiesの暗号が解除され、元に戻ります
      • 渡されたトークンがユーザーの記憶ダイジェストと一致することを確認
        • BCrypt gemでは,比較に使っている==演算子が再定義されている
          • BCrypt::Password.new(remember_digest).is_password?(remember_token)を使っている
        • authenticated?をUserモデルに追加する
          • app/models/user.rb
            • BCrypt::Password.new(remember_digest).is_password?(remember_token)
      • ログインしてユーザーを保持する
        • app/controllers/sessions_controller.rb
          • remember user
      • ユーザーを記憶する
        • app/helpers/sessions_helper.rb
          • def remember(user)
      • 永続的セッションのcurrent_userを更新する
        • def current_user
    • ユーザーを忘れる
      • forgetメソッドをUserモデルに追加
        • update_attribute(:remember_digest, nil)
      • 永続セッションからログアウト
        • app/helpers/sessions_helper.rb
        • forgetヘルパーメソッドではuser.forgetを呼んでからuser_idとremember_tokenのcookiesを削除
    • 2つの目立たないバグ
      • ユーザーがログイン中の場合にのみログアウトさせる必要
      • ユーザーが複数のブラウザ (FirefoxChromeなど) でログインしていたとき
      • テスト駆動開発は、この種の地味なバグ修正にはうってつけ
        • 2番目のウィンドウでログアウトをクリックするユーザーをシミュレート
          • log_out if logged_in?
        • 記憶ダイジェストを持たないユーザーを用意しauthenticated?を呼び出し
          • return false if remember_digest.nil?
  • [Remember me] チェックボックス
    • [remember me] チェックボックスをログインフォームに追加
      • app/views/sessions/new.html.erb
        • <%= f.label :remember_me, class: "checkbox inline" do %>
          • <%= f.check_box :remember_me %>
      • 2つのCSSクラスcheckboxとinline
        • Bootstrapではこれらをチェックボックスとテキスト「Remember me on this computer」として同じ行に配置
    • [remember me] チェックボックスCSS
    • [remember me] チェックボックスの送信結果を処理
      • app/controllers/sessions_controller.rb
        • params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      • コラム 9.2. 10種類の人々
        • 「この世には10種類の人間がいる。2進法を理解できる奴と、2進法を理解できない奴だ」
        • 三項演算子 (ternary operator)
          • 論理値? ? 何かをする : 別のことをする
  • [Remember me] のテスト
    • [Remember me] ボックスをテストする
      • log_in_asヘルパーを追加
        • ActionDispatch::IntegrationTestクラスにも定義する
          • 私たち開発者は単体テストか統合テストかを意識せずに、ログイン済みの状態をテストしたいときはlog_in_asメソッドをただ呼び出せば良い、ということになります
      • テスト内ではcookiesメソッドにシンボルを使えない
      • [remember me] チェックボックスのテスト
        • test/integration/users_login_test.rb
      • 演習
        • コントローラで定義したインスタンス変数にテストの内部からアクセスするには、テスト内部でassignsメソッドを使います
        • app/controllers/sessions_controller.rb
          • @userにする
        • test/integration/users_login_test.rb
          • assert_equal cookies['remember_token'], assigns(:user).remember_token
    • [Remember me] をテストする
      • テストを忘れている疑いのあるコードブロック内にわざと例外発生を仕込む
        • raise
      • test/helpers/sessions_helper_test.rb
        • assert_equal @user, current_user
        • assert is_logged_in?
        • @user.update_attribute(:remember_digest, User.digest(User.new_token))
        • assert_nil current_user
  • 最後に
    • 前々章から第9章までの間に、ユーザー登録からログイン機構に至るまで、広大な知識について幅広く学んできました
    • 基本的な認証機構に必要な残りの作業は、ログイン状態やログイン済みのユーザーIDに基いて、ページへのアクセス権限を制限する実装 (認可モデル) だけ
    • Herokuにデプロイしても、Heroku上でマイグレーションを実行するまでの間は一時的にアクセスできない状態 (エラーページ) になる
      • トラフィックの多い本番サイトでは、このような変更を行う前にメンテナンスモードをオンにしておくことが一般的
      • heroku maintenance:on(またはoff)
    • 本章のまとめ
      • Railsでは、あるページから別のページに移動するときに状態を保持することができる。ページの状態を長期間保持したいときは、cookiesメソッドを使って永続的なセッションにする
      • 記憶トークンと記憶ダイジェストをユーザーごとに関連付けて、永続的セッションが実現できる
      • cookiesメソッドを使うと、ユーザーのブラウザにcookiesなどを保存できる
      • ログイン状態は、セッションもしくはクッキーの状態に基づいて決定される
      • セッションとクッキーをそれぞれ削除すると、ユーザーのログアウトが実現できる
      • 三項演算子を使用すると、単純なif-then文をコンパクトに記述できる

Ch10 ユーザーの更新・表示・削除

  • Usersリソース用のRESTアクション (表 7.1) のうち、これまで未実装だったedit、update、index、destroyアクションを加え、RESTアクションを完成させます
  • 認可モデル (Authorization Model) について
  • サンプルデータとページネーション (pagination) を導入
  • ユーザーを更新する
    • ユーザー情報を編集するパターンは、新規ユーザーの作成と極めて似通っています
    • newアクションと同じようにして、ユーザーを編集するためのeditアクションを作成
    • POSTリクエストに応答するcreateの代わりに、PATCHリクエストに応答するupdateアクションを作成
    • 最大の違いは、ユーザー登録は誰でも実行できますが、ユーザー情報を更新できるのはそのユーザー自身に限られるということ
      • beforeフィルター (before filter) を使ってこのアクセス制御を実現
    • 編集フォーム
      • ユーザーのeditアクション
        • app/controllers/users_controller.rb
          • @user = User.find(params[:id])
      • ユーザーのeditビュー
        • app/views/users/edit.html.erb
        • target="_blank"が使われていますが、これを使うとリンク先を新しいタブ (またはウィンドウ) で開くようになるので、別のWebサイトへリンクするときなどに便利
          • ただしtarget="_blank"にはセキュリティ上の小さな問題
        • @userインスタンス変数を使うと、編集ページがうまく描画される
        • Railsによって名前やメールアドレスのフィールドに値が自動的に入力
          • これらの値は、@user変数の属性情報から引き出されています。
        • WebブラウザはそのままではPATCHリクエスト (表 7.1でRESTの慣習として要求されている) を送信できないので、RailsはPOSTリクエストと、隠しinputフィールドを利用してPATCHリクエストを「偽造」
      • Railsはどうやって新規ユーザー用のPOSTリクエストとユーザー編集用のPATCHリクエストを区別するのでしょうか
        • Railsは、ユーザーが新規なのか、それともデータベースに存在する既存のユーザーであるかを、Active Recordのnew_record?論理値メソッドを使って区別できる
        • form_for(@user)を使ってフォームを構成すると、@user.new_record?がtrueのときにはPOSTを、falseのときにはPATCHを使います
      • レイアウトの “Settings” リンクを更新する
        • app/views/layouts/_header.html.erb
          • <\li><%= link_to "Settings", edit_user_path(current_user) %><\/li>
      • 演習
        • target="_blank"で新しいページを開くときには、セキュリティ上の小さな問題があります。それは、リンク先のサイトがHTMLドキュメントのwindowオブジェクトを扱えてしまう、という点
          • 具体的には、フィッシング (Phising) サイトのような、悪意のあるコンテンツを導入させられてしまう可能性があります
          • 対処方法は、リンク用のaタグのrel (relationship) 属性に、"noopener"と設定するだけ
        • newとeditフォーム用のパーシャル
          • <% provide(:button_text, "Save changes") %>
          • <%= render 'form' %>
            • view以下のパスを書くが,同階層ならファイル名だけでよいようだ
            • partialを示す_は不要
    • 編集の失敗
      • ユーザーのupdateアクションの初期実装
        • app/controllers/users_controller.rb
          • createと同様
          • update_attributesへの呼び出しでuser_paramsを使っている
    • 編集失敗時のテスト
      • rails generate integration_test users_edit
      • 最初は編集失敗時の簡単なテストを追加
        • まず編集ページにアクセスし、editビューが描画されるかどうかをチェック
        • その後、無効な情報を送信してみて、editビューが再描画されるかどうかをチェック
        • PATCHリクエストを送るためにpatchメソッドを使っていることに注目
          • これはgetやpost、deleteメソッドと同じように、HTTPリクエストを送信するためのメソッド
      • 演習
        • assert_select "div.alert", text: "The form contains 4 errors."
    • TDDで編集を成功させる
      • より快適にテストをするためには、アプリケーション用のコードを「実装する前に」統合テストを書いた方が便利
        • そういったテストのことは「受け入れテスト (Acceptance Tests)」
        • ある機能の実装が完了し、受け入れ可能な状態になったかどうかを決めるテスト
      • ユーザー名やメールアドレスを編集するときに毎回パスワードを入力するのは不便なので、(パスワードを変更する必要が無いときは) パスワードを入力せずに更新できると便利
      • @user.reloadを使って、データベースから最新のユーザー情報を読み込み直して、正しく更新されたかどうかを確認
      • test/integration/users_edit_test.rb
      • ユーザーのupdateアクション
        • flash[:success] = "Profile updated"
        • redirect_to @user
      • パスワードが空のままでも更新できるようにする
        • app/models/user.rb
          • validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
        • has_secure_passwordでは (追加したバリデーションとは別に) オブジェクト生成時に存在性を検証するようになっている
          • 空のパスワード (nil) が新規ユーザー登録時に有効になることはありません
  • 認可
    • ウェブアプリケーションの文脈では、認証 (authentication) はサイトのユーザーを識別すること
    • 認可 (authorization) はそのユーザーが実行可能な操作を管理すること
    • この節では、ユーザーにログインを要求し、かつ自分以外のユーザー情報を変更できないように制御
      • こういったセキュリティ上の制御機構をセキュリティモデルと呼びます
    • ユーザーにログインを要求する
      • 転送させる仕組みを実装したいときは、Usersコントローラの中でbeforeフィルターを使います
        • beforeフィルターは、before_actionメソッドを使って何らかの処理が実行される直前に特定のメソッドを実行する仕組み
      • beforeフィルターにlogged_in_userを追加
        • app/controllers/users_controller.rb
          • before_action :logged_in_user, only: [:edit, :update]
            • :onlyオプション (ハッシュ) を渡すことで、:editと:updateアクションだけにこのフィルタが適用されるように制限
          • unless logged_in?
            • flash[:danger] = "Please log in."
            • redirect_to login_url
      • テストユーザーでログインする
        • test/integration/users_edit_test.rb
          • log_in_as(@user)
      • セキュリティモデルを確認するためにbeforeフィルターをコメントアウト
      • editとupdateアクションの保護に対するテストする
        • test/controllers/users_controller_test.rb
          • def setup (← 何故か追加していなくてテスト通らなかった)
            • @user = users(:michael)
          • editアクションとupdateアクションをそれぞれ実行させてみて、flashにメッセージが代入されたかどうか、ログイン画面にリダイレクトされたかどうかを確認
          • 適切なリクエストはそれぞれGETとPATCH
    • 正しいユーザーを要求する
      • ユーザーが自分の情報だけを編集できるようにする必要
      • セキュリティモデルが正しく実装されている確信を持つために、テスト駆動開発で進めていきます
      • fixtureファイルに2人目のユーザーを追加
        • test/fixtures/users.yml
      • log_in_asメソッドを使って、editアクションとupdateアクションをテスト
        • 間違ったユーザーが編集しようとしたときのテスト
          • 既にログイン済みのユーザーを対象としているため、ログインページではなくルートURLにリダイレクト
      • beforeフィルターを使って編集/更新ページを保護
        • correct_userというメソッドを作成し、beforeフィルターからこのメソッドを呼び出す
          • redirect_to(root_url) unless current_user?(@user)
      • current_user?メソッド
        • app/helpers/sessions_helper.rb
          • def current_user?(user)
            • user == current_user
    • フレンドリーフォワーディング
      • 保護されたページにアクセスしようとすると、問答無用で自分のプロフィールページに移動させられてしまいます
      • リダイレクト先は、ユーザーが開こうとしていたページにしてあげるのが親切
      • 実際のテストはまず編集ページにアクセスし、ログインした後に、(デフォルトのプロフィールページではなく) 編集ページにリダイレクトされているかどうかをチェックする
        • get edit_user_path(@user)
        • log_in_as(@user)
        • assert_redirected_to edit_user_url(@user)
      • フレンドリーフォワーディングの実装
        • app/helpers/sessions_helper.rb
          • def redirect_back_or(default)
            • redirect_to(session[:forwarding_url] || default)
            • session.delete(:forwarding_url)
              • これをやっておかないと、次回ログインしたときに保護されたページに転送されてしまい、ブラウザを閉じるまでこれが繰り返されてしまいます
              • 転送用のURLを削除する動作はredirect文の後に置かれていても実行される
                • 明示的にreturn文やメソッド内の最終行が呼び出されない限り、リダイレクトは発生しません
          • def store_location
            • session[:forwarding_url] = request.original_url if request.get?
        • app/controllers/users_controller.rb
        • app/controllers/sessions_controller.rb
        • requestオブジェクトも使っています (request.original_urlでリクエスト先が取得できます)
        • POSTや PATCH、DELETEリクエストを期待しているURLに対して、(リダイレクトを通して) GETリクエストが送られてしまい、場合によってはエラーが発生します
          • if request.get?という条件文を使ってこのケースに対応
        • ログインユーザー用beforeフィルターにstore_locationを追加
        • デフォルトのURLは、Sessionコントローラのcreateアクションに追加し、サインイン成功後にリダイレクト
          • フレンドリーフォワーディングを備えたcreateアクション
            • 前にインスタンス変数に変更しているので,redirect_back_or @userにする必要がある
        • 演習
          • test/integration/users_edit_test.rb
            • assert_nil session[:forwarding_url]
  • すべてのユーザーを表示する
    • ユーザーの一覧ページ
      • indexアクションのリダイレクトをテスト
        • test "should redirect index when not logged in" do
      • beforeフィルターのlogged_in_userにindexアクションを追加して、このアクションを保護
      • ユーザーのindexアクション
        • @users = User.all
      • ユーザーのindexビュー
        • ユーザーを列挙してユーザーごとにliタグで囲むビューを作成
          • eachメソッドを使って作成
      • gravatar_forヘルパーにオプション引数を追加する
      • ユーザーのindexページ用のCSS
      • ユーザー一覧ページへのリンクを更新
        • app/views/layouts/_header.html.erb
      • 演習
        • test/integration/site_layout_test.rb
          • userをセットアップして,セットアップしたユーザでログイン
          • routeをgetして各linkをselectする
    • サンプルのユーザー
      • GemfileにFaker gemを追加
      • サンプルユーザーを生成するRubyスクリプト (Railsタスクとも呼びます) を追加
        • db/seeds.rb
          • Example Userという名前とメールアドレスを持つ1人のユーザと、それらしい名前とメールアドレスを持つ99人のユーザーを作成
          • create!は基本的にcreateメソッドと同じものですが、ユーザーが無効な場合にfalseを返すのではなく例外を発生させる (6.1.4) 点が異なります
    • ページネーション
      • Railsには豊富なページネーションメソッドがあります。今回はその中で最もシンプルかつ堅牢なwill_paginateメソッドを使ってみましょう
      • Gemfileにwill_paginate gem とbootstrap-will_paginate gemを両方含め、Bootstrapのページネーションスタイルを使ってwill_paginateを構成する
      • indexページでpaginationを使う
        • <%= will_paginate %>
        • paginateでは、キーが:pageで値がページ番号のハッシュを引数に取ります
        • User.paginateは、:pageパラメーターに基いて、データベースからひとかたまりのデータ (デフォルトでは30) を取り出し
        • pageがnilの場合、 paginateは単に最初のページを返します
        • indexアクションでUsersをページネート
          • @users = User.paginate(page: params[:page])
          • :pageパラメーターにはparams[:page]が使われていますが、これはwill_paginateによって自動的に生成
    • ユーザー一覧のテスト
      • 今回のテストでは、ログイン、indexページにアクセス、最初のページにユーザーがいることを確認、ページネーションのリンクがあることを確認、といった順でテスト
      • fixtureでは埋め込みRubyをサポート
      • fixtureにさらに30人のユーザーを追加する
        • <% 30.times do |n| %>
        • user_<%= n %>:
          • name: <%= "User #{n}" %>
      • rails generate integration_test users_index
      • paginationクラスを持ったdivタグをチェックして、最初のページにユーザーがいることを確認
        • User.paginate(page: 1).each do |user|
          • assert_select 'a[href=?]', user_path(user), text: user.name
      • 演習
        • assert_select 'div.pagination', count: 2
    • パーシャルのリファクタリング
      • ユーザーのliをrender呼び出しに置き換え
        • <%= render user %>
          • renderをパーシャル (ファイル名の文字列) に対してではなく、Userクラスのuser変数に対して実行
          • Railsは自動的に_user.html.erbという名前のパーシャルを探しにいく
      • app/views/users/_user.html.erb
      • renderを@users変数に対して直接実行
        • <%= render @users %>
          • Railsは@users をUserオブジェクトのリストであると推測
          • ユーザーのコレクションを与えて呼び出すと、Railsは自動的にユーザーのコレクションを列挙し、それぞれのユーザーを_user.html.erbパーシャルで出力
  • ユーザーを削除する
    • 管理ユーザー
      • 論理値をとるadmin属性をUserモデルに追加
        • rails generate migration add_admin_to_users admin:boolean
        • default: falseという引数をadd_columnに追加
      • サンプルデータ生成タスクに管理者を1人追加
        • db/seeds.rb
      • Strong Parameters、再び
        • 任意のWebリクエストの初期化ハッシュをオブジェクトに渡せるとなると、攻撃者は次のようなPATCHリクエストを送信してくるかもしれません
          • patch /users/17?admin=1
        • Strong Parametersを使って対策
          • paramsハッシュに対してrequireとpermitを呼び出し
            • def user_params
              • params.require(:user).permit(:name, :email, :password, :password_confirmation)
      • 演習
        • admin属性の変更が禁止されていることをテスト
        • test/controllers/users_controller_test.rb
          • patch user_path(@other_user), params: { user: { password: @other_user.password, password_confirmation: @other_user.password,admin: true } }
          • assert_not @other_user.reload.admin?
    • destroyアクション
      • Usersリソースの最後の仕上げとして、destroyアクションへのリンクを追加
      • まず、ユーザーindexページの各ユーザーに削除用のリンクを追加
      • 続いて管理ユーザーへのアクセスを制限
      • app/views/users/_user.html.erb
        • <% if current_user.admin? && !current_user?(user) %>
          • | <%= link_to "delete", user, method: :delete, data: { confirm: "You sure?" } %>
        • 必要なDELETEリクエストを発行するリンクの生成は、method: :deleteによって行われている
      • ブラウザはネイティブではDELETEリクエストを送信できないため、RailsではJavaScriptを使って偽造
        • JavaScriptをサポートしないブラウザをサポートする必要がある場合は、フォームとPOSTリクエストを使ってDELETEリクエストを偽造することもできます。こちらはJavaScriptがなくても動作
      • destroyアクション (表 7.1) を追加
        • 該当するユーザーを見つけてActive Recordのdestroyメソッドを使って削除し、最後にユーザーindexに移動
          • User.find(params[:id]).destroy
          • flash[:success] = "User deleted"
          • redirect_to users_url
        • :destroyアクションもlogged_in_userフィルターに追加
      • サイトを正しく防衛するには、destroyアクションにもアクセス制御を行う必要
        • beforeフィルターを使ってdestroyアクションへのアクセスを制御
          • before_action :admin_user, only: :destroy
          • redirect_to(root_url) unless current_user.admin?
    • ユーザー削除のテスト
      • fixture内の最初のユーザーを管理者にする
      • Usersコントローラをテストするために、アクション単位でアクセス制御をテスト
        • 2つのケースをチェック
          • ログインしていないユーザーであれば、ログイン画面にリダイレクト
          • ログイン済みではあっても管理者でなければ、ホーム画面にリダイレクト
        • log_in_as(@other_user)
        • assert_no_difference 'User.count' do
          • delete user_path(@user)
        • assert_redirected_to login_url
        • 管理者ではないユーザーの振る舞いについて検証していますが、管理者ユーザーの振る舞いと一緒に確認できるとよさそう
      • 削除リンクとユーザー削除に対する統合テスト
        • test/integration/users_index_test.rb
          • test "index as admin including pagination and delete links" do
            • 各ユーザーの削除リンクをテストするときに、ユーザーが管理者であればスキップしている
            • first_page_of_users = User.paginate(page: 1)
            • first_page_of_users.each do |user|
              • assert_select 'a[href=?]', user_path(user), text: user.name
                • unless user == @admin
                  • assert_select 'a[href=?]', user_path(user), text: 'delete'
            • assert_difference 'User.count', -1 do
              • delete user_path(@non_admin)
          • test "index as non-admin" do
            • assert_select 'a', text: 'delete', count: 0
  • 最後に
    • 今は登録もログインもログアウトもできます
    • プロフィールの表示も、設定の編集も、すべてのユーザーの一覧画面もあります
    • 一部のユーザーは他のユーザーを削除することすらできるようになりました
    • この時点で、サンプルアプリケーションはWebサイトとしての十分な基盤 (ユーザーを認証したり認可したり) が整った
    • アプリケーションを本番展開したり、サンプルデータを本番データとして作成することもできます (本番データベースをリセットするにはpg:resetタスクを使います)
      • git push heroku
      • heroku pg:reset DATABASE
      • heroku run rails db:migrate
      • heroku run rails db:seed
      • heroku restart
    • 本章のまとめ
      • ユーザーは、編集フォームからPATCHリクエストをupdateアクションに対して送信し、情報を更新する
      • Strong Parametersを使うことで、安全にWeb上から更新させることができる
      • beforeフィルターを使うと、特定のアクションが実行される直前にメソッドを呼び出すことができる
      • beforeフィルターを使って、認可 (アクセス制御) を実現した
      • 認可に対するテストでは、特定のHTTPリクエストを直接送信する低級なテストと、ブラウザの操作をシミュレーションする高級なテスト (統合テスト) の2つを利用した
      • フレンドリーフォワーディングとは、ログイン成功時に元々行きたかったページに転送させる機能である
      • ユーザー一覧ページでは、すべてのユーザーをページ毎に分割して表示する
      • rails db:seedコマンドは、db/seeds.rbにあるサンプルデータをデータベースに流し込む
      • render @usersを実行すると、自動的に_user.html.erbパーシャルを参照し、各ユーザーをコレクションとして表示する
      • boolean型のadmin属性をUserモデルに追加すると、admin?という論理オブジェクトを返すメソッドが自動的に追加される
      • 管理者が削除リンクをクリックすると、DELETEリクエストがdestroyアクションに向けて送信され、該当するユーザーが削除される
      • fixtureファイル内で埋め込みRubyを使うと、多量のテストユーザーを作成することができる

Ch11 アカウントの有効化

  • アカウント有効化やパスワード再設定の仕組みと、以前に実装したパスワードや記憶トークンの仕組みにはよく似た点が多い
    • 多くのアイデアを使い回すことができます (具体的にはUser.digestやUser.new_token、改造版のuser.authenticated?メソッドなど)
  • AccountActivationsリソース
    • セッション機能 (8.1) を使って、アカウントの有効化という作業を「リソース」としてモデル化する
    • AccountActivationsコントローラ
      • rails generate controller AccountActivations
      • ユーザーからのGETリクエストを受けるために、(本来であればupdateのところを) editアクションに変更
      • アカウント有効化に使うリソース (editアクション) を追加
        • resources :account_activations, only: [:edit]
      • 演習
        • 名前付きルートでは、pathではなくurl
          • メール(外部)からアクセスしてもらうのには完全なURLが必要
    • AccountActivationのデータモデル
      • rails generate migration add_activation_to_users activation_digest:string activated:boolean activated_at:datetime
      • add_column :users, :activated, :boolean, default: false
      • Activationトークンのコールバック
        • before_create :create_activation_digest
          • メソッド参照と呼ばれるもので、こうするとRailsはcreate_activation_digestというメソッドを探し、ユーザーを作成する前に実行
      • Userモデルにアカウント有効化のコードを追加
        • メールアドレスを小文字にするメソッドも (リスト 6.32)、メソッド参照に切り替え
      • サンプルユーザーの生成とテスト
        • サンプルデータとfixtureも更新し、テスト時のサンプルとユーザーを事前に有効化
        • db/seeds.rb
        • test/fixtures/users.yml
  • アカウント有効化のメール送信
    • Action Mailerライブラリを使ってUserのメイラーを追加
    • 送信メールのテンプレート
      • rails generate mailer UserMailer account_activation password_reset
        • メイラーは、モデルやコントローラと同様にrails generateで生成
        • 生成したメイラーごとに、ビューのテンプレートが2つずつ生成されます。1つはテキストメール用のテンプレート、1つはHTMLメール用のテンプレート
      • 最初に、生成されたテンプレートをカスタマイズして、実際に有効化メールで使えるようにします
        • app/mailers/application_mailer.rb
        • app/mailers/user_mailer.rb
          • def account_activation(user)
            • mail to: user.email, subject: "Account activation"
        • app/views/user_mailer/account_activation.text.erb
          • アカウント有効化のテキストビュー
          • <%= edit_account_activation_url(@user.activation_token, email: @user.email) %>
        • app/views/user_mailer/account_activation.html.erb
          • アカウント有効化のHTMLビュー
    • 送信メールのプレビュー
      • Railsでは、特殊なURLにアクセスするとメールのメッセージをその場でプレビュー
      • config/environments/development.rb
        • development環境のメール設定
      • test/mailers/previews/user_mailer_preview.rb
        • Userメイラープレビュー
        • user = User.first
        • user.activation_token = User.new_token
        • UserMailer.account_activation(user)
    • 送信メールのテスト
      • assert_matchという非常に強力なメソッドが使われています。これを使えば、正規表現で文字列をテストできます。
      • test/mailers/user_mailer_test.rb
        • 現在のメールの実装をテストする
        • CGI.escape(user.email)
          • テスト用のユーザーのメールアドレスをエスケープ
        • fixtureユーザーに有効化トークンを追加
      • config/environments/test.rb
    • ユーザーのcreateアクションを更新
      • app/controllers/users_controller.rb
        • UserMailer.account_activation(@user).deliver_now
        • flash[:info] = "Please check your email to activate your account."
        • redirect_to root_url
        • リダイレクト先をプロフィールページからルートURLに変更し、かつユーザーは以前のようにログインしないようになっています
      • test/integration/users_signup_test.rb
  • アカウントを有効化する
    • 今度はAccountActivationsコントローラのeditアクションを書いていきましょう
    • アクションへのテストを書き、しっかりとテストできていることが確認できたら、AccountActivationsコントローラからUserモデルにコードを移していく作業 (リファクタリング)
    • authenticated?メソッドの抽象化
      • メタプログラミング
        • sendメソッドの強力きわまる機能です。このメソッドは、渡されたオブジェクトに「メッセージを送る」ことによって、呼び出すメソッドを動的に決めることができます
      • app/models/user.rb
        • 抽象化されたauthenticated?メソッド
        • digest = send("#{attribute}_digest")
      • app/helpers/sessions_helper.rb
        • if user && user.authenticated?(:remember, cookies[:remember_token])
      • test/models/user_test.rb
        • assert_not @user.authenticated?(:remember, '')
    • editアクションで有効化
      • paramsハッシュで渡されたメールアドレスに対応するユーザーを認証
        • if user && !user.activated? && user.authenticated?(:activation, params[:id])
      • app/controllers/account_activations_controller.rb
        • アカウントを有効化するeditアクション
        • user.update_attribute(:activated, true)
        • user.update_attribute(:activated_at, Time.zone.now)
      • app/controllers/sessions_controller.rb
        • 有効でないユーザーがログインすることのないようにする
    • 有効化のテストとリファクタリング
      • test/integration/users_signup_test.rb
        • assert_equal 1, ActionMailer::Base.deliveries.size
          • 本当に重要な1点
          • deliveriesは変数なので、setupメソッドでこれを初期化しておかないと、並行して行われる他のテストでメールが配信されたときにエラーが発生
      • app/models/user.rb
        • Userモデルにユーザー有効化メソッドを追加
        • user.という記法を使っていない
        • def activate
          • update_attribute(:activated, true)
          • update_attribute(:activated_at, Time.zone.now)
        • def send_activation_email
          • UserMailer.account_activation(self).deliver_now
      • app/controllers/users_controller.rb
        • ユーザーモデルオブジェクトからメールを送信
        • @user.send_activation_email
      • app/controllers/account_activations_controller.rb
        • ユーザーモデルオブジェクト経由でアカウントを有効化
        • user.activate
      • 演習
        • update_columns(activated: true, activated_at: Time.zone.now)
        • @users = User.where(activated: true).paginate(page: params[:page])
        • redirect_to root_url and return unless @user.activated?
        • まずshow用にintegrationテストを作成する(indexは既存)
          • rails g integration_test users_show
        • テスト用のactivated: falseユーザーを新しく作る
          • test/fixtures/users.yml
          • activated: false
        • test/integration/users_index_test.rb
          • if user.activated?
          • else
            • assert_select 'a[href=?]', user_path(user), text: user.name, count: 0
          • unless user == @admin || !user.activated?
        • test/integration/users_show_test.rb
          • get user_path(@non_activated_user)
          • assert_redirected_to root_url
  • 本番環境でのメール送信
    • heroku apps:rename sample-app
    • 本番環境からメール送信するために、「Mailgun」というHerokuアドオンを利用してアカウントを検証
      • (このアドオンを利用するためにはHerokuアカウントにクレジットカードを設定する必要がありますが、アカウント検証では料金は発生しません)
      • 「starter」というプランを使うことにします。これは、(執筆時点では) 1日のメール数が最大400通までという制限がありますが、無料で利用することができます
    • config/environments/production.rb
      • Railsのproduction環境でMailgunを使う設定
    • heroku addons:create mailgun:starter
      • MailgunのHerokuアドオンを追加するために、コマンドを実行
    • Herokuの環境変数を表示したい場合は、次のコマンドを実行
      • heroku config:get MAILGUN_SMTP_LOGIN
      • heroku config:get MAILGUN_SMTP_PASSWORD
    • Mailgunアカウントのuser_nameとpassword設定を記入する行もありますが、そこには記入せず、必ず環境変数「ENV」に設定する
    • 受信メールの認証
      • heroku addons:open mailgun
  • 最後に
    • アカウント有効化を実装したことにより、サンプルアプリケーションの「ユーザー登録」「ログイン」「ログアウト」の仕組みがほぼ完成した
    • これを完成させるための最後に1ピースは、ユーザーがパスワードを忘れた時の「パスワード再設定」機能
    • 本章のまとめ
      • アカウント有効化は Active Recordオブジェクトではないが、セッションの場合と同様に、リソースでモデル化できる
      • Railsは、メール送信で扱うAction Mailerのアクションとビューを生成することができる
      • Action MailerではテキストメールとHTMLメールの両方を利用できる
      • メイラーアクションで定義したインスタンス変数は、他のアクションやビューと同様、メイラーのビューから参照できる
      • アカウントを有効化させるために、生成したトークンを使って一意のURLを作る
      • より安全なアカウント有効化のために、ハッシュ化したトークン (ダイジェスト) を使う
      • メイラーのテストと統合テストは、どちらもUserメイラーの振舞いを確認するのに有用
      • Mailgunを使うと、production環境からメールを送信できる

Ch12 パスワードの再設定

  • ほとんどは、アカウント有効化で見てきた内容と似通っています
    • PasswordResetsリソースを作成して、再設定用のトークンとそれに対応するダイジェストを保存するのが今回の目的
  • 全体の流れ
    • ユーザーがパスワードの再設定をリクエストすると、ユーザーが送信したメールアドレスをキーにしてデータベースからユーザーを見つける
    • 該当のメールアドレスがデータベースにある場合は、再設定用トークンとそれに対応する再設定ダイジェストを生成する
    • 再設定用ダイジェストはデータベースに保存しておき、再設定用トークンはメールアドレスと一緒に、ユーザーに送信する有効化用メールのリンクに仕込んでおく
    • ユーザーがメールのリンクをクリックしたら、メールアドレスをキーとしてユーザーを探し、データベース内に保存しておいた再設定用ダイジェストと比較する (トークンを認証する)
    • 認証に成功したら、パスワード変更用のフォームをユーザーに表示する
  • PasswordResetsリソース
    • まずはPasswordResetsリソースのモデリング
      • 新たなモデルは作らずに、代わりに必要なデータ (再設定用のダイジェストなど) をUserモデルに追加していく形
      • PasswordResetsもリソースとして扱っていきたいので、まずは標準的なRESTfulなURLを用意
      • パスワードを再設定するフォームが必要なので、ビューを描画するためのnewアクションとeditアクションが必要
        • それぞれのアクションに対応する作成用/更新用のアクションも最終的なRESTfulなルーティングには必要になります
    • PasswordResetsコントローラ
      • rails generate controller PasswordResets new edit --no-test-framework
      • config/routes.rb
        • resources :password_resets, only: [:new, :create, :edit, :update]
      • app/views/sessions/new.html.erb
        • パスワード再設定画面へのリンクを追加する
        • <%= link_to "(forgot password)", new_password_reset_path %>
    • 新しいパスワードの設定
      • パスワードの再設定でも、トークン用の仮想的な属性とそれに対応するダイジェストを用意
      • 再設定用のリンクはなるべく短時間 (数時間以内) で期限切れになるようにしなければなりません
      • reset_digest属性とreset_sent_at属性をUserモデルに追加
        • rails generate migration add_reset_to_users reset_digest:string reset_sent_at:datetime
      • app/views/password_resets/new.html.erb
        • 新しいセッションを作成するためのログインフォーム (リスト 8.4) を使います
        • form_forで扱うリソースとURLが異なっている点と、パスワード属性が省略されている点
      • 演習
        • password_resetはUserモデルに変更を加えるコントローラ
          • インスタンス変数を使う場合@user
          • form_forに@userを使うと/usersに対応するPOSTとしてsignupとなる
          • → :password_reset
    • createアクションでパスワード再設定
      • app/controllers/password_resets_controller.rb
        • パスワード再設定用のcreateアクション
      • app/models/user.rb
        • Userモデルにパスワード再設定用メソッドを追加する
        • def create_reset_digest
        • def send_password_reset_email
  • パスワード再設定のメール送信
    • パスワード再設定のメールとテンプレート
    • 送信メールのテスト
      • test/mailers/user_mailer_test.rb
        • パスワード再設定用メイラーメソッドのテストを追加
  • パスワードを再設定する
    • editアクションで再設定
      • app/views/password_resets/edit.html.erb
        • パスワード再設定のフォーム
        • <%= hidden_field_tag :email, @user.email %>
          • editアクションとupdateアクションの両方でメールアドレスが必要
          • 前者 (hidden_field_tag) ではメールアドレスがparams[:email]に保存されますが、後者(f.hidden_field :email, @user.email)ではparams[:user][:email] に保存されてしまう
      • app/controllers/password_resets_controller.rb
        • パスワード再設定のeditアクション
        • @userインスタンス変数を定義
        • params[:id]の再設定用トークンと、リスト 11.26で抽象化したauthenticated?メソッドを使って、このユーザーが正当なユーザーである (ユーザーが存在する、有効化されている、認証済みである) ことを確認
    • パスワードを更新する
      • app/controllers/password_resets_controller.rb
        • before_action :check_expiration, only: [:edit, :update]
        • def update
          • if params[:user][:password].empty?
            • @user.errors.add(:password, :blank)
          • elsif @user.update_attributes(user_params)
          • else
            • render 'edit'
        • def user_params
          • params.require(:user).permit(:password, :password_confirmation)
        • def check_expiration
          • if @user.password_reset_expired?
      • app/models/user.rb
        • def password_reset_expired?
          • reset_sent_at < 2.hours.ago
    • パスワードの再設定をテストする
      • rails generate integration_test password_resets
      • test/integration/password_resets_test.rb
        • パスワード再設定をテストする手順は、アカウント有効化のテスト (リスト 11.33) と多くの共通点がありますが、テストの冒頭部分には次のような違い
          • 最初に「forgot password」フォームを表示して無効なメールアドレスを送信し、次はそのフォームで有効なメールアドレスを送信
          • 後者ではパスワード再設定用トークンが作成され、再設定用メールが送信
        • メールのリンクを開いて無効な情報を送信し、次にそのリンクから有効な情報を送信して、それぞれが期待どおりに動作
        • assert_select "input[name=email][type=hidden][value=?]", user.email
          • inputタグに正しい名前、type="hidden"、メールアドレスがあるかどうかを確認
      • 演習
        • def create_reset_digest
          • update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
        • assert_match /expired/i, response.body
          • 期限切れをテストする方法
            • レスポンスの本文に「expired」という語があるかどうかでチェック
        • @user.update_attribute(:reset_digest, nil)
          • パスワードの再設定に成功したらダイジェストをnilになるように変更
        • test/integration/password_resets_test.rb
          • test "password resets" doの最後
            • assert_nil user.reload.reset_digest
  • 本番環境でのメール送信 (再掲)
  • 最後に
    • サンプルアプリケーションのユーザー登録・ログイン・ログアウトの仕組みは、本物のアプリケーションと近いレベルに仕上がりました
    • 本章のまとめ
      • パスワードの再設定は Active Recordオブジェクトではないが、セッションやアカウント有効化の場合と同様に、リソースでモデル化できる
      • Railsは、メール送信で扱うAction Mailerのアクションとビューを生成することができる
      • Action MailerではテキストメールとHTMLメールの両方を利用できる
      • メイラーアクションで定義したインスタンス変数は、他のアクションやビューと同様、メイラーのビューから参照できる
      • パスワードを再設定させるために、生成したトークンを使って一意のURLを作る
      • より安全なパスワード再設定のために、ハッシュ化したトークン (ダイジェスト) を使う
      • メイラーのテストと統合テストは、どちらもUserメイラーの振舞いを確認するのに有用
      • Mailgunを使うとproduction環境からメールを送信できる
  • 証明: 期限切れの比較

Ch13 ユーザーのマイクロポスト

  • Micropostモデル
    • まずはMicropostリソースの最も本質的な部分を表現するMicropostモデルを作成するところから
    • 基本的なモデル
      • Micropostモデルは、マイクロポストの内容を保存するcontent属性と、特定のユーザーとマイクロポストを関連付けるuser_id属性の2つの属性だけを持ちます
      • String型ではなくText型
        • ある程度の量のテキストを格納するとき
        • 投稿フォームにString用のテキストフィールドではなくてText用のテキストエリアを使うため、より自然な投稿フォームが実現
        • Text型の方が将来における柔軟性に富んでいて、例えばいつか国際化をするときに、言語に応じて投稿の長さを調節することもできます
        • Text型を使っていても本番環境でパフォーマンスの差は出ません
      • rails generate model Micropost content:text user:references
      • add_index :microposts, [:user_id, :created_at]
        • user_idに関連付けられたすべてのマイクロポストを作成時刻の逆順で取り出しやすくなります
        • 両方のキーを同時に扱う複合キーインデックス (Multiple Key Index) を作成
    • Micropostのバリデーション
      • test/models/micropost_test.rb
        • 新しいMicropostの有効性に対するテスト
        • Micropostモデルのバリデーションに対するテスト
      • app/models/micropost.rb
        • validates :user_id, presence: true
        • validates :content, presence: true, length: { maximum: 140 }
    • User/Micropostの関連付け
      • Webアプリケーション用のデータモデルを構築するにあたって、個々のモデル間での関連付けを十分考えておくことが重要
      • 紐付いているユーザーを通してマイクロポストを作成
        • @micropost = @user.microposts.build(content: "Lorem ipsum")
          • newメソッドと同様に、buildメソッドはオブジェクトを返しますがデータベースには反映されません。
          • @user.microposts.buildのようなコードを使うためには、 UserモデルとMicropostモデルをそれぞれ更新して、関連付ける必要
      • app/models/micropost.rb
        • belongs_to :user
      • app/models/user.rb
        • has_many :microposts
      • test/models/micropost_test.rb
        • @micropost = @user.microposts.build(content: "Lorem ipsum")
    • マイクロポストを改良する
      • ユーザーのマイクロポストを特定の順序で取得できるようにしたり、マイクロポストをユーザーに依存させて、ユーザーが削除されたらマイクロポストも自動的に削除されるようにしていきます
      • デフォルトのスコープ
        • test/models/micropost_test.rb
          • assert_equal microposts(:most_recent), Micropost.first
        • test/fixtures/microposts.yml
          • マイクロポスト用のfixture
          • created_atカラム
            • Railsによって自動的に更新されるため基本的には手動で更新できない
            • fixtureファイルの中では更新可能
        • app/models/micropost.rb
          • default_scope -> { order(created_at: :desc) }
            • Procやlambda (もしくは無名関数)と呼ばれるオブジェクトを作成する文法
            • ->というラムダ式は、ブロック (4.3.2) を引数に取り、Procオブジェクトを返します
              • このオブジェクトは、callメソッドが呼ばれたとき、ブロック内の処理を評価
      • Dependent: destroy
        • app/models/user.rb
          • マイクロポストは、その所有者 (ユーザー) と一緒に破棄されることを保証する
          • has_many :microposts, dependent: :destroy
        • test/models/user_test.rb
          • assert_difference 'Micropost.count', -1 do
            • @user.destroy
  • マイクロポストを表示する
    • マイクロポストの描画
      • rails generate controller Microposts
      • app/views/microposts/_micropost.html.erb
        • 1つのマイクロポストを表示するパーシャル
        • <\li id="micropost-<%= micropost.id %>">
          • 将来、JavaScriptを使って各マイクロポストを操作したくなったときなどに役立ちます
      • app/controllers/users_controller.rb
        • @microposts = @user.microposts.paginate(page: params[:page])
      • app/views/users/show.html.erb
        • マイクロポストをユーザーのshowページ (プロフィール画面) に追加
            • 順序無しリストのulタグではなく、順序付きリストのolタグを使っている
            • マイクロポストが特定の順序 (新しい→古い) に依存しているため
          1. <%= will_paginate @microposts %>
            • 明示的に@microposts変数をwill_paginateに渡す必要
            • インスタンス変数をUsersコントローラのshowアクションで定義
    • マイクロポストのサンプル
      • db/seeds.rb
        • サンプルデータにマイクロポストを追加
        • content = Faker::Lorem.sentence(5)
        • users.each { |user| user.microposts.create!(content: content) }
        • ループの順序に違和感があるかもしれませんが、これは14.3でステータスフィード (いわゆるタイムライン) を実装するときに役立ちます
      • app/assets/stylesheets/custom.scss
        • マイクロポスト用のCSS
    • プロフィール画面のマイクロポストをテストする
      • rails generate integration_test users_profile
      • test/fixtures/microposts.yml
        • ユーザーと関連付けされたマイクロポストのfixture
        • <% 30.times do |n| %>
        • micropost_<%= n %>:
      • test/integration/users_profile_test.rb
        • 今回のテストでは、プロフィール画面にアクセスした後に、ページタイトルとユーザー名、Gravatar、マイクロポストの投稿数、そしてページ分割されたマイクロポスト、といった順でテスト
        • assert_match @user.microposts.count.to_s, response.body
          • assert_selectよりもずっと抽象的なメソッド
          • assert_selectではどのHTMLタグを探すのか伝える必要がありますが、assert_matchメソッドではその必要がない
        • assert_select 'h1>img.gravatar'
          • ネストした文法
          • h1タグ (トップレベルの見出し) の内側にある、gravatarクラス付きのimgタグがあるかどうかをチェック
      • 演習
        • assert_select 'div.pagination', count: 1
  • マイクロポストを操作する
    • データモデリングとマイクロポスト表示テンプレートの両方が完成したので、次はWeb経由でそれらを作成するためのインターフェイスに取りかかりましょう
    • Micropostsリソースへのインターフェイスは、主にプロフィールページとHomeページのコントローラを経由して実行
      • Micropostsコントローラにはnewやeditのようなアクションは不要
      • createとdestroyがあれば十分
    • config/routes.rb
      • resources :microposts, only: [:create, :destroy]
      • scaffoldが生成するような複雑なコードはほとんど不要になりました
    • マイクロポストのアクセス制御
      • test/controllers/microposts_controller_test.rb
        • Micropostsコントローラの認可テスト
          • ログイン済みかどうかを確かめるテストでは、Usersコントローラ用のテストがそのまま役に立ちます
          • 正しいリクエストを各アクションに向けて発行し、マイクロポストの数が変化していないかどうか、また、リダイレクトされるかどうかを確かめればよい
        • test "should redirect create when not logged in" do
        • test "should redirect destroy when not logged in" do
      • app/controllers/application_controller.rb
        • logged_in_userメソッドをApplicationコントローラに移す
      • app/controllers/users_controller.rb
        • Usersコントローラ内のlogged_in_userフィルターを削除
      • app/controllers/microposts_controller.rb
        • before_action :logged_in_user, only: [:create, :destroy]
    • マイクロポストを作成する
      • ユーザーのサインアップを実装しました。マイクロポスト作成の実装もこれと似ています
      • 主な違いは、別の micropost/new ページを使う代わりに、ホーム画面 (つまりルートパス) にフォームを置くという点
      • ユーザーのログイン状態に応じて、ホーム画面の表示を変更
      • app/controllers/microposts_controller.rb
        • Micropostsコントローラのcreateアクション
        • ユーザー用アクションと似ています
        • 違いは、新しいマイクロポストをbuildするためにUser/Micropost関連付けを使っている点
        • micropost_paramsでStrong Parametersを使っていることにより、マイクロポストのcontent属性だけがWeb経由で変更可能になっている
          • params.require(:micropost).permit(:content)
      • app/views/static_pages/home.html.erb
        • Homeページ (/) にマイクロポストの投稿フォームを追加する
        • <% if logged_in? %>
          • <%= render 'shared/user_info' %>
          • <%= render 'shared/micropost_form' %>
      • app/views/shared/_user_info.html.erb
        • サイドバーで表示するユーザー情報のパーシャル
      • app/views/shared/_micropost_form.html.erb
        • マイクロポスト投稿フォームのパーシャル
      • app/controllers/static_pages_controller.rb
        • @micropost = current_user.microposts.build if logged_in?
      • app/views/shared/_error_messages.html.erb
        • Userオブジェクト以外でも動作するようにerror_messagesパーシャルを更新する
        • @userをobjectにする
      • app/views/users/_form.html.erb
        • @userをf.objectにする
      • app/views/password_resets/edit.html.erb
        • <%= render 'shared/error_messages', object: f.object %>
      • vim test/integration/site_layout_test.rb
        • 修正必要
      • 演習
        • app/views/static_pages/_home_logged_in.html.erb
        • app/views/static_pages/_home_not_logged_in.html.erb
    • フィードの原型
      • すべてのユーザーがフィードを持つので、feedメソッドはUserモデルで作るのが自然
      • app/models/user.rb
        • マイクロポストのステータスフィードを実装するための準備
        • Micropost.where("user_id = ?", id)
      • app/controllers/static_pages_controller.rb
        • homeアクションにフィードのインスタンス変数を追加する
        • @feed_items = current_user.feed.paginate(page: params[:page])
      • app/views/shared/_feed.html.erb
        • ステータスフィードのパーシャル
        • <%= render @feed_items %>
        • <%= will_paginate @feed_items %>
      • app/views/static_pages/home.html.erb
        • Homeページにステータスフィードを追加する
        • <%= render 'shared/feed' %>
      • app/controllers/microposts_controller.rb
    • マイクロポストを削除する
      • app/views/microposts/_micropost.html.erb
        • マイクロポストのパーシャルに削除リンクを追加する
        • <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
      • app/controllers/microposts_controller.rb
        • Micropostsコントローラのdestroyアクション
        • ユーザーにおける実装 (リスト 10.59) とだいたい同じ
        • 大きな違いは、admin_userフィルターで@user変数を使うのではなく、関連付けを使ってマイクロポストを見つけるようにしている点
        • destroyメソッドではリダイレクトを使っている
          • request.referrer || root_url
            • request.referrer
              • 一つ前のURLを返します
              • request.referrerを使うことでDELETEリクエストが発行されたページに戻すことができるので、非常に便利
            • redirect_back(fallback_location: root_url)と置き換えてもうまく動く
    • フィード画面のマイクロポストをテストする
      • test/fixtures/microposts.yml
        • 別のユーザーに所属しているマイクロポストを追加
      • test/controllers/microposts_controller_test.rb
        • 間違ったユーザーによるマイクロポスト削除に対してテスト
        • log_in_as(users(:michael))
        • micropost = microposts(:ants)
        • assert_no_difference 'Micropost.count' do
          • delete micropost_path(micropost)
      • rails generate integration_test microposts_interface
      • test/integration/microposts_interface_test.rb
        • マイクロポストのUIに対する統合テスト
        • test "micropost interface" do
        • 今回の統合テストでは、ログイン、マイクロポストのページ分割の確認、無効なマイクロポストを投稿、有効なマイクロポストを投稿、マイクロポストの削除、そして他のユーザーのマイクロポストには [delete] リンクが表示されないことを確認、といった順でテスト
        • 初期化時に@が抜けていてインスタンス変数がnilになっていると,NoMethodErrorになる
      • 演習
        • test/integration/microposts_interface_test.rb
          • assert_match "#{@user.microposts.count} microposts", response.body
          • assert_match "1 micropost", response.body
  • マイクロポストの画像投稿
    • 基本的な画像アップロード
      • CarrierWaveという画像アップローダ
        • Rails 5.2から標準となったActive Storage
      • GemfileにCarrierWaveを追加する
        • mini_magick gemとfog gemsも含めている
      • CarrierWaveを導入すると、Railsのジェネレーターで画像アップローダーが生成できるようになります
        • rails generate uploader Picture
      • CarrierWaveでアップロードされた画像は、Active Recordモデルの属性と関連付けされているべき
        • 関連付けされる属性には画像のファイル名が格納されるため、String型
        • rails generate migration add_picture_to_microposts picture:string
      • app/models/micropost.rb
        • Micropostモデルに画像を追加する
        • mount_uploader :picture, PictureUploader
      • app/views/shared/_micropost_form.html.erb
        • マイクロポスト投稿フォームに画像アップローダーを追加
        • Homeページにアップローダーを追加するためには、マイクロポストのフォームにfile_fieldタグを含める
        • <%= f.file_field :picture %>
      • app/controllers/microposts_controller.rb
        • params.require(:micropost).permit(:content, :picture)
      • app/views/microposts/_micropost.html.erb
        • マイクロポストの画像表示を追加
        • <%= image_tag micropost.picture.url if micropost.picture? %>
          • picture?という論理値を返すメソッド
            • 画像用の属性名に応じて、CarrierWaveが自動的に生成してくれるメソッド
      • 演習
        • test/integration/microposts_interface_test.rb
          • assert_select 'input[type=file]'
          • picture = fixture_file_upload('test/fixtures/rails.png', 'image/png')
          • post microposts_path, params: { micropost: { content: content, picture: picture } }
    • 画像の検証
      • app/uploaders/picture_uploader.rb
        • 画像フォーマットのバリデーション
        • def extension_whitelist
      • app/models/micropost.rb
        • 画像に対するバリデーションを追加
        • validate :picture_size
          • 独自のバリデーションを定義するために、今まで使っていたvalidatesメソッドではなく、validateメソッドを使っている
          • ファイルサイズに対するバリデーションはRailsの既存のオプション (presenceやlengthなど) にはありません
        • def picture_size
          • if picture.size > 5.megabytes
            • errors.add(:picture, "should be less than 5MB")
      • app/views/shared/_micropost_form.html.erb
        • ファイルサイズをjQueryでチェック
        • <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
        • <\script type="text/javascript">
          • $('#micropost_picture').bind('change', function() {
            • var size_in_megabytes = this.files[0].size/1024/1024;
            • if (size_in_megabytes > 5) {
              • alert('Maximum file size is 5MB. Please choose a smaller file.');
        • ユーザーはアラートを無視してアップロードを強行する、といったことが可能
    • 画像のリサイズ
      • sudo apt install -y ImageMagick
      • MiniMagickというImageMagickRubyを繋ぐgemを使って、画像をリサイズ
      • app/uploaders/picture_uploader.rb
        • 画像をリサイズするために画像アップローダーを修正
        • include CarrierWave::MiniMagick
        • process resize_to_limit: [400, 400]
        • storage :file
        • def store_dir
          • "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
      • 演習
        • config/initializers/skip_image_resizing.rb
          • テスト時は画像のリサイズをさせない設定
    • 本番環境での画像アップロード
      • 本番環境でクラウドストレージに保存するためには、リスト 13.69のようにfog gemを使うと簡単
      • app/uploaders/picture_uploader.rb
        • 本番環境での画像アップロードを調整
        • if Rails.env.production?
          • storage :fog
        • else
          • storage :file
      • アマゾンの「Simple Storage Service (S3) 」を使います
        • 省略
      • .gitignoreファイルにアップロード用ディレクトリを追加
        • #アップロードされたテスト画像を無視する
        • /public/uploads
  • 最後に
    • 本章のまとめ
      • Active Recordモデルの力によって、マイクロポストも (ユーザーと同じで) リソースとして扱える
      • Railsは複数のキーインデックスをサポートしている
      • Userは複数のMicropostsを持っていて (has_many)、Micropostは1人のUserに依存している (belongs_to) といった関係性をモデル化した
      • has_manyやbelongs_toを利用することで、関連付けを通して多くのメソッドが使えるようになった
      • user.microposts.build(...)というコードは、引数で与えたユーザーに関連付けされたマイクロポストを返す
      • default_scopeを使うとデフォルトの順序を変更できる
      • default_scopeは引数に無名関数 (->) を取る
      • dependent: :destroyオプションを使うと、関連付けされたオブジェクトと自分自身を同時に削除する
      • paginateメソッドやcountメソッドは、どちらも関連付けを通して実行され、効率的にデータベースに問い合わせしている
      • fixtureは、関連付けを使ったオブジェクトの作成もサポートしている
      • パーシャルを呼び出すときに、一緒に変数を渡すことができる
      • whereメソッドを使うと、Active Recordを通して選択 (部分集合を取り出すこと) ができる
      • 依存しているオブジェクトを作成/削除するときは、常に関連付けを通すようにすることで、よりセキュアな操作が実現できる
      • CarrierWaveを使うと画像アップロードや画像リサイズができる

Ch14 ユーザーをフォローする

  • 他のユーザーをフォロー (およびフォロー解除) できるソーシャルな仕組みの追加と、フォローしているユーザーの投稿をステータスフィードに表示する機能を追加
  • Relationshipモデル
    • ユーザーをフォローする機能を実装する第一歩は、データモデルを構成すること
    • データモデルの問題 (および解決策)
      • followingテーブルと has_many関連付けを使って、フォローしているユーザーのモデリング
      • 正しいモデルを見つけ出す方法の1つは、Webアプリケーションにおけるfollowingの動作をどのように実装するかをじっくり考えること
        • RESTアーキテクチャは、作成されたり削除されたりするリソースに関連していた
        • アプリケーションによって作成または削除されるのは、つまるところ2人のユーザーの「関係 (リレーションシップ)」である
        • Twitterのようなフォロー関係では左右非対称の性質
          • 左右非対称な関係性を見分けるために、それぞれを能動的関係 (Active Relationship)と受動的関係 (Passive Relationship)と呼ぶ
      • まずは、フォローしているユーザーを生成するために、能動的関係に焦点を当てていきます
      • followingテーブルをactive_relationshipsテーブルと見立ててみましょう
      • 能動的関係も受動的関係も、最終的にはデータベースの同じテーブルを使うことになります。したがって、テーブル名にはこの「関係」を表す「relationships」を使いましょう
      • rails generate model Relationship follower_id:integer followed_id:integer
      • db/migrate/[timestamp]_create_relationships.rb
        • relationshipsテーブルにインデックスを追加
        • add_index :relationships, :follower_id
        • add_index :relationships, :followed_id
        • add_index :relationships, [:follower_id, :followed_id], unique: true
          • あるユーザーが同じユーザーを2回以上フォローすることを防ぎます
    • User/Relationshipの関連付け
      • フォローしているユーザーとフォロワーを実装する前に、UserとRelationshipの関連付けを行います
      • app/models/user.rb
        • 能動的関係に対して1対多 (has_many) の関連付けを実装
        • has_many :active_relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
      • app/models/relationship.rb
        • リレーションシップ/フォロワーに対してbelongs_toの関連付けを追加
        • belongs_to :follower, class_name: "User"
        • belongs_to :followed, class_name: "User"
    • Relationshipのバリデーション
      • 先に進む前に、Relationshipモデルの検証を追加して完全なものにしておきましょう
      • test/models/relationship_test.rb
        • Relationshipモデルのバリデーションをテスト
        • def setup
        • test "should be valid" do
        • test "should require a follower_id" do
        • test "should require a followed_id" do
      • app/models/relationship.rb
        • Relationshipモデルに対してバリデーションを追加
          • Rails 5から必須ではなくなりました
        • validates :follower_id, presence: true
        • validates :followed_id, presence: true
      • test/fixtures/relationships.yml
        • Relationship用のfixtureを空にする
    • フォローしているユーザー
      • Relationshipの関連付けの核心、followingとfollowersに取りかかります
      • 今回はhas_many throughを使います
      • app/models/user.rb
        • Userモデルにfollowingの関連付けを追加する
        • has_many :following, through: :active_relationships, source: :followed
          • :sourceパラメーター (リスト 14.8) を使って、「following配列の元はfollowed idの集合である」ということを明示的にRailsに伝えます
        • フォローしているユーザーを配列の様に扱えるようになりました
      • followingメソッドで配列のように扱えるだけでも便利ですが、Railsは単純な配列ではなく、もっと賢くこの集合を扱っています
        • following.include?(other_user)
          • 実際にはデータベースの中で直接比較をするように配慮
      • 次に、followingで取得した集合をより簡単に取り扱うために、followやunfollowといった便利メソッドを追加
        • 今回は、こういったメソッドはテストから先に書いていきます
          • Webインターフェイスなどで便利メソッドを使うのはまだ先なので、すぐに使える場面がなく、実装した手応えを得にくいから
          • 一方で、Userモデルに対するテストを書くのは簡単かつ今すぐできます
        • test/models/user_test.rb
          • “following” 関連のメソッドをテスト
        • app/models/user.rb
          • "following" 関連のメソッド
          • 可能な限りself (user自身を表すオブジェクト) を省略している
          • def follow(other_user)
            • following << other_user
          • def unfollow(other_user)
            • active_relationships.find_by(followed_id: other_user.id).destroy
          • def following?(other_user)
            • following.include?(other_user)
    • フォロワー
      • リレーションシップというパズルの最後の一片は、user.followersメソッドを追加すること
        • user.followingメソッドと対
      • app/models/user.rb
        • 受動的関係を使ってuser.followersを実装
        • この実装はリスト 14.8とまさに類似
        • 参照先 (followers) を指定するための:sourceキーを省略してもよかった
          • :followers属性の場合、Railsが「followers」を単数形にして自動的に外部キーfollower_idを探してくれるから
      • test/models/user_test.rb
        • followersに対するテスト
        • assert archer.followers.include?(michael)を追加
  • [Follow] のWebインターフェイス
    • この節では、モックアップで示したようにフォロー/フォロー解除の基本的なインターフェイスを実装
    • また、フォローしているユーザーと、フォロワーにそれぞれ表示用のページを作成
    • フォローのサンプルデータ
      • 先にサンプルデータを自動作成できるようにしておけば、Webページの見た目のデザインから先にとりかかることができ、バックエンド機能の実装を後に回すことができます
      • db/seeds.rb
        • サンプルデータにfollowing/followerの関係性を追加
        • users = User.all
        • user = users.first
        • following = users[2..50]
        • followers = users[3..40]
        • following.each { |followed| user.follow(followed) }
        • followers.each { |follower| follower.follow(user) }
    • 統計と [Follow] フォーム
      • config/routes.rb
        • Usersコントローラにfollowingアクションとfollowersアクションを追加する
        • resources :users do
          • member do
            • get :following, :followers
        • この場合のURLは /users/1/following や /users/1/followers のようになる
        • memberメソッドを使うとユーザーidが含まれているURLを扱うようになります
        • idを指定せずにすべてのメンバーを表示するには、次のようにcollectionメソッド
          • collection do
            • get :rabbits
          • /users/rabbitsに対応
      • ルーティングを定義したので、統計情報のパーシャルを実装する準備が整いました
      • app/views/shared/_stats.html.erb
        • フォロワーの統計情報を表示するパーシャル
        • このパーシャルでは、divタグの中に2つのリンクを含めるようにします
        • <% @user ||= current_user %>
          • このパーシャルはプロフィールページとHomeページの両方に表示
        • @user.following.count
        • @user.followers.count
        • <\strong id="following" class="stat">
          • こうしておくと、14.2.5でAjaxを実装するときに便利
          • 一意のidを指定してページ要素にアクセス
      • app/views/static_pages/_home_logged_in.html.erb
        • Homeページにフォロワーの統計情報を追加する
          • <%= render 'shared/stats' %>
      • app/assets/stylesheets/custom.scss
        • Homeページのサイドバー用のSCSS
      • app/views/users/_follow_form.html.erb
        • フォロー/フォロー解除フォームのパーシャル
        • <% unless current_user?(@user) %>
          • <% if current_user.following?(@user) %>
            • <%= render 'unfollow' %>
          • <% else %>
            • <%= render 'follow' %>
      • config/routes.rb
        • Relationshipリソース用のルーティングを追加する
        • resources :relationships, only: [:create, :destroy]
      • app/views/users/_follow.html.erb
        • ユーザーをフォローするフォーム
        • <%= form_for(current_user.active_relationships.build) do |f| %>
          • <%= hidden_field_tag :followed_id, @user.id %>
          • <%= f.submit "Follow", class: "btn btn-primary" %>
      • app/views/users/_unfollow.html.erb
        • ユーザーをフォロー解除するフォーム
        • <%= form_for(current_user.active_relationships.find_by(followed_id: @user.id), html: { method: :delete }) do |f| %>
          • <%= f.submit "Unfollow", class: "btn" %>
      • これらの2つのフォームの主な違いは、リスト 14.21は新しいリレーションシップを作成するのに対し、リスト 14.22は既存のリレーションシップを見つけ出すという点
        • 前者はPOSTリクエストを Relationshipsコントローラに送信してリレーションシップをcreate (作成) し、後者はDELETEリクエストを送信してリレーションシップをdestroy (削除) する
        • リスト 14.21のhidden_field_tagメソッドを使います。このメソッドは、次のフォーム用HTMLを生成
      • app/views/users/show.html.erb
        • プロフィールページにフォロー用フォームとフォロワーの統計情報を追加
          • <%= render 'shared/stats' %>
        • <%= render 'follow_form' if logged_in? %>
      • 演習
        • test/integration/site_layout_test.rb
        • test/integration/users_profile_test.rb
          • assert_match @user.active_relationships.count.to_s, response.body
          • assert_match @user.passive_relationships.count.to_s, response.body
    • [Following] と [Followers] ページ
      • test/controllers/users_controller_test.rb
        • フォロー/フォロワーページの認可をテスト
        • 前回のアクセス制御と同様に、まずはテストから
      • app/controllers/users_controller.rb
        • followingアクションとfollowersアクション
        • チュートリアルのいたるところで見てきたように、Railsは慣習に従って、アクションに対応するビューを暗黙的に呼び出します。例えば、showアクションの最後でshow.html.erbを呼び出す、といった具合
        • 一方で、リスト 14.25のいずれのアクションも、renderを明示的に呼び出し、show_followという同じビューを出力
      • app/views/users/show_follow.html.erb
        • フォローしているユーザーとフォロワーの両方を表示するshow_followビュー
        • 現在のユーザーを一切使っていない
          • 他のユーザーのフォロワー一覧ページもうまく動きます
      • rails generate integration_test following
        • HTML構造を網羅的にチェックするテストは壊れやすく、生産性を逆に落としかねない
        • 基本的なテストだけに留めており、網羅的なテストにはしていません
          • 今回は、正しい数が表示されているかどうかと、正しいURLが表示されているかどうかの2つのテストを書きます
      • test/fixtures/relationships.yml
        • following/followerをテストするためのリレーションシップ用fixture
      • test/integration/following_test.rb
        • following/followerページのテスト
        • assert_not @user.following.empty?
          • 次のコードを確かめるためのテスト
          • @user.following.each do |user|
            • assert_select "a[href=?]", user_path(user)
          • もし@user.following.empty?の結果がtrueであれば、assert_select内のブロックが実行されなくなるため、その場合においてテストが適切なセキュリティモデルを確認できなくなることを防いでいます
    • [Follow] ボタン (基本編)
      • rails generate controller Relationships
        • フォローとフォロー解除はそれぞれリレーションシップの作成と削除に対応しているため、まずはRelationshipsコントローラが必要
      • 最初にテストを書き、それをパスするように実装することでセキュリティモデルを確立
      • test/controllers/relationships_controller_test.rb
        • リレーションシップの基本的なアクセス制御に対するテスト
        • コントローラのアクションにアクセスするとき、ログイン済みのユーザーであるかどうかをチェック
        • もしログインしていなければログインページにリダイレクトされるので、Relationshipのカウントが変わっていないことを確認
      • app/controllers/relationships_controller.rb
        • logged_in_userフィルターをRelationshipsコントローラのアクションに対して追加
        • リレーションシップのアクセス制御
        • Relationshipsコントローラ
        • フォーム (リスト 14.21とリスト 14.22) から送信されたパラメータを使って、followed_idに対応するユーザーを見つけてくる必要
        • その後、見つけてきたユーザーに対して適切にfollow/unfollowメソッド (リスト 14.10) を使います
    • [Follow] ボタン (Ajax編)
      • Ajaxを使えば、Webページからサーバーに「非同期」で、ページを移動することなくリクエストを送信することができます
      • form_forをform_for ..., remote: trueに置き換えるだけ
        • たったこれだけで、Railsは自動的にAjaxを使うようになります
      • app/views/users/_follow.html.erb
        • <%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
      • app/views/users/_unfollow.html.erb
        • <%= form_for(current_user.active_relationships.find_by(followed_id: @user.id), html: { method: :delete }, remote: true) do |f| %>
        • formタグの内部でdata-remote="true"を設定
          • これは、JavaScriptによるフォーム操作を許可することをRailsに知らせるためのもの
      • JavaScriptを前面に出すべからずという哲学
      • 対応するRelationshipsコントローラを改造して、Ajaxリクエストに応答できるようにしましょう
        • リクエストの種類によって応答を場合分けするときは、respond_toメソッド
      • app/controllers/relationships_controller.rb
        • RelationshipsコントローラでAjaxリクエストに対応
        • respond_to do |format|
          • format.html { redirect_to user }
          • format.js
        • いずれかの1行が実行されるという点が重要
        • respond_toメソッドは、上から順に実行する逐次処理というより、if文を使った分岐処理に近いイメージ
        • ビューで変数を使うため、userが@userに変わった
      • ブラウザ側でJavaScriptが無効になっていた場合 (Ajaxリクエストが送れない場合) でもうまく動くようにします
      • config/application.rb
        • config.action_view.embed_authenticity_token_in_remote_forms = true
      • Ajaxリクエストを受信した場合は、Railsが自動的にアクションと同じ名前を持つJavaScript用の埋め込みRuby (.js.erb) ファイル (create.js.erbやdestroy.js.erbなど) を呼び出す
        • これらのファイルではJavaScriptと埋め込みRuby (ERb) をミックスして現在のページに対するアクションを実行する
      • JS-ERbファイルの内部では、DOM (Document Object Model) を使ってページを操作するため、RailsjQuery JavaScriptヘルパーを自動的に提供
        • これによりjQueryライブラリの膨大なDOM操作用メソッドが使えるようになりますが、13.4.2で見たように今回使うのはわずか2つ
        • まずはドル記号 ($) とCSS idを使って、DOM要素にアクセスする文法
          • $("#follow_form")
          • follow_formの要素をjQueryで操作
          • jQueryの文法はCSSの記法から影響を受けており、#シンボルを使ってCSSのidを指定
          • jQueryCSSと同様、ドット.を使ってCSSクラスを操作
        • 次に必要なメソッドはhtml
          • 引数の中で指定された要素の内側にあるHTMLを更新
          • $("#follow_form").html("foobar")
            • フォロー用フォーム全体を"foobar"という文字列で置き換えたい場合
      • 純粋なJavaScriptと異なり、JS-ERbファイルでは組み込みRuby (ERb) が使えます
      • app/views/relationships/create.js.erb
        • JavaScriptと埋め込みRubyを使ってフォローの関係性を作成する
        • $("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
        • $("#followers").html('<%= @user.followers.count %>');
      • app/views/relationships/destroy.js.erb
        • Ruby JavaScript (RJS) を使ってフォローの関係性を削除する
        • $("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
        • $("#followers").html('<%= @user.followers.count %>');
    • フォローをテストする
      • test/integration/following_test.rb
        • [Follow] / [Unfollow] ボタンをテスト
        • assert_difference '@user.following.count', 1 do
          • post relationships_path, params: { followed_id: @other.id }, xhr: true
          • xhr (XmlHttpRequest) というオプションをtrueに設定すると、Ajaxでリクエストを発行するように変わります
        • assert_difference '@user.following.count', -1 do
          • delete relationship_path(relationship), xhr: true
        • それぞれ従来どおりのテストと、Ajax用のテストの2つ
  • ステータスフィード
    • 現在のユーザーにフォローされているユーザーのマイクロポストの配列を作成し、現在のユーザー自身のマイクロポストと合わせて表示
    • このセクションを通して、複雑さを増したフィードの実装に進んでいきます
    • これを実現するためには、RailsRubyの高度な機能の他に、SQLプログラミングの技術も必要
    • 動機と計画
      • この目的は、現在のユーザーによってフォローされているユーザーに対応するユーザーidを持つマイクロポストを取り出し、同時に現在のユーザー自身のマイクロポストも一緒に取り出す
      • まずはテストから書いていく
        • このテストで重要なことは、フィードに必要な3つの条件を満たすこと
          • 1) フォローしているユーザーのマイクロポストがフィードに含まれている
          • 2) 自分自身のマイクロポストもフィードに含まれている
          • 3) フォローしていないユーザーのマイクロポストがフィードに含まれていない
      • test/models/user_test.rb
        • ステータスフィードのテスト
        • assert michael.feed.include?(post_following)
        • assert michael.feed.include?(post_self)
        • assert_not michael.feed.include?(post_unfollowed)
    • フィードを初めて実装する
      • micropostsテーブルから、あるユーザー (つまり自分自身) がフォローしているユーザーに対応するidを持つマイクロポストをすべて選択 (select) する
      • SQLがINというキーワードをサポートしていることを前提にしています (大丈夫、実際にサポートされています)。このキーワードを使うことで、idの集合の内包 (set inclusion) に対してテストを行えます
      • フォローされているユーザーに対応するidの配列が必要
        • これを行う方法の1つは、Rubyのmapメソッドを使うことです。このメソッドはすべての「列挙可能 (enumerable)」なオブジェクト (配列やハッシュなど、要素の集合で構成されるあらゆるオブジェクト) で使えます
        • [1, 2, 3, 4].map(&:to_s)
          • アンパサンド (Ampersand) & と、メソッドに対応するシンボルを使った短縮表記 (4.3.2) が使えます
        • [1, 2, 3, 4].map(&:to_s).join(', ')
        • User.first.following_ids
          • following_idsメソッドは、has_many :followingの関連付けをしたときにActive Recordが自動生成したもの
          • user.followingコレクションに対応するidを得るためには、関連付けの名前の末尾に_idsを付け足すだけで済みます
        • User.first.following_ids.join(', ')
        • 実際にSQL文字列に挿入するときは、このように記述する必要はありません。実は、?を内挿すると自動的にこの辺りの面倒を見てくれます
          • さらに、データベースに依存する一部の非互換性まで解消
        • Micropost.where("user_id IN (?) OR user_id = ?", following_ids, id) ← これでOK
      • app/models/user.rb
        • とりあえず動くフィードの実装
        • Micropost.where("user_id IN (?) OR user_id = ?", following_ids, id)
    • サブセレクト
      • フォローしているユーザー数に応じてスケールできるように、ステータスフィードを改善
      • app/models/user.rb
        • Micropost.where("user_id IN (:following_ids) OR user_id = :user_id, following_ids: following_ids, user_id: id)
        • 疑問符を使った文法も便利ですが、同じ変数を複数の場所に挿入したい場合は、置き換え後の文法を使う方がより便利
        • following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
        • Micropost.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id)
      • 演習
        • test/integration/following_test.rb
          • assert_match CGI.escapeHTML(micropost.content), response.body
  • 最後に
    • ステータスフィードが追加され、Railsチュートリアルのサンプルアプリケーションがとうとう完成しました
    • このサンプルアプリケーションには、Railsの主要な機能 (モデル、ビュー、コントローラ、テンプレート、パーシャル、beforeフィルター、バリデーション、コールバック、has_many/belongs_to/has_many through関連付け、セキュリティ、テスティング、デプロイ) が多数含まれています
    • サンプルアプリケーションの機能を拡張する
      • この項で提案する拡張機能 (検索、返信、メッセージ機能など) のほとんどは、Webアプリケーションでは一般的な機能
      • 一般的なアドバイス
        • Railsアプリケーションに何らかの機能を実装していて困ったときは、RailsガイドやRails APIをチェックしてみてください。いずれも1,000ページを超える大型ドキュメントなので、今自分がやろうとしていることに関連するトピックがあるかもしれません
        • できるだけ念入りにGoogleで検索し、自分が調べようとしているトピックに言及しているブログやチュートリアルがないかどうか、よく探すことです。Webアプリケーションの開発には常に困難がつきまといます。他人の経験と失敗から学ぶことも重要です
      • Ruby/Railsのバージョンを上げてみよう
        • 実際のプロダクト開発ではこまめにアップグレードするのがオススメ
        • Rubyはバージョン間の互換性が高いためそこまで苦労しないと思いますが、Railsは少々大変かもしれません。Railsガイドに『Railsアップグレードガイド』があるので、この演習課題に取り組むときはぜひ参考にしてみてください
      • 返信機能
        • @replyは受信者のフィードと送信者のフィードにのみ表示されるようにします
        • これを実装するには、micropostsテーブルのin_reply_toカラムと、追加のincluding_repliesスコープをMicropostモデルに追加する必要がある
        • スコープの詳細については、RailsガイドのActive Record クエリインターフェイスを参照
        • このサンプルアプリケーションではユーザー名が重なり得るので、ユーザー名を一意に表す方法も考えなければならない
          • 1つの方法は、idと名前を組み合わせて@1-michael-hartlのようにすること
          • もう1つの方法は、ユーザー登録の項目に一意のユーザー名を追加し、@replyで使えるようにすること
      • メッセージ機能
        • ダイレクトメッセージを行える機能
        • Messageモデルと、新規マイクロポストにマッチする正規表現が必要
      • フォロワーの通知
        • ユーザーに新しくフォロワーが増えたときにメールで通知する機能
        • メールでの通知機能をオプションとして選択可能にし、不要な場合は通知をオフにできるようにしてみましょう
        • メール周りで分からないことがあったら、RailsガイドのAction Mailerの基礎にヒントがないか調べてみましょう
      • RSSフィード
        • ユーザーごとのマイクロポストをRSSフィードする機能を実装
        • 次にステータスフィードをRSSフィードする機能も実装
        • 余裕があればフィードに認証スキームも追加してアクセスを制限
      • REST API
        • 三者のアプリケーションからリソースのget/post/put/deleteが行える
        • 解決のヒントは、respond_toブロックをコントローラーの多くのアクションに追加すること
        • このブロックはXMLをリクエストされたときに応答
        • セキュリティには十分注意
        • 認可されたユーザーにのみAPIアクセスを許可する必要
      • 検索機能
        • ユーザーを検索
        • マイクロポストを検索
        • まずは自分自身で検索機能に関する情報を探してみましょう。難しければ、@budougumi0617 さんの簡単な検索フォームの実装例を参考にしてください
      • 他の拡張機能
        • 「いいね機能」「シェア機能」「minitestの代わりにRSpecで書き直す」「erbの代わりにHamlで書き直す」「エラーメッセージをI18nで日本語化する」「オートコンプリート機能」といったアイデア
    • 読み物ガイド
    • 本章のまとめ
      • has_many :throughを使うと、複雑なデータ関係をモデリングできる
      • has_manyメソッドには、クラス名や外部キーなど、いくつものオプションを渡すことができる
      • 適切なクラス名と外部キーと一緒にhas_many/has_many :throughを使うことで、能動的関係 (フォローする) や受動的関係 (フォローされる) がモデリングできた
      • ルーティングは、ネストさせて使うことができる
      • whereメソッドを使うと、柔軟で強力なデータベースへの問い合わせが作成できる
      • Railsは (必要に応じて) 低級なSQLクエリを呼び出すことができる
      • 本書で学んだすべてを駆使することで、フォローしているユーザーのマイクロポスト一覧をステータスフィードに表示させることができた
    • あとがき

おまけ

Ch15 React

  • webpackの導入
    • Webpacker gemの追加
      • Asset Pipelineでも良いのではと思われると思いますが、webpackを利用すると他にも色々な機能が利用できます
        • JavaScript以外で書かれたコードを、ブラウザが解釈できるJavaScriptに変換してあげる必要があり、その役割もwebpackが担ってくれます
        • Reactなどをnodeモジュールとして管理したいという場合にも、webpackを利用することで簡単に管理できるようになります
      • gem 'webpacker', '~> 3.0'
    • webpackerのインストール
      • rails webpacker:install
    • webpackerのインストールタスクで生成されたファイルの説明
    • webpackの利用
      • app/javascript/packs/application.jsをload
      • bin/webpackでtranspile
    • トランスパイルされたファイルの読み込み
      • app/views/layouts/_head.html.erb
        • <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
      • webpack-dev-serverを立ち上げておくことで、ファイルの変更の度にコンソールから$ bin/webpackを実行しなくても自動でトランスパイルが実行
  • Reactの導入
    • Reactのインストール
      • rails webpacker:install:react
      • bin/webpack
    • Reactコンポーネントの利用
      • app/views/layouts/_head.html.erb
        • <%= javascript_pack_tag 'hello_react', 'data-turbolinks-track': 'reload' %>
      • ReactDOM.renderは2つの引数をとり、1つ目の引数がコンポーネント、2つ目の引数がそのコンポーネントが表示されるDOM要素
    • Reactコンポーネントを自由に表示する
      • react-railsというgemを導入
      • rails generate react:install
        • spring stopしてからやらないとエラーになった
        • 依存するライブラリがインストールされたり、app/javascript/packs/application.jsに新しくreact-railsの設定が追記
      • Helloコンポーネントをapp/javascripts/components/hello_react.jsxに移動
      • ReactDOM.render()はreact-railsが実行してくれるのでコメントアウトして、export default Helloを追記
      • export default Hello
      • app/javascript/packs/application.jsに追記されたreact-railsの設定で、コンポーネントを明示的にimportする必要はありません
      • react-railsが用意したヘルパメソッドに、app/javascripts/components以下に置かれたコンポーネントのファイル名を指定してあげることでインポート
      • app/views/layouts/_head.html.erb
        • hello_reactの行を削除
      • app/views/layouts/application.html.erb
        • <%= react_component("hello_react", name: "React") %>
  • カウンターコンポーネントを作る
    • app/javascript/components/counter.jsx
    • app/views/layouts/application.html.erb
      • <%= react_component("counter") %>
  • フォローボタンのコンポーネントを作る
    • フォローボタンのコンポーネント雛形作成
      • app/views/users/_follow_form.html.erb
        • <%= react_component("follow_button", user: @user.attributes, relationship: current_user.active_relationships.find_by(followed_id: @user.id)&.attributes) %>
      • app/javascript/components/follow_button.jsx
    • コンポーネントから通信する
      • 通信には、jQueryの$.ajaxを利用
      • beforeSendですが、これはCSRFでないことをRailsに教えるための秘密の文字列をリクエストのヘッダに仕込むもの
      • JSONでのリクエストに対応 (ここら辺使い勝手の良さを感じる)
        • app/controllers/relationships_controller.rb
          • def create
            • @relationship = current_user.follow(@user)
            • respond_to do |format|
              • format.json { render json: @relationship }
          • def destroy
            • respond_to do |format|
      • レスポンスのJSONは自動的にJavaScriptのオブジェクトとなり、thenで取得できます
        • .then((response) => {
          • const relationship = response
          • this.setState({ relationship })
    • チャタリングを防止する
      • リクエスト中は、ボタンの操作を行えないように、stateにリクエスト中のフラグを用意
      • app/javascript/components/follow_button.jsx
        • constructor(props) {
          • this.state = {
            • loading: false,
        • follow = () => { // unfollowも同じ
          • loading: true
          • }).then((response) => {
            • loading: false,
        • <\button className={ className } onClick={ this.handleClickFollowButton } disabled={ this.state.loading }>
    • ボタンの見た目を良くする
      • yarn add classnames
        • classnamesというモジュールを導入して、状態によるクラス名の変更を簡単にしましょう
  • Reduxの紹介
    • Reduxとは
    • 準備
      • yarn add redux react-redux
    • Reduxでカウンターを作成する
      • Action
      • ActionCreator
      • Reducer
      • Store
      • ContainerComponent
      • Component
    • Storeとコンポーネントを接続する
      • Storeを渡すのはContainerComponentではなく普通のComponentがいい
  • 最後に
    • 本章のまとめ
      • webpackergemを利用することで、簡単にReactを利用した開発を行える
      • JavaScriptは進化し続けていて、最新の記法で記述したJavaScriptをブラウザが理解できる形式に変換するためにトランスパイラを利用する ― JavaScriptの最新の記法は謎めいているが、慣れると非常に協力である
      • Reactを利用すると、HTMLとJSをコンポーネントという単位でまとめるためて記述することができる
      • Reactは渡されるpropsの変化や内部のstateが更新される度にrenderを呼び出し、propsやstateに応じたHTMLを返す
      • JavaScriptからAjax通信を行う場合は、CSRFトークンをリクエストに含める必要がある
      • ReactコンポーネントのHTMLのクラスを条件によって変えたい場合は、classnamesを利用する
      • Reduxは登場人物(ファイル)が多いだけで、各登場人物の役割は単純である
      • Reduxを利用するとstateがStoreで一元管理されるので、状態の見通しが良くなる
      • Reduxは必ず利用する必要はなく、コンポーネントが複雑なstateを持ち、それらが他のコンポーネントにも影響を与える場合に利用を検討すべき