AWS DevDay Tokyo 2019 - Day 2 セミナーメモ

# AWS DevDay Tokyo 2019 - Day 2

2019/10/3 ~　10/4

https://aws.amazon.com/jp/about-aws/events/2019/devday/

2日目（10/4）：終日、45分毎の個別セッション。たくさん見たいセッションがあって迷ったが、サーバレス関連がやっぱり今後盛り上がりそうなことを実感。

あとはAmplifyのように、技術者にとっての無駄な手間を少なくし、本当にフォーカスすべき作業に注力できる環境を作ってくれる技術は活用しないと生きていけないと思った。

## オープンソースコミュニティで加速するサーバレスの未来
* Sperker:堀家　隆宏氏（Servlerless Operation, Inc.）
* テーマ：クラウドの世界にいながら、OSCに参加することの意味、どんなことをもたらすか
* Serverless Framework
    * Lambdaを中心にAPI Gateway、DynamoDBなど必要なリソースを一括管理する
* 関わるOSS
    * Serverless Framework
        * プラグインシステム：コミュニティでのプラグイン開発が活発
        * Serverless Step Functions
            * Cloud Formationに比べて記述量が少なくて済む
        * Serverless API Gateway Service Proxies
            * API GatewayからLambdaを経由せずにS3やDynamDBにつなぐためのプロキシサービス
* OSS活動を継続的に続けるモチベーション
    * オンラインでコードを中心につながるコミュニティ
    * 人気のあるOSSにはスキルがある人が集まる→そういった人からのレビューで格段にスキルアップ
    * 遠くの国のあったことない人から感謝される喜び
    * 英語ができないのは大きな問題ではない
        * 翻訳ツールを使いながら、時間がかかっても文章を組み立てて、それを伝えることが重要
    * OSSと向き合うマインドセット
        * 人気があるOSSは偉くてすごい人だけが作っているのではなく、当たり前に自分の意思が反映される場所
        * 知らない人に感謝される喜び
        * 世界を変えるのは難しいが、周りの環境を少しだけ変えるのはできるんじゃないか
* OSS継続の難しさ
    * とりあえず公開しても反応がなく飽きる
    * 活動自体はめちゃくちゃ地味
* どう打開するか
    * まずはスター1000以上目安によくかかわっている人が複数いる、かつhelp-wantedなどコントリビュータの入り口を作ってくれるプロジェクトで継続的にプルリクを送り続ける
    * 先送りにされている問題をつぶしていく人の存在はめちゃくちゃ重要
    * 継続する人の数はめちゃくちゃ少ない：継続することで信頼され、コミット権を付与してもらえる可能性は高い
    * コミット権をもらう頃にはコミュニティの一員として認識される→自分の見える景色も変わる
    * プルリクを出し続けたプロダクトのプラグインなど付随のOSSプロダクトを出してみる
    * コミュニティの人がフィードバック、宣伝、一緒に開発に参加してくれる→良いサイクルが回り、継続するモチベーションに
* サーバレスの未来とオープンソース
    * Serverless:Cloud2.0
    * Cloud2.0とは？
        * サーバレスで自分たちの責務はコードの部分＝その責務から解放されるには少ないコードが望まれる
        * そしてその多くはマネージドサービスで実現できない部分をコードで補っている
        * サーバレスの狙いはよりコードを少なくし、クラウドのサービスをできるだけ使うこと＝次世代のクラウドの使い方＝Cloud2.0
        * Cloud2.0のキング：拡張性と可用性の高いクラウドサービスの利点を理解し、少ないコードで書ける人
        * ＝＞フルマネージドサービスをうまく利用することで、アプリケーションロジックの責務の多くをクラウドに任せ、よりビジネスバリューを出すための仕事に集中すること
        * コードを書くことは本質的になくなることはない
            * コードを書く視点を変えてみる。単発で納品する仕事のコードに価値があるのか？継続的に何かを解決できるようなことをコードで表現していくほうが良いのでは？
        * クラウドのサービスは日々新しいものがリリース＝新たなものは新たな問題をもたらす＝問題とはチャンスであること
            * OSSで解決できないか？＝OSSで自分の書くコードが多くの人に影響を与えられる
