「Application Architecture for .NET」を読んだ - 1部

.NETのエンタープライズアプリケーションアーキテクチャ 第2版 (マイクロソフト公式解説書)

.NETのエンタープライズアプリケーションアーキテクチャ 第2版 (マイクロソフト公式解説書)

古めですが、ここに参考文献が上がっています
matarillo.com: .NETのアプリケーションアーキテクチャ

第一部基礎編のメモ。

TL;DL

アーキテクチャとはシステム開発の利害関係者(ステークホルダー)全体にまたがる共通理解を指す

  • システム開発の利害関係者は、それぞれが異なった要望や関心事を持っている
    • 大まかに分類すると、利用者の領域、ビジネスの領域、そしてシステムの領域となる。それぞれはトレードオフの関係にあることも多いため、アーキテクチャはこれら3つの領域のバランスを取ったものになっていなければならない

1. 現代のアーキテクトとアーキテクチャ

  • アーキテクトは役割
    • ≒ Lead Developer
    • Architect extends Developer
  • アーキテクチャは顧客のためのシステムを構築するもの
    • 明確な答えはないが、見つけ出すことは仕事
    • 良いアーキテクチャ: 変更が困難な決断が全て適正なものであることがわかる
  • 重要な決断を下さなければならないことがアーキテクチャ
    • プロジェクトの出来るだけ早い段階で正しく下さなけばならないもの(先送りにしたいもの)

2. 成功のための設計

  • ソフトウェアプロジェクトの最大の敵はBBM
  • 成功するソフトウェアプロジェクト
    • ビジネスニーズを理解し、そこから上手くいくソリューションを引き出すプロジェクト
  • 上手く設計されたソフトウェア
    • 成功するプロジェクトを背景とし、既存のコードとインフラストラクチャを再利用した上で設計され、利用可能なテクノジと既知のベストプラクティスを踏まえて改良されたソフトウェア
  • ボスは追従者を生み、リーダーは他のリーダーを生む
  • マネージメントチームがリーダーシップを理解していてる + 開発チームがコードの品質について理解している == プロジェクトを成功に導く
  • リファクタリングはプロジェクトに価値を生み出さないけど、行わないと価値が失われる
  • Legacy Code: 側に置いてはいるが、側に置きたくないコード
    • testが書かれていない == Legacy Code
    • 幅広く利用されているため、置き換えるのが難しい
    • これ以上、Legacy Codeを増やさないようにするのが問題
  • 切り離されたブロック(black box) == 境界付けられたcontext

3. ソフトウェアの設計原則

基本的な設計原則
  • 凝集性: 密接に絡み合った責務 - 高いのが理想
    • 単一責任の原則
  • 結合性
    • AクラスBクラスの結合の度合い - 低いのが理想
  • 内蔵型のobject(高凝集)が安定したinterfaceを通じて他のobjectとやり取りする(疎結合)ことを意味する
  • 関心の分離 - AOP
オブジェクト指向設計(OOD)
  • 関連のあるobjectを見つけ出し、相互にやり取りするobjectの結合性を最小限に抑え、コードを再利用する
  • 合成と継承
    • 派生classは親classのコードを継承するだけではなく、contextを警鐘し、そこから親classに対する可視性を手に入れる
    • 合成は防御的
  • 関心の分離
    • 変化する可能性が高い部分を切り出す
    • classが必要でないことがある。関数だけで良いなら、それを使用するだけにする
    • 現実の世界がモデルではなく、イベントを表す、イベントがデータを運ぶもの
開発ベクトルと設計ベクトル
  • SOLID原則
    • 単一責務の原則(SRP)
      • 責務とは変更の理由のこと
      • 限界まで追及するとプロパティだけの貧血classになる危険がある
    • 開放/閉鎖の原則(OCP)
      • 拡張に対して開いている / 修正に対しては閉じたまま
      • composite / interface / generics
    • リスコフの置換原則(LSP)
      • classを作成するとしたら合成の方が安全
      • サブclassをその基底classと置き換えることが出来ないといけない
        • 派生classはその基底classよりも多くのことを要求すべきではなく、それ以下のものを提供すべき
        • class継承のcontextで「特殊な」という表現がされたら注意する
    • インターフェース分離の原則(ISP)
      • クライアントが使用しないinterfaceにクライアントを強制的に依存させてはならない
    • 依存関係逆転の原則(DIP)
      • 上位moduleを下位moduleに依存させるのではなく、両方のmoduleを抽象化に依存させるべき
        • Service Locator
        • Dependency Injection(constructor / setter / interface)
  • coding vector

