はじめに
デベロッパーたちのバイブル
↓↓↓↓
こちらを参考にさせていただきました。
開発プロセスの図解 (vol.55)
DRY原則とは何か (vol.49)
Don't Reqeat Yourself 繰り返しを避けること
- すべての知識はシステム内において、単一、かつ明確な、そして信頼できる表現になっていなければならない
- 信頼性の高いソフトウェアを開発して、開発そのものを簡単に理解したりメンテナンスできるようにする唯一の方法は、DRY原則に従うこと
- 現在の方法がDRY原則に反していることに気づくセンス
- 現在の方法をDRY原則に適用させるための技術基盤(または知識基盤)
- Railsでは規約に沿って作ればRailsが自動的に解釈して処理する
- ときにはあてて規約違反を犯す
- 規約に沿うために時間をかけるよりもあえて逸脱してしまったほうが楽になることもある
- 「アジャイル開発」ではなく「アジャイルな開発」を目指す
- Agileとは日本語で「俊敏な、敏捷な」
- Railsなら、ジェネレータやプラグインを有効に活用することで早く動くものが作れる
Railsの批判的な意見(https://techracho.bpsinc.jp/hachi8833/2019_01_25/68846 はてブコメント)
- フルスタックWAFよりもクラウドプラットフォームのサポートとマイクロサービス化の柔軟性のほうが重要というトレンドは5年前くらいから明らかだったと思うし自分がrailsを捨てたのもその時期
- 確かに世の流れがサーバーサイドはマイクロサービスだったりで、JSONやgRPCを喋れればとりあえずOKみたいな感じで、フルスタックなフレームワークはいらなくなってきつつあるかもしれない。
- つい三、四年前はモテモテだったのに。それだけフロントエンド周りが進化したってことだろうな。
Yahoo!オークション(2009年時点) 構築・運用ノウハウ大公開 (vol.53)
- シンプルな設計、フルAPI化、冗長化
- 最初の設計思想を変わらずに運用を続けている
- ビジネスロジックはその殆どがC++言語
- オブジェクト指向言語の特徴である再利用可能なコーディングが開発効率を高めることも理由としてあげられるが、
- 何よりもお客様からのアクション1つ1つをイベントとしてとらえて、それに従って高速にリアルタイムにhそりを行うのにC++は最も適している
- アメリカでオークションシステムが作られた
- 昔からあるよく知られた技術だけを使って構築されている
最小構成から考える、システムの基本構成
- 最初は1台のサーバーでWebサーバとRDBMSを動かしサービスを提供する方法
- そして、極力、サーバー台数を減らし、コストをかけない
ヤフオクの実際の構成
- ロードバランサを複数台もち、それえらをDNSラウンドロビンで回す
機能の細分化と各機能の最適化
- 何よりもまず、システムが提供する機能単位でサーバの分割を行った
- 機能の細分化によって増強するサーバの台数が抑えられる
Webページの特徴から細分化
- 1つのHTMLファイルはそれぞれ特徴が異なることに目を向ける
- HTMLを返すサーバと画像を返すサーバ(imageサーバ)を分離する
WHERE id=xxxだけなRDBMSは不要
- 1つのオークションに対し1つのファイルを作り、そこにデータを保存する方法
- ファイルの場合、処理に介在するのはOSとハードウェアだけ
- RDBMSの場合、それに加えてRDBMSも処理に介在することになる
統計情報用には別途、RDBMSを
- ファイルに保存していおいて統計情報が欲しくなったときにRDBMSを作る
Webサービス「即日」開発 (vol.54)
自分が「欲しい」サービスから
- 最初は自分のために自分で作る
「道具」を活用する
- 思いついたことを付箋に書いて壁に貼る
アンテナを張る
- Git、海外ブログ、ソーシャルブックマークサービスなどから
アイディアの作り方
アイデアは組み合わせて作る
- アイデアとは既存の要素の新しい組み合わせ以外のなにものでもない
アイデアは難しいことが可能になるときに生まれる
- Webサービスにおいて、アイデアの実現方法まで浮かばないと成り立たない
例)YourAVHost
- 「ブログ検索エンジンで、某ファイル共有サイトへリンクを張っているエントリをピックアップし、その中のテキストがAV女優の名前とマッチした場合、その女優と関連のあるファイルとみなす
アイデアは、シャワーを浴びているときに振ってくる
- リラックスしている瞬間にデてくる
設計
- 目的は仕様書を作ることではない
- 仕様書はあくまで補助
ノートだけでも設計はできる
- UMLなどをソフトウェアで使うのは大規模開発のみ!
- ノートと3色ボールペンとシャーペンのみ
- 課題管理(Issue Tracking)もノートで
- 紙やホワイトボートの活用はXPプログラミングやアジャイル開発に通ずる
抑えておきたい設計項目
ユースケース・シナリオ定義
- ユーザ側からみた、システムに対する機能を完結に図示したもの
- その機能ごとにユーザがシステムをどのように使うかを記述したもの
- 制作のスケジュール管理という面でも良い指標になる
リスク分析
- 「技術リスク」:実現するために現在世の中に存在し利用可能な技術か
- 「スキルリスク」:自分や共同開発者のスキル
- 初期の段階で、どのようなリスクがあるか洗い出しておく
例)Kutter
- 「難しいところ」から手を出して検証していく
- Twitterの検索サービスで出力されているフィードを情報の入力源としているが、フィードだけで欲しい情報が得られるかどうかという技術リスクが存在した
- フィードの内容を細かく調査をしたり、実際にパースする簡単なスクリプトをつくった
- 早い段階で難しいリスクを検証することで、制作のめどがたちやくすなる
UI/画面設計
- サイトの画面イメージを早いうちから持っておくと、サービスが作りやすくなる
- 似た機能を持つサービスを参考にして、ノートへラフな画面のスケッチを描く
- また「ここにはどんな情報がのるか」といった事柄もセント文字で表しておくと、のちほどバックエンドの実装に役に立つ
DB設計
- テーブル名・カラム名の単純な列挙をノートに書き込む
- ER図をつくる
- ノートに書きながら考え、いつでも参照できるようにし、変化に柔軟な状態にする
URI設計
- どういったURLにアクセスをすればこういう情報が見れる、もしくは投稿できるといったことを予め考えておく
- RESTの概念を参考にしておくとURLがきれになる
API設計
- 内部で使用するオリジナルライブラリを外部からどのように扱うか
- 「テスト」をしながら設計を進める
- テストを描くことによってAPIの利用シーンを想定し、同時にそのAPIが望むとおり動作するかのテストを自動的に行うことができる
すべてを書く必要はない
- 必要な事柄のみノートで整理し、残りの点は実装しながら意識をしてみる
開発
バックエンドの実装
例) Kutter
- Webアプリもしくは情報を収集するクローラーの場合を考える
機能と構成
機能
- Web上で「食べた」を含んだつぶやきを一覧で見る
ことができる - 「何を食べたか」に近いキーワードのタグクラウド を見ることができる
- タグ別につぶやき一覧を見ることができる
構成
コマンドラインインタフェース(CLI)のスクリプトがcronで定期的に実行されて
データを登録、Webアプリがその表示を行うというもの
- ❶TwitterSearchAPIで「食べた」を検索し、「Atom」形式で出力させる
- ❷AtomフィードをCLIスクリプトが取得
- ❸パースを行いユーザ情報やつぶやいた内容などを 含んだ「Tweet」オブジェクトを作成する
- ❹DBのユーザ情報を挿入もしくは更新
- ❺DBにつぶやきの内容を挿入
- ❻Webアプリ側でDBの内容を読み取り表示する
フレームワークの選定
- モデル・ビュー・コントローラを切り離すことに習慣化する
- 全体のコード量が減る
- プラグイン(ミドルウェア)などを使うと複雑な処理が簡単になる
MVCを使う上でのポリシー
- モデルによるロジックの切り離し
- ビューによるテンプレート処理
- コントローラによるディスパッチ
コントローラにロジックを書きすぎない
- ロジックはモデルもしくは「API」と名付けいている層に記述する
- そうするとCLIからの利用もできる
- WAFを経由しなくともテスト可能になる
設計を実装に活かす技術 (vol.55)
- アジャイルとウォーターフォールの良いとこどりで開発効率アップ
- 当たり前で地味なことを、当たり前に地味に実装する
重複した作業
- 前フェーズで作成されたドキュメントに同じ情報が存在しているにもかかわらず、実装に向けて設計を詳細化していく段階において、別のドキュメントを用意し、重複した情報を含む別のドキュメントを記述してしまっている
- 前フェーズで作成したドキュメントの存在が伝わっていないことにより、後フェーズの人が同一の情報を作成してしまうといったこともある
- 設計時の情報の重複は、作業の重複だけでなく、メンテナンスの労力の増加や変更漏れなどの、本来必要のない無駄な作業が発生する要因となる
設計と実装の乖離
- 多くの開発現場では、業務知識に精通した人が、上流フェーズ(要件定義、外部設計)を担当する
- 実装技術に長けた人が下流フェーズ(詳細設計や実装・テスト)を担当する
- なんだかんだ言ってもやっぱりウォーターフォール・モデルが標準
- 各フェーズで求められる知識やスキルが異なる
- 専門性をもたせたほうが特価した人材を育成しやすい
- 各フェーズ間の請負単価が異なるので同一メンバーをアサインできない
変更対処の想定がない
- 多くの開発現場において設計者自身が要求は変化しないことを前提として設計を行ってしまっているのが実情
- 要求は変化するもの。まずはこれを大前提として認識しなければならない。
- ユーザはシステムのプロフェッショナルでないことがほとんどなので、システムへの要求をそれないに口にはするものの、本当にできあがったシステムを想定して要求を出せる人は数少ない
開発プロセスは効率を上げるものか?
- 計画駆動形手法とアジャイル手法
- ソフトウェア開発プロジェクトは非常に複雑な多様性を持つ状況下で実施されるものであり、ある特定の開発プロセスを採用すればすべてが解決するというものではない
- 各種開発プロセスのメリット・デメリットを把握し、プロジェクトの性質や自社の状況に合わせる必要がある
- 各プロセスで採用されている手法の中で有効なものを組み合わせ、利用していくことが大切
計画駆動形手法
メリット
- 計画に対するコミットメントがユーザと開発会社にわかりやすく、契約がシンプルになる
- 計画とのずれがモニタリングできるため、リスク予測が行いやすい
- フェーズごとに必要なスキルセットが異なるため、人的リソースを確保しやすい。複数のスキルを持つスーパーマンが必要ない
デメリット
- #遅く可能性を重視するあまり、管理工数が肥大化する
- フェーズ間が分析されることでコミュニケーションロスや設計と実装の乖離が発生しやすくなる
アジャイル手法
メリット
- 動作する実物を短いサイクルでユーザに提示しながら進めるため、ユーザにとって本当に必要な仕様を引き出しやすい
- 絶えず優先順位が変わるような、予測が立ちにくい場面で対応しやすい
デメリット
- いつも密なコミュニケーションが取れることが前提。
- 大枠での予算内で必達目標に到達できるかどうか計画が立てにくく、見積もりもしにくい
- 設計から実装、テストまで一通り、比較的にスキルの高い人材が必要
- ユーザの拘束時間が長くなることが受け入れられない
- 金額とコミットメントラインを提示しにくいため、契約を締結しにくい
良いとこどりしたい
ソフトウェア開発とは
- 目的は、原則的には決められた期間内に決められた金額でユーザが求める価値を提供すること
- 保守フェーズではソフトウェアライフサイクルの6〜8割ものコストがかかる
- 保守フェーズを含めたソフトウェアライフサイクル全体を通じの開発効率を丈mることは、ソフトウェアの価値そのものを大きく高めることになる
- 初期段階で必要な事項を適切に行うことでソフトウェアの価値がほぼ決まる
開発効率を上げるために知るべきこと(vol.55)
- フェーズとフェーズをしっかりつなぐ
- ユーザの満足度を高めつつ、要求変化による開発フェーズ全体への影響を最小限にする
- 変更が発生したときの影響を少なくする
DRY
- ドキュメントの種類を限定し、フェーズを追うごとに詳細化していく
- 設計フェーズにおいても、重複した情報を記載するドキュメントが作成される可能性が高くなる
- 追記方式によりそれを防ぐ
案件の最適化
- 画一的な方法は、効率を犠牲にする可能性がある
- プロジェクトの要件に合わせて手法や決まりごとにライトチューニングを加える
- 自分・自社の開発フェーズ全体を見た上で、採用するメリット、デメリットのトレードオフを考えてみてから利用する
設計と実装の乖離を防ぐ
自動生成ツールの活用
- 設計成果物からの自動生成は、品質・効率・乖離防止の面でかなり有効
- そもそも、1つ1つを人が実装するわけではないので乖離は発生し得ない
完全な画面モック
- 設計段階から最終成果物と同等のモックが存在していることで、実装者が設計を誤認する確率をかなり抑えられる
完全なデータ
- 完全なモック同様、完全なデータが存在することでデータ設計者の意図が実装者に伝わる
トレーニングの実施
- 実装前に2〜3日勉強会の名目で設計者による実装者のトレーニングを行う
- 設計意図を乖離なく伝えるうえで高い効果が期待できる
最小で最適化されたドキュメント
- 実装アーキテクチャにあった設計成果物としてのドキュメント
レビュー
- 設計者と実装者の相互レビュー
- (疑問) 設計者=実装者の場合はどうしよう?
設計から実装までの流れ
- 要件定義・設計・実装・テスト はすべての設計手法に共通する
- それぞれのフェーズには明確な目的がある
- 後続するフェーズを無視してそのフェーズの目的にのみ注力すると、後フェーズにおいて必要となる成果物の漏れや情報の二重化などが発生し、無駄な作業の増加につながる
- フェーズにより参画するメンバーの入れ替えが多く発生する場合は、コミュニケーションコストの増加というリスクも孕んでいる
- 開発フェーズ全体を俯瞰した上で効率よく進めるには、要件から設計、設計から実装、実装からテスト、それぞれのフェーズ間のギャップをいかに埋めるかが重要となる
基本設計編 (vol.55)
- くまなく要求を引き出し、グランドデザインを描く
- ユーザ要求をもとにして、具体的に何を作るかを定義し、定義付けたものを開発することをユーザと合意するフェーズ
- 実際に行うことは、ユーザ(自分)と対話しながら、画面と画面遷移、そこから行われる処理とデータ構造を定義する
- 要するに、ソフトウェアの仕様の決定を行うフェーズ
- またの名を外部設計
目的とゴール
- ユーザの要求をくまなく引き出し、ソフトウェアの仕様として定義
- 「何を作るか」を完全に理解できることがこのフェーズのゴール
進め方
- ドキュメントフォーマット定義に始まり、業務単位でスパイラルに仕様を固めていく
- 最後に仕様のウォークスルー会をもって全体レビューを行うことで終了
ドキュメントフォーマット定義
- 設計は「仕様として定義したものを実装者が確実に実装できるようにすること」
- 「作成しようとしている仕様書・設計書が、実装アーキテクチャにあったあったものである」ことが必須になる
- フォーマットひとつの定義を変えるだけで様々な効果を得ることができる
実装アーキテクチャにあった設計ドキュメントのフォーマットが定義されることの効果
- 実装のしやすさが向上し、効率が上がる
- 設計者の意図が実装者に伝わりやすくなり、実装ミスが減る
- 実装者と設計者の質疑応答のやりとりを減らす
フォーマットの違いによる実装の違いの実例
リクエストドリブン方式: JavaのStruts, RubyのRails
- 業務単位である画面の間に、設計の単位であるプログラムが挟まれるような形式になる
- 会員詳細アクションを設計するためには、リクエストの送信元となる「会員一覧画面」、HTMLレンダリングの対象となる「会員詳細画面」を把握する必要がある
イベントドリブン方式: JavaのJSFやASP.NET
- 画面とプログラムが一対一にマッピングされる
- プログラム設計を行う際に把握する画面は1つで済む
業務単位でスパイラルに進める
- 基本設計の中で最も重要な業務が仕様の抽出
- ソフトウェアは形のないもの、実物を触って見せながら要件を出し切る
- 実際に業務をイメージしながら触れてもらうことで、要求と成果物に乖離がないことを確かめる
- 画面のモックアップを使って確認する
業務単位でのレビュー
- ユーザはシステムより業務をイメージしており、その業務の中でどのようにシステムを使うかを考えている
- 1つの業務でA,B,Cという3つの機能を使用するにもかかわらず、それらをバラバラにみせられると自分が実際に業務で使用することをイメージしにくいため、要求を出しにくい
- 業務単位でレビューを行うことで、要求を引き出しやすくなる
画面の実物
- ユーザがシステムの実物を想像しやすいように基本設計段階で「完全な画面」を作り込んでおく
- 完全な画面は実装者にも成果物のイメージが伝わり実装ミスを抑えられる
ドキュメント作成時のポイント
- 仕様を確認するために作成するドキュメントは、おもに仕様のレビューで使用するもの
- 「画面定義書」、「処理定義書」、「画面の実物」
画面定義書
- 押さえるべき仕様は、画面の各項目の入出力の仕様(項目名、バリデーション、フォーマット、発生イベント)
処理定義書
- 画面定義書のイベントごとに記述する
- イベント発生時にシステムが行う処理を記述する
- 実装に依存した記述を避け、仕様にフォーカスした記述を行う
- 事前条件、処理概要、事後条件を簡潔な文章で記述する
- 処理概要には、何の処理を行うのかと、エラー条件がある場合はエラー条件とエラー時の処理内容を記述する
画面の実物
- ユーザが使い慣れているプラットフォームに似たものを作る
レビューと成果物作成を兼ねる
- 全体の整合性を取りながら設計を進めるにはレビューが欠かせない
- 基本設計フェーズでは仕様とデータ構造を中心に定義していくので、それぞれ定義されている機能がどのテーブルに対してどのような操作を行うのかを、機能仕様書とテーブル設計書を順にレビューしていきながら、CRUD(Create Read Update Delete)図に記載していく
要件フェーズとの関係
- 要件定義フェーズ: ソフトウェアが何を満たすか(What)
- 設計フェーズ: 要件定義をどのように実現するか(how)
- 要件定義の成果物と基本設計ので作成する成果物には依存関係がある
- そのため、それらの依存関係を意識しないと、内容の重複したドキュメントや、要件定義の内容と異なる成果物を作成してしまう恐れがある
詳細設計フェーズとの関係
- 詳細設計の成果物は、基本設計で作成したユーザ向けの内容を、実装者向けの実装を考慮した内容へと進化させたものにあんる
- 詳細設計フェーズで新たに作成する成果物もあるが、詳細機能使用書は、基本設計フェーズで作成した画面定義書、処理定義書をものに実装可能な形式へと進化させたもの
- 処理が複雑な場合はクラス図やシーケンス図などのドキュメントを追記する
- このように前フェーズの成果物に追記する形式をとることで、成果物間での情報の重複、無駄な成果物の作成を防ぐことが出来る
詳細設計
- 基本設計で定義された内容を、アーキテクチャの決定や使用の詳細化を行うことで、どうやって作るのかを定義するフェーズ
- ここでの準備が不十分のままに実装フェーズを開始してしまうと、乖離だけの問題にとどまらず、実装のばらつきや共通化が上手く行えていないことによる無駄な実装が発生し、深刻な効率低下を引き起こす
進め方
- 基本設計ドキュメントをもとに詳細設計ドキュメント作成、レビュー、実装、ドキュメントのフォーマットを定義
- 記載するべき情報、必要のない情報を精査する
- 機能単位でスパイラルに設計を行い、すべての機能の設計完了をもって詳細設計は終了
ドキュメントの詳細化
- 基本設計で作成された処理定義書や画面定義書を実装者が実装に利用するドキュメントに必要な情報を追記する
- 重複があればドキュメントを統合する
詳細化のポイント
- 実装者が実装できる文章に変える
- システムエラーの処理方法やトランザクション協会など、アーキテクチャ設計書に実装の共通ルールとしてまとめて記載しておくことで、処理定義書には「仕様を実装する」ことにのみフォーカスしてドキュメントの詳細化を行うことができ、何度も同じことを記述する手間を省くことが可能
実装
- 設計者と実装者が一緒に1つの設計書をPC上で見ながら、順を追っての説明を実装前に必ず行う
- 一度説明すると、設計書の記述のミスや説明が足りない箇所などがその場で質問で上がってきやすく、その場で設計書を修正できる
Clツールのすすめ
- 統合テストの自動化をする
- リポジトリに対してソースコードをチェックインしたタイミングでビルドとユニットテストを自動実行
ここでも顧客レビュー
ユーザの状況変化を汲み取る
- 実装成果物に対しても、基本設計を進める際に行ったような業務単位でユーザレビューを入れ、前提とした仕様に問題ないかという確認をとっておく
ユーザの関心を保ち、安心してもらう
- 実装フェーズは設計フェーズでのユーザとの接触回数が極端に少なくなる
- リリース出来る状態を保ち、順次ユーザレビューを行っていくことで不安を取り除く
ドキュメントの最終Fix
- 実装フェーズに入ってからも設計書をメンテンナンスする
- 実装者からの質問を記録するなど
- 追記せずに、わざわざ別のドキュメントを仕立てたりしない
- 追記内容はすでにある該当文書に加えていくことが最適
Webサイト表示を高速化する(vol.59)
Webサイトが表示されるまでの流れ
-
- リクエストを受けてサーバサイドが処理する時間(サーバサイド)
-
- レスポンスを返却する通信時間(通信時間)
-
- レスポンス情報を解読し、表示するために必要な情報を構築する時間(フロントエンド)
-
1にかかる時間がパフォーマンスチューニングの対象になることが多い
-
2,3のフロントエンドの処理に8割もの時間を費やしていることが分かった(Yahoo!inc.の調査結果)
Webサイトの高速化とは?
- 「8割」の時間を短縮する
- WebサイトのあるWebページの表示に5秒かかっている場合、その1秒がサーバサイトの処理、4秒がフロントエンドの処理ということになる