* Serverless days Tokyo:10月22日

## サーバレスで作るモバイルアプリ向けBackend For Frontend
* Sperker:椎名　アマド氏（株式会社Timers）
* モバイルアプリ：家族アプリFamm
    * 古き良きを新しく：次に何が流行るかではなく、人類として昔から未来まで変わらない価値観はなにか？＝＞家族
* 課題解決のための技術導入に関するケーススタディ
* モバイルアプリ開発での課題
    * サーバーはRESTfulなAPIを使いたい
    * クライアント側はUIベース：1つの画面で複数のリソースからデータを取得することもある：できれば１つのAPIコールでやりたい
    * iOS,AndroidでAPI分けたくない
        * 例：1画面で複数APIを呼び成型するのは大変→１つの巨大なAPIに集約
            * iOS,Andoroidで差分が出ないようにメンテするのは大変
        * 様々な制約条件の中で改善を進めるため、コミュニケーションの調整コストが増加
        * 複数OS、バージョンの影響範囲を考慮しつつ、巨大APIをメンテするのは困難
    * サーバAPI複雑化、iOS&Andoroid間で複雑なAPIを扱うビジネスロジックの分散
* 解決策（案）
    * １．自動テストの網羅によりデグレ防止
        * API修正のたびに過去バージョンも考慮した手動テスト実施
    * ２．ネイティブでコード共有
        * Kotlin/NativeなどでiOS&Androidでともに利用できるビジネスロジックをライブラリ化する案
        * 整理が必要なことが多い、コストが高いわりに完全に幸せにならない
            * ノウハウ不足
            * 共通ライブラリ修正時のCIフロー
    * ３．APIに表示ロジックを寄せる
        * APIのほうでUI表示用に文言処理、必要な成型もしてしまい、実際の文字列を返す
        * サーバAPIでテストを充実させていれば品質も担保
        * →片方の解決しかしていない
            * サーバで行うことが増える：i8n対応、日付成型など
            * サーバエンジニアの責務として画面表示という責務が増える
            * ただでさえ現状のAPIがモノリシックなのに、さらに責務範囲が広がってしまう
    * どれも課題が多い　－＞　そこでBFF
* BFFとは
    * One backend per user experience
    * 一つのユーザー体験に一つのバックエンド
    * クライアントとバックエンドの間に挟まるAPI
    * クライアントは直接バックエンドをたたかずにBFFをたたく
    * BFFはクライアントの要件に合わせて最適化される
    * クライアントの種類（デスクトップ、モバイル）毎にBFFがあり、それぞれがバックエンドとつながる
        * BFFはクライアントサイドが管理
            * クライアントサイドが使いやすいようにBFFを管理する
        * バックエンドはバックエンドが管理
        * クライアントごとにUIやAPI要件が様々な場合、クライアントごとに都合のよい（密結合な）API層を用意することで責務の分離
        * 例：NetFlix：デスクトップ、モバイル、TV、Game Console
    * 集約と変換
        * 様々なバックエンドサービスと通信してデータ集約
        * さらにデータをクライアントに適した形に変換
        * クライアントはBFFとだけ通信すれば集約済みのデータが返ってくる：扱いやすい
        * マイクロサービスを多く使うケースで最適
* BFF:Fammの場合
    * マイクロサービスではないが、複数のバックエンドAPIからリソースを取得して集約
    * 文言出し分けなどのUIロジックをBFFに集約することで、iOS&Andoroidの間で分散しているロジックを吸収
        * かつ、バックエンド側ではUIに関する責務を負う必要がない