4. 高品質なソフトウェアの作成

  • テストされていないものは壊れていると思え
  • どのようなシステム、どのようなcontextにおいても単純さは常に長所
  • 依存関係を排除するテスト
    • テストダブル(fakeとmock)
      • fake object: objectの比較的単純なcopy(元のobjectと同じinterfaceを提供する。状態は無くハードコーディングされているケースが多い)
        • やり取りに関心は無い
      • mock object: fake object + 独自の特性を持つobject
  • TDDのテストの最終目的はカバレッジを広げることでは無く、「設計を改善する事」
    • テストは目的では無く、良い設計を実現するための手段
  • applicationのロジックを左右する重要な決断が下される場所(ビジネス層/ドメイン層)で、テストを重点的に行なうべき
  • codeの拡張性
    • 早まった拡張はソフトウェアの諸悪の根源になりかねない(過剰性能)
  • 読み易さは主観的な問題
    • coding以外の事をする十分な時間がない事を承知しているなら、最初から読み易いコードを書くように
  • code comment: codeにおいて下される自明ではない判断について説明する文(特定の部分関する洞察に満ちた見解)
  • code品質
    • テスト容易性/拡張性/可読性

「Kent Beckの実装パターン」を読んだ

実装パターン

実装パターン

メモです。リーダブルコードをより具象化、パターン化した本という印象。

TL;DL

  • 「他人が読んでわかるコード」が「よいコード」
  • 読み手を意識しながらコーディングすることの重要性。いかに意図を正しく伝えるか

プログラマの仕事は,他のプログラマとの間でコミュニケーションを取ることである.マシンとではない.

Implementation

実装パターン

  • 「相手にこのコードで何を伝えたいか」を自問する思考方法
  • 誇りの持てないものに対して無駄にする時間はない、よいコードを書くこと自体が喜びであり、そのコードを他の人が理解し、評価し、使用し、拡張してくれれば、さらに喜びは増す

「責任」についての本

  • 自分とその相棒であるマシンのためだけではなく、他の人のためにコードを作成する

コードを通して考えを伝える

  1. 自分で何を考えているを意識出来るくらいに思考速度を落とす == 直感でコードを書く振りを止める
  2. 他人の重要性を認識する

卓越したプログラムに必要とされる要素 - 動機

  1. コミュニケーション
    • 他の人はこれを見てどう感じるだろう
  2. シンプル
    • 余分な複雑性を取り除き、本質を目立たせる
  3. 柔軟性
    • 複雑を引き起こさない、シンプルから生まれる柔軟性

原則 - 行動

  1. 結果の局所化
    • 変数のコストを低く
  2. 繰り返しの最小化
    • 小さな部品を作る
  3. ロジックとデータの一体化
    • ロジックが操作するデータは近くに
  4. 対称性
  5. 宣言型の表現
    • 型に意図を詰める
  6. 変更頻度
    • 同じタイミングで変更されるデータは近くに

Class

  • classの名前が決まれば操作の名前は後から決まってくる
    • 短く力強く、意味が豊富で的確な
  • Interfaceとクラス階層は相互排他ではない
  • 新しいSubInterfaceを導入することでInterfaceの拡張を安全に行う
  • 状態を持たないVOで暗黙的なシーケンスを無視する
  • static関数を格納したライブラリクラスはいつでもオブジェクトクラスに変換できるように
  • classは関連する状態を一つに纏めるもの

State

  • オブジェクトは、外部の世界に示される振る舞いと、その振る舞いを支えるために使用される状態のパッケージ
  • 似たような状態(近くにあるか、同じ計算で使われている、発生・消滅のタイミングが同時か)は1つに纏め、異なる状態は離しておく
  • flagに基づいて決定を行うコードが重複しているならstrategyパターンを検討する
  • static fieldと引数の両方を使用できるなら引数でクラス間の結合を行う
  • 変数の生存期間、スコープ、型は、コンテキストで伝えることが出来る
  • 変数やメソッドを出来るだけ汎用的な型で宣言する
    • 後から具象クラスを自由に変更できる

Behavior

  • 実装を選択するためのメッセージを広範囲に使用すると、明示的な条件分岐のないコードになる(実行時の型に基づいて)
  • 自分の意図をより明確に伝えるために説明メッセージを用いる

Method

  • 出来るだけ汎用的な型で戻り値を宣言する
  • 複雑なオブジェクト生成をコンストラクタではなく、ファクトリー(static method)に任す
    • コンストラクタは具象クラスに貼り付けるので、ファクトメソッドでコードの抽象度が上げる
      • 抽象的な型を返すことが出来る
      • 意図にあった名前を付けることが出来る
      • ファクトリーの中で何をやっているのか気になるので、オーソドックスな生成だけならコンストラクタを用いる
  • メソッド名では意図を伝達し、実装戦略が重要でないなら含めないべき(呼び出し側がどう見えるかによって命名する)
  • 公開するものを少なくすることにより得られる柔軟性を重視する
  • privateなヘルパーメソッドでサブルールンを隠蔽する + 共通部分を除去する
  • 変換処理は変換後のオブジェクトに変換用のコンストラクタを定義する

Collection

  • Collectionを継承するより委譲を活用するのが良い
    • 意味のある操作だけ公開し、わかりやすい名前を付ける事が出来る
    • 継承だと、不適切な(意図しない)メソッドまで保持することになる(ex. clear)
class Library {
    Collection<Book> books = new ArrayList<>();
    // ...
}

Extended to Framework

  • clientのコードを壊すことなくFWの改善が行えるようにするためには複雑性が増すことの方がコスト的に有利な事がある
  • clietnにはシンプルなインターフェースを提供する
  • 目標のFWは、進化可能なくらい複雑だが、使用するのには十分シンプルであり。進化可能なくらいに応用範囲は狭いが、使用するのに十分適応範囲が広い
  • 公開される詳細の数を減らし、変更される確率の低い詳細を公開する

see also

関数型プログラミングから得られる改善

関数型で書いた際に、どういった事が可能になるか。

  • コード量が少なくなる
  • 最適化がしやすい
  • 並行/並列化がしやすい -ドキュメントが少なくなる
  • 状態を持たないので、関数を組み合わせて利用しても相互に影響しない
  • 定理と証明

see also

「許可を求めるな、謝罪せよ」の言葉を通して

リクルートライフスタイルさんの採用サイト *1 を見て、

「許可を求めるな、謝罪せよ」

こういった企業文化いいなと思ったので、幾つか抜粋メモ。

事前に許可がおりることを持っているより 思い立ったらとにかくやってみるといい、 うまくいかなくても後から謝り、改良すればよい というハッカーマインドを鼓舞する言葉

まずはやってみる

  • まずは作る、思い立ったらスピードを最優先する方が結果最終的によい方向に進みやすい
  • 半ば強引なまでの積極性がないと
  • チャレンジグになりたい
  • 従え、心の声に

最小の許可で、行動をしたい。

see also

「ピクサー流 創造するちから」を読んだ

ピクサー流 創造するちから―小さな可能性から、大きな価値を生み出す方法

ピクサー流 創造するちから―小さな可能性から、大きな価値を生み出す方法

想像力と創造性を生みだす手助けとなるエッセンス、メッセージが沢山含まれている本であり、 エド・キャットムル氏が語るマネジメント論、ピクサーの想像力と創造性の秘密だけではなく、 各ヒット作の裏側。スティーブジョブズの人間性など、様々な側面が語られた本だと思う。

以下、メッセージをセクション毎に抜き出した。*1

デミングと日本企業に学んだこと

問題を見つけて直すのは、製造ラインの最上位の管理者から最も末端の人まで、すべての社員の責任である。 責任を持つことに許可はいらない。

いいアイデアといいスタッフ、どちらが大切か

イデアは人が考えるものだ。だからアイデアよりも人の方が大事だ。

正直さと素直さ

正直になることが義務のように感じられる人は、素直さを求められると多少気が楽になる。

できるだけ早く失敗しよう

失敗する可能性のあることに取り組むのが、本当に創造的な企業だ。

信頼とは、相手が失敗しないことを信じるのではなく、相手が失敗しても信じることである。

組織には野獣も必要

目標は緩く、意思は固くもつほうがいい。

創業者にしがみつかない

変化を止めて自分を守ろうとするか、変化を受け入れてそれを武器に返るのかどちらかだ。