* BFF導入にあたる取り決め
    * BFF APIはクライアントエンジニアの管轄
    * クライアントエンジニアが管理するなら、インフラ管理はしたくない＝サーバレス
    * サーバレスで実現するための環境整備はサーバサイドエンジニアが行う
        * サーバレスの環境まわりの課題についてはサーバサイドエンジニアがサポート
    * 技術選定：言語
        * TypeScript
            * 他のサーバレス（Lambda）ではGoを使っているが、クライアントエンジニアが使いやすい言語を選定
        * Lambda＋API Gateway + serverless
        * APIGatewayはANYですべてのリクエストを受け付け、Lambdaは1つのExpressアプリケーションで複数エンドポイントをハンドリング
            * API Gateway + Lambdaが増えると管理運用が大変になるため、集約して1つにする形を採用
            * 本来はあまりきれいではないかもしれないが、生産性、管理のしやすさ、今後のエンドポイント数の増加規模を考えても妥当と判断
    * 認可・認証
        * API GatewayのAPIKeyとともにBackendAPI用のトークンもリクエストで渡している
            * つまり現状はBackend APIと密結合
            * 現状マイクロサービスがないので足りているが、今後BFFからマイクロサービスをコールする際に認証の見直しが必要
    * i18n
        * i18n NPNモジュールで特に不都合なし
    * TEST/CI/Deploy
        * テストはJestを利用
        * develop/masterにmergeされたらCircleCI経由でそれぞれデプロイが走る
        * serverless CLIのdeployコマンドがあるのでCIも簡単に構築
* 今後やりたいこと
    * 今後のマイクロサービス化でBFFが複数マイクロサービスと通信できる設計（主に認証認可）
    * 現状BFFは一度インターネットに出て行ってBackend APIと通信しているのでVPC内で完結させるなど速度の最適化をしたい
    * 他の画面についてもBFF化
* 自分のチーム・プロダクトの課題は何なのかを考え、それを解決する判断をする
    * モダンな、トレンドだからなどの安易な理由で導入したら失敗する
    * 課題ドリブンで試行し、技術選定、導入：どれくらいのスパンを見通して課題とするかはそれ自体が永遠の課題

## よくある課題を一気に解決
* AWS Startup SAチーム
    * AWS Startupゼミ
        * 技術的な課題と傾向を把握、「あるある」まとめ
            * どう考えて、どの資料を見ればいいか
* よくある課題１：コンテナのCI/CDちゃんとしたい
    * 本当にしたいことは？
        * 開発速度を上げ、プロダクトの価値を向上させたい
        * テストをちゃんと行い、プロダクトのクオリティを上げたい
        * 自動化しつつも条項の把握やロールバック等のハンドリングを適切にやりたい
    * 思考フロー
        * 手作業でのデプロイと決別
            * パイプライン外での構成変更やデプロイを認めない強い気持ち
                * 今までと変わるので最初は面倒に感じるー遅くなっているわけではないのに遅くなっているように感じたりする
            * 手作業での変更を行わないためにどうすべきかという思考
            * 緊急時は仕方がないこともある
                * ビジネスへの影響を考慮し意思決定することは重要
                * 例外的な対応と認識し、しっかりと帳尻を合わせる

        * リビジョンとデプロイメントを連動させることを考える
            * リビジョン：リビジョン番号、タグ、リリースバージョン
                * Gitのリビジョン番号とコンテナのタグを合わせる：複数コンテナがあればすべて合わせるべき
            * メリット 
                * 本番やステージングなどの環境によらず、一意なコード／コンテナを利用できるようになる
                * ロールバックが容易
            * The Twelve-Factor Appでもベストプラクティスとされている
                * コードベースとアプリケーションの間に、常に1対1の関係を持たせる
        * マネージドサービスを中心にパイプラインを構成する
            * 本来の目的は効率化やクオリティの向上：CI/CD環境自体の管理運用コストをできるだけ抑える
* よくある課題２：ログってどう設計すればいいの
    * ログ解析したいが、垂れ流している状態
    * 本当にしたいことは？
        * サービス/アプリの状況を把握、可視化したい
    * 思考フロー 
        * ログの種類と目的を考えよう
            * アプリのログ、ミドルウェアのログ、OSのログ
            * 利用状況の把握、調査用、監査用件で必要とされるもの
            * 用途に合ったものが出力されているかっ確認
                * 足りない項目はないか？
                * 環境に応じた適切な情報量なのか？
                * 秘匿性が高いものが出力されていないか（ID・PWやメールアドレス）
        * ログの設計を使用
            * ログレベル
                * 用途や緊急度によって適宜ログレベルを設定する
            * 出力先
                * 運用者がすぐに見つけられるところに集約  
                    * /var/log,app/logなど
                    * Cloudwatch logsや、S3など
            * 権限
                * 適切なログの権限なのか
                    * 内容によっては見られてはいけない、変更もされてはいけない
        * アプリケーションにあったフォーマットを考えよう
            * WebServerやAppでどのような種類が出力できるか見直し、必要な項目を入れる
                * デフォルトでは項目が足りないことも多い
* よくある課題３：いい感じの機械学習基盤を作りたい
    * 環境構築が大変、会社で買ったGPUが足りなくなってきた、など
    * 本当にしたいことは？
        * ユーザに価値をとどけつつ運用負荷を減らしたい
        * 俗人化させず、再現性を担保、パフォーマンスも大事
        * ユーザ、エンジニア、データの増加に対応できるスケーラブルな機械学習基盤を作って、プロダクトの継続的な価値向上につなげたい
    * 思考フロー
        * できるだけマネージドサービスを使えないか考える
            * 自分でモデルを作らなくても、学習済みのモデルをAPIで簡単に使える
                * コンピュータビジョン：物体検出、顔認識
                * 音声
                * 自然言語処理
                * チャットポッド
            * 自分でモデルを作る場合でも、マネージドサービスSageMakerを使う
                * 幅広いフレームワーク、インターフェースに対応、インフラ面も強力
        * どこまで自由度を求めるか考える
            * AutoML
                * Amazon Personalize/Forecast
            * Amazon SageMaker
                * ビルトインアルゴリズム
                * トレーニングスクリプトを用意
                    * train.pyの入出力を書き換え
                * 自分のDocker イメージを用意
                    * Bring Your Own Container
        * ワークフローの構築と自動化を考える
            * データだけ用意してビルトインアルゴリズムで定期実行
                * StepFunctions workflow
* よくある課題４：セキュリティを自動化するにはどうすれば
    * セキュリティ、何をどこまでやればよいのか、やったらやったで大変そう
    * セキュリティに不安があるのでレビューしてほしい
    * セキュリティの要件はサービス内容によって変わり、サービス運営者が決めるべき内容
    * 本当にしたいことは？
        * 効率よく過不足なくセキュリティに取り組みたい
        * セキュアなシステムで事業とユーザを守りたい
    * 思考フロー
        * まずマネージドサービスを使おう
            * マネージドサービスで自分の責任範囲を小さくする
                * マネージド度の高いサービスを使うことで、クラウド事業者の責務を増やす＝自分の責務を減らす
            * セキュリティ系マネージドサービスで低コストに高機能を得る
                * 監視、検知：GuardDuty,CloudTrail,AWS Config
                * 集約・把握：Security Hub
                * 対応：CloudWatch Event
        * キャッチすべきアラートやイベントを決める
            * 何を検知できるのか、発生時にどう影響があるかを考える
        * イベントに対するレスポンスを考える
            * 各種監視・検知サービスはCloudWatchEventsに集約できる
                * →管理者への通知やLambdaやStep Fucntionを使って対応実施