ピクサーが集合的な思考の意識転換を図るために使用している8つのメカニズム
  1. 全員で問題解決(デイリーズ)
  2. 現地調査でつかむ本物感

    テクニックは既知のもので、それを予期せぬ方法で使うのがアートだ。

  3. 制約の力
  4. テクノロジーとアートの融合

    芸術は技術を挑発し、技術は芸術に刺激を与える。

  5. 短編で実験する
  6. 観察力を養う
  7. 反省会
  8. 学び続ける(ピクサー・ユニバーシティ)
生まれ変わったクリエイティブ集団

誰にとっても現金のボーナスは嬉しいが、それと同じくらい価値のあるものがある。
それは、尊敬する相手から面と向かって「ありがとう」と言われることだ。

まとめ

素直さや自由、建設な批判がピクサーの大切にしてある文化であり、 創造的になるための条件だと感じた。
パンチのある名言が満載でポジティブな気持ちになれる、また期間を開けて読み返そう。

see alsp

*1:巻末付録に企業運営の指針が載っているのはとても親切

Facebookの文化「ハッカーの流儀」

Facebookの文化であり、マネジメント手法と唄っている
ハッカーの流儀
を読んで、共感する部分があったので纏めた。

ハッカーの流儀というのは継続的な改善と反復をともなう構築アプローチです。 ハッカーは常に物事は改良でき、いかなるものも完成することはないと信じています。彼らは直さずにいられないのです。 時には現状に満足した人々やそんなこと不可能だと言う人ばかりがいる中でそうします。

終わりがないものに挑んでいるからこそ、満足してそこで手が止まったらダメだと感じた。

以下、5つの価値

  1. インパクトへの集中

    最良の方法は常にもっとも重要な問題に集中するということ

  2. 素早く動く

    壊してでも早く進め

  3. 大胆に

    最もリスクが高いのは何もリスクを取らないこと

  4. オープンに

    人々はより多くの情報を手にしてより良い決断をし、よりインパクトの大きなことができるようになります。

  5. 社会的価値を生み出す

    何をするときであれ、世界のために本当の価値をどう作り出すかに常に集中するということです。

まとめ

「コードは議論に勝る」

「リーダブルコード」を再び読んだ

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

発売当初に読んだが、再び読んでみた。

TL;DL

「自分のコードを他人が読んだ時、理解するまでの時間が最短になる為のコーディング手段」を提示してくれる。今後も色褪せない良書であり、プログラマであれば、読むべき書だと思う。

Readableの定義

コードは他の人が最短で理解できるように書かなければならない

以下、各章で気になった言葉をメモしていく

2. 名前に情報を詰め込む

直行する概念は無理に1つにまとめようとせずに、別々に使えるようにするといい

3. 誤解されない名前

最善の名前とは、誤解されないものである。

4. 美しさ

間違ったスタイルであろうと、プロジェクトの規約に従う。
一貫性のあるスタイルは「正しい」スタイルよりも大切だ。

5. コメントするべきでは「ない」こと

コードからすぐに分かることをコメントに書かない。

6. コメントは正確で簡潔に

コメントは領域に対する情報の比率が高くなければならない。

7. 制御フローを読みやすくする

行数を短くするよりも、他の人が理解するのにかかる時間を短くする。

8. 巨大な式を分割する

「頭がいい」コードに気を付ける。あとで他の人がコードを読むときにわかりにくくなる。

9. 変数と読みやすさ

  • クラスのメンバへのアクセスを制限する方法
    • scopeは短く
    • メソッドを出来るだけstaticに(メンバ変数とは関係ないことが分かる)
    • 大きなクラスを小さなクラスの分割する
      • 但、分割後のクラスが独立していれば問題ないが、クラスで相互にメンバを参照し合うようなら分割しても意味がない
    • そもそも、一度だけ書き込む変数を使う、immutableに

10. 無関係の下位問題を抽出する

  • 無関係の下位問題を積極的に探し出して、分離する
    • プロジェクト固有のコードから汎用コードを分離する(Util関数のライブラリ化)

13. 短いコードを書く

最も読みやすいコードは、何も書かれていないコードだ。

14. テストと読みやすさ

  • テストを読みやすくする、一般的な設計原則として
    • 大切でない詳細はユーザから隠し、大切な詳細は目立つようにする

まとめ

目標かつ日々意識することを忘れたり、ぶれたりするような事があった際に、
この本に立ち返りたいと思う。

See also