## AWS活用で進む地方／中小企業のゲームチェンジ
* Sperker：立花 拓也 氏（株式会社ヘプタゴン）
* 東北を拠点に地方中小企業へのITサービス展開（主にAWS活用）
    * IT予算の概念がないことも：レンタルサーバ代の月1万円しかない、とか
    * IT関連の知識は相対的に低い
* クラウドネイティブな世界とコミュニティファーストな世界：人間力
    * 人にしかできないことが求められる世界で、組織を超えたつながり、他者とのつながりによるイノベーション
* WEB案件
    * レンタルサーバなどからのリフトが多い
    * 既存環境に何らかの問題があり相談されるケースが多い
    * 割り切ってシングル構成も多い

## 自然言語処理の開発現場でのAWS活用術
* Speaker: 山田 育矢 氏 、 島岡 聖世 氏 （株式会社Studio Ousia）

* QA Engine
    * ヘルプデスクや社内の問い合わせ業務の自動化、効率化支援プロダクト
    * WEB画面上で機械学習モデル構築などが行える
    * チャットボットへモデルを連携し、問い合わせに利用
* https://git.io/JeZGL

* SageMaker導入
    * レガシーシステムの課題  
        * 周縁的な処理によるコードの肥大化
            * 本質的な処理は学習と推論
            * 周辺的な処理として、学習ジョブ起動、状態確認、推論インスタンス起動、更新、モニタリング、スケーリング、etc...
            * 本質的な処理以外にジョブやリソースのマネジメントに必要なコードが肥大化してしまった
        * コンポーネント間の依存関係
            * コントロールサーバ、機械学習モジュール、クライアントAPIの３つのコンポーネントが、共通モジュールを利用するなどの依存関係を持ってしまった
        * ＝＞機械学習の改良が困難に
    * SageMakerで解決できないか？
        * 機械学習のフルマネージメントサービス
            * 機械学習のワークフロー全体をAWSのAPIやコンソールで管理可能
        * 魅力
            * 周辺的な処理を任せられる
                * 学習・推論という本質的な処理にフォーカスできる
            * 機械学習処理をDockerイメージで作成できる
                * 任意の言語、フレームワークを利用可能
                * SageMakerから見れば、モデルは要件を満たすブラックボックス
    * どのように変わったか？
        * レガシー時代は依存していた3つのコンポーネントを別々のリポジトリで管理
            * コンポーネント間の依存関係はSageMakerのインターフェースに置き換え（REST API呼び出し）
        * コードの量が減った：40%減
            * 周辺的な処理がSageMakerに吸収された
        * 学習時間の短縮
        * 性能向上
* 周辺的な処理をプラットフォームに任せれば、本質的な仕事に専念できるようになる
* コンポーネント同士の依存関係をなくせば、チームの共同作業は効率的になる

## Amplify Frameworkの挙動を解説する
* Speaker:塚田 朗弘 氏（アマゾン ウェブ サービス ジャパン株式会社）

* 目的
    * ライブラリとしてやっていることを知る
    * 「そういうことを気にしなくてよい」ことを実感する
* なぜAmplifyが必要なのか？
    * 一般的なWEB,モバイルアプリの構成要素
        * サーバサイドやデータベースでの管理、運用やログ収集して可視化、クライアントへのプッシュ通知、クライアントイベント収集（マーケティングとしてのユーザ動向分析など）、分析業務、他システムとの連携
            * など、多岐にわたる要素を気にしないといけない
    * アプリ開発者がやりたいことは何？＝ユーザに価値を届けたい
* AWS Amplify
    * 中身
        * Amplify CLI
        * Amplify Framework
        * Amplify Console
    * Amplify CLI
        * やりたいことから直感的に、やりたいことだけを意識して構築できる
            * 各サービスの詳細をしらなくても、やりたいことからサーバレスなバックエンドを構築してくれる
                * アプリケーション開発者は本当に必要な開発だけに集中できる
                * バックエンドの構築はシンプルなコマンドで実行できる
            * ＝Amplifyの仕組みとか知らなくても大丈夫
        * Amplify CLIとは？
            * TypeScriptで実装されたnpmパッケージ
            * amplify add ...
                * 使えるサービスが追加される　api,auth,analytics, etc...
            * amplify serve:ローカルでサーバ立てて動かすのがすごく簡単に
            * amplify codegen:GraphQLスキーマオブジェクトを生成
            * amplify env <add|pull>:dev,prodなどの複数環境を管理する
    * Amplify Framework
        * クラウドに接続されたUI Componentやライブラリを使いフロントエンドアプリを構築
        * Viewコンポーネント
            * 認証機能を提供するVueコンポーネントの例
                * <amplify-authenticator />：ユーザ認証UIを作成
    * Developer-Friendlyな開発が可能
* はじめかた
    * 公式サイトのチュートリアル
    * AWS LOFT

## レガシーコードからの脱却
* Sperker:吉羽 龍太郎 氏（株式会社アトラクタ）
* 書籍「レガシーコードからの脱却」（https://www.oreilly.co.jp/books/9784873118864/ ）
* レガシーコードとは？
    * テストのないコード：テストがなければコードが良くなっているか悪くなっているかわからない
    * 保守または拡張が困難なコード：コードベースだけではなく、プロジェクト全体
        * ＝定義は様々
    * 本セッションでの定義
        * 理由は問わず修正、拡張、作業が難しいコード＝保守に多額のお金がかかる
        * ※同じ用語を使っていても、中身に認識の相違があることが多い
            * 議論の時は共通認識は何かを確認すべき
    * 品質は重要ではなく、ソフトウェアが何をするかを重要視したためにたくさんのレガシーコードが生み出されたと考えられる
* 使われるソフトウェア
    * 変更が必要になる：必要な変更をすべて予測するのは無理
        * よって、変更可能となるように書くべき
        * 使うかもしれない、で作るときりがない
        * 必要になったときに対応できるエンジニアリングプラクティスを身に着ける
    * そもそもソフトウェアの保有コストを下げたい：メンテナンスコストを下げたい
* リリース後のバグ修正にはとてつもない時間がかかる
    * 「ソフトウェアの成功と失敗」によると、開発者の時間の半分以上が過去にやった仕事の手直し
    * コードを扱いやすくして保守コストを下げたい：開発方法に目を向けなければいけない
* ウオーターフォール：最初から正しい計画が立てられるなら正しく作れるけど・・・
* ソフトウェアが生み出す成果を決める要素

    * 問題設定力
        * そもそもどういった問題を解決しようとしているのか
    * 開発力
        * 知識やアーキテクチャ設計力、
    * チーム力
        * プロセス習熟、心理的安全性、、、
    * それぞれの総合力で成果が生まれる
* レガシーコードを作らない9つのプラクティス
    * １．やり方より先に目的、理由、だれのためかを伝える
    * ２．小さなバッチで作る
    * ３．継続的に統合する
    * ４．協力しあう
    * ５．CLEANコードを作る
    * ６．まずテストを書く
    * ７．テストでふるまいを例示する
    * ８．設計は最後に行う
    * ９．レガシーコードをリファクタリングする
        * ScrumとXPからプラクティスを抽出
* １．やり方より先に目的、理由、だれのためかを伝える
    * プロダクトオーナー：Whatを担当する
    * 開発エンジニア：Howを担当する
        * WhatとHowを分離する
            * やり方（How)は開発者の領域
                * やり方を明示されると選択や交渉の余地が減る
                * 結果として手続きてきなコードになりがち
        * 双方が創造的に協調＝無駄な時間や機能が減る
        * まずコンテキストを共有・理解すること
    * ユーザーストーリー
        * 会話の材料となるもの（仕様書ではない）
        * 会話によってソフトウェアを作るための理解を深める
        * 知識は詳細なドキュメントではなく、コード（テストも含む）にまとめるべき
        * ストーリーが限定的であることで、テスト可能になる（受け入れ基準と自動化）
            * 実例による振る舞いのテストが可能に
        * シンプルに初めて、追加は後で行う（＝＞２．小さなバッチで作る）
            * 漸進的に進めることで、良い設計が浮かび上がってくる
* ２．小さなバッチで作る
    * タイムボックスとスコープボックス
        * タイムボックス：固定の時間の中でタスクに取り組む
        * スコープボックス：ストーリーやタスクなどの作業単位で終わらせる（時間は重視しない）
            * 作業単位が均一で小さい場合に選択
            * カンバン
    * 長い期間で大きなうそをつくのではなく、短いイテレーションの中で小さなうそをつく
* QCDSの何を調整すればいいのか？
    * ウオーターフォールではどれも調整できない
    * スコープと時間を柔軟に考える（特にスコープ）
        * 品質を満たせなければ意味がない：品質を満たせる作業量とする：スコープで調整
    * 人月の神話
        * 人を追加するとやり取りが増えて速度が落ちる
    * 品質を犠牲にすると、後からつらくなる
    * スコープを調整し、価値ある機能から順番に作る
        * バックログ化
* ケイデンス、リソース効率、プロセス効率
    * ケイデンス（リズム）が長くなると、リソース効率化を目指しやすい
        * 同時に着すするものが増える、タスク切り替えが増える
        * 役割分担が増える
        * 最後にテストフェーズや統合フェーズが増える
    * ケイデンスを短くすると、プロセス効率が上がる
        * 同時に着手するものを減らす必要（いわゆる1個流し）
    * プロセス内の作業の量を減らすと、システムが安定する
    * ※モブプログラミング：究極の1個流し
* ソフトウェアの評価
    * 顧客にとって価値あるものに基づいて評価すべき：どんな効率で、どれだけ頑張ったかは関係ない
        * 価値は完成して初めて価値になる
        * 価値実現までの時間が期待した通りか？
        * 部分最適化を避ける
* フィードバックサイクル
    * 小さなバッチのほうがフィードバックが増える
        * スプリントレビュー、レトロスペクティブ
        * 顧客やPOと同席し、フィードバックの回数を増やす
        * ビルドを高速化する
    * フィードバックへの対応をサポートする文化が必要
        * 今やっていることとフィードバックで戻ってきたこととどちらが優先かを考える文化
* 良いコードとは？よくないコードとは？
    * 何が良いコードで何が悪いコードかの認識を一致させる
        * 良くない例をチームで理解し、避ける必要がある
    * 一方で、従うべきガイドラインも必要
    * CLEANコード
        * 凝集性、疎結合、カプセルか、断定的、非儒町
            * テストのしやすさと密接な関係がある
    * 凝集性
        * それぞれの部品は1つのことだけ扱う
        * クラスが1つの責任に集中する
            * ＝名前を付けられるアイデアや概念になる
            * ※名前重要：具体的な名前がついていないものは怪しい
            * わかりやすいコードは自然言語に近い内容で書かれている
    * 疎結合
        * 密結合のすべてが悪ではない
            * 意図的な結合と不慮の結合
        * 再利用という名目のもとにコードの品質を犠牲にしてはいけない
    * カプセル化
        * インターフェースと実装を切り離す
            * 呼び出し側の観点で機能を設計する
            * 何をやっているかを示す具体的な名前を付けて、どう動くかは隠す
    * 断定的
        * 自分の責任は自分で管理する
        * オブジェクトがフィールドを持つなら自分で責任を持つ
        * ＝振る舞いを配置する場所が依存データがある場所であることを示す
    * 非冗長
        * 同じことを繰り返してはいけない(DRY原則）
        * 意図的に冗長を組み込むことはあるが、あくまで意図的に
    * テストのしやすさが設計や実装の品質の目安