覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

「ソフトウェア・ファースト あらゆるビジネスを一変させる最強戦略」

「ソフトウェア・ファースト あらゆるビジネスを一変させる最強戦略」 を読んでみました。


IT業界では、相当知名度の高い 及川さん が書かれた本だったので読む前からかなり興味津々でした。


内容紹介は以下のようになっています

MicrosoftやGoogleで世界標準の製品開発に携わってきた技術者が書き下ろす、
あらゆるビジネスが「ソフトウェア中心」に刷新される
今必要な次世代型サービス開発の要諦

AI活用、デジタル・トランスフォーメーション、SaaSをベースにしたサブスクリプションビジネスetc.今、
世界中の企業がITを駆使したデジタルシフト(事業のサービス化)を急いでいる。

日本企業がこの世界的潮流に取り残されないためには、かつての成功モデルである「製造業的ものづくり」から脱却し、
ソフトウェアを中心としたサービス志向の開発体制を構築することが重要だと著者は説く。

ソフトウェアがビジネスの中心を担い、インターネットがあらゆるビジネスの基盤となりつつある今、
日本企業はどう変化すれば生き残れるのか?

世界的IT企業で働き、現在は製造業をはじめとする日本企業の変革にも携わる著者が書き下ろす、
ソフトウェア・ファーストな開発論をぜひ読んでほしい。


本のカバー裏には以下の文言が書かれています。

ソフトウェアがビジネスの中心を担い、インターネットがあらゆるビジネスの基盤となった今、 日本企業はどう変化すれば生き残れるのか? すべてはIT活用を「手の内化」することから始まる!


この、「手の内化」するという言葉が本書の中にも何度か登場します。
それだけ重要だということです。


本の副題からも分かる通り、技術的に深い話を述べられたものではありません。

ITによるビジネスモデルの変革がどんどん進んでいる世の中で、日本の大手企業ではその流れから取り残されています。
IT化、デジタル化というものができているといっても、真の意味でのIT利用ができていない企業が圧倒的に多いと思われます。
この状況を変えるために 企業の戦略の中心に ソフトウェア を置く "ソフトウェア・ファースト" という考え方が重要になります。
どのようにすれば、真の意味でITというものを使ったサービスの提供や、DX(デジタルトランスフォーメーション)というものが進められるのかが書かれています。
基本的に、そういったものを推し進めるための 組織作り、文化の醸成、プロダクト開発 などの方法が書かれています。

極端な言い方をすると、実際の現場のエンジニアよりも、それよりも上のレイヤーのマネジャー層や経営層の方が読むのが一番良いように思います。
ただし、現場のエンジニアに対するメッセージも書かれていますし、エンジニアが読んでも十分過ぎるほどに価値があると思います。

筆者がこれまで、外資系企業、日系企業、さまざまな企業での多様な経験をされてきたからこそ書ける内容だと思います。
正直、この本の内容は及川さんが書かれているから説得力があるものだと思います。


本自体は極端に分厚いものではないので、短時間で読み終えられます。
ただ、そこに書かれた各種エッセンスは非常に濃いです。
いくつかの企業の事例や筆者の経験した内容も書かれており、参考にすべき部分も多いです。

ただし、この本の内容を単純にコピーして実践するのは簡単では無いと思います。
が、この本に書かれた内容を一種の軸にして組織作りや働き方について考える必要があると思います。


以下は私が書籍内で気になった部分の抜粋です。(自分用のメモです)

  • Webやスマートフォンが登場して以来、イノベーションはコンシューマサイドで起きています。一般ユーザとしてITを活用することが、ソフトウェア・ファーストを実践する第一歩と考えましょう。

  • いくつかの日本企業の相談を受けていると、残念ながらマネージャーが機能していないと思わざるを得ない現場が散見されます。
    マネージャーの職務は多岐に渡りますが、部下の成長をサポートするために一番大事なのは適切な評価です。・・・
    評価とは、部下が成長していくための気付きを与える行為です。定期的な人事考課の季節を待つのではなく、常に適切なタイミングでフィードバックをしなければなりません。そのためには、部下の能力を理解して、その能力を活かしたパフォーマンスを発揮しているか把握しておくことが大切です。

  • 「どこでも働ける」人材が、能動的に所属する組織を選んで働いているという状況は、その組織を強くします。と同時に、その人材は常に「どこでも働き続けられる」だけの努力を怠りません。個人の強さが組織の強さとなります。
    一方で、組織は強くあり続け、強い個人を惹き付ける努力を怠らないようにしないと、社員は「どこでも働ける」のですぐ流出してしまいます。この個人と会社との良い緊張関係がお互いを強くするのです。

  • 「創造性は制約を好む」(Creativity loves constraints):マリッサ・メイヤー氏の言葉

  • 自社内では新規事業だとしても、世の中全体を見渡して完全に新しいものを作ることはまれだと思うので、開発中のプロダクトを既存のカテゴリーにあてはめて命名するのはよくあります。しかしその瞬間から、人間の考えは固定化されてしまいます。心理学でいうアンカリング効果に近いことが起きてしまうのです。筆者はラベリングという言い方もしていましたが、開発中のプロダクトにどんなに新しいコンセプトを入れ込もうとしても、既存のプロダクトカテゴリーの名称で呼んでしまった途端に手垢のついた枠組みの中でしか考えられなくなってしまうのです。

  • 航空業界は80年代に予約システムの相互乗り入れを開始しました。本来ならば、ユーザーを奪い合う間柄です。・・・「新たな競合」である通信事業者にユーザーを奪われていたという背景があったためです。・・・航空便を使って移動し、対面で打ち合わせを行なっていたのが、電話会議の普及によって訪問しなくても打ち合わせが可能となり、ビジネス客が激減したのです。
    これなどは、ドメイン(業界)を超えたところに真の競合がいた例です。

  • どんな類のものでも、「変革」で全員が100%満足できるものを目指すのは不可能です。・・・考えなければならないのは、「今いる社員」を満足させるより「将来の社員」を満足させることであり、新たに価値を提供するユーザーの満足度を最大化することです。

  • 内製化が必要な最も重要な理由はノウハウの蓄積です。・・・現代のプロダクト開発は仮説検証の繰り返しです。多くの失敗の中から成功のきっかけをつかみ、それを育てていくことになります。結果だけ見ると成功しか見えないかもしれませんが、実はその裏にある多くの失敗と、そこから得た学びこそが財産となります。プロダクト開発の一部を外出ししていると、その知見が内部に蓄積されません。

  • 昨今はエンジニアが転職先を選ぶ時の一つの要件として、その会社に優れたCTOがいるかどうかを見るという風潮もあります。CTOがいなくても技術力が高くエンジニアを尊重している会社はありますが、CTOを置くくらいきちんと開発に取り組み、エンジニアの待遇や開発体制も整備されているかを判断材料にしている人もいるようです。

  • リファラル採用は自社の魅力を測るリトマス試験紙でもあるのです。


まとめ

私が何書いても仕方ありませんので、とにかく皆さんこの本を読みましょう!

Kotlin - ラムダにおけるスコープ内の変数アクセス・キャプチャ

今日も相変わらず 「Kotlinイン・アクション」 を読みながらの写経です。

Kotlinイン・アクション

Kotlinイン・アクション

  • 作者: Dmitry Jemerov,Svetlana Isakova,長澤太郎,藤原聖,山本純平,yy_yank
  • 出版社/メーカー: マイナビ出版
  • 発売日: 2017/10/31
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (2件) を見る


関数で匿名の内部クラスを宣言した場合、その関数の引数とローカル変数をそのクラスの中から参照できますが、
ラムダでも同様のことが可能です。関数でラムダを使用すると、関数の引数とラムダの前に宣言されているローカル変数を参照できます。

以下のコードでは、関数の引数の prefix, suffix と 関数内でラムダの前に宣言したローカル変数 title にアクセスしています。

fun main() {
    val messages = listOf("0 success", "1 Not super-user", "2 No such file or directory",
        "3 No such process", "4 Interrupted system call", "5 I/O error")

    printMessages(messages, "'", "'")
}

fun printMessages(messages: Collection<String>, prefix: String, suffix: String) {
    var title = "Message:"
    messages.forEach {
        println("$title ${prefix}${it}${suffix}")
    }
}


実行結果は以下の通りで、正常に各変数にアクセスできていることがわかります。

Message: '0 success'
Message: '1 Not super-user'
Message: '2 No such file or directory'
Message: '3 No such process'
Message: '4 Interrupted system call'
Message: '5 I/O error'


変数のキャプチャ

先ほどのコードを Java で記述すると大凡以下のようになります。

import java.util.Collection;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> messages = List.of("0 success", "1 Not super-user", "2 No such file or directory",
                "3 No such process", "4 Interrupted system call", "5 I/O error");

        printMessages(messages, "'", "'");
    }

    private static void printMessages(Collection<String> messages, String prefix, String suffix) {
        String title = "Message:";
        messages.forEach(
                msg -> {
                    System.out.println(title + " " + prefix + msg + suffix);
                });
    }
}

ここで重要なことはJavaのコードでのラムダ内で操作している変数は 実質的final であるため、変更ができません。
それに対して、Kotlinではfinal変数への参照だけに制限されていません。そのため、ラムダ内から変数を変更することもできます。


例えばJavaで以下のようなコードを書いてもコンパイルエラーとなってしまいます。(successCount, errorCountのインクリメント部分がエラーになります)

public class Main {
    public static void main(String[] args) {
        List<String> messages = List.of("0 success", "1 Not super-user", "2 No such file or directory",
                "3 No such process", "4 Interrupted system call", "5 I/O error");

        printMessages(messages, "'", "'");
    }

    private static void printMessages(Collection<String> messages, String prefix, String suffix) {
        String title = "Message:";
        int successCount = 0;
        int errorCount = 0;
        messages.forEach(
                msg -> {
                    if (msg.startsWith("0")) {
                        successCount++;
                    } else {
                        errorCount++
                    }
                    
                    System.out.println(title + " " + prefix + msg + suffix);
                });

        System.out.println("success count = " + successCount + ", error count = " + errorCount);
    }
}


これに対してKotlinでは以下のようなコードをコンパイルすることが可能です。

fun main() {
    val messages = listOf("0 success", "1 Not super-user", "2 No such file or directory",
        "3 No such process", "4 Interrupted system call", "5 I/O error")

    printMessages(messages, "'", "'")
}

fun printMessages(messages: Collection<String>, prefix: String, suffix: String) {
    var title = "Message:"
    var successCount = 0
    var errorCount = 0
    messages.forEach {

        if (it.startsWith("0")) {
            successCount++
        } else {
            errorCount++;
        }

        println("$title ${prefix}${it}${suffix}")
    }

    println("success count = $successCount, error count = $errorCount");
}

実行結果は以下の通りです

Message: '0 success'
Message: '1 Not super-user'
Message: '2 No such file or directory'
Message: '3 No such process'
Message: '4 Interrupted system call'
Message: '5 I/O error'
success count = 1, error count = 5


Javaとは違い、Kotlinはラムダ内からfinalではない変数を参照して、それを変更することも可能です。
上記コード例の prefix, suffix, successCount, errorCount などのラムダから参照される外部変数は、ラムダによって キャプチャ(caputure)されている と表現されます。

デフォルトでは、ローカル変数のライフタイムは変数が宣言されている関数によって制約されます。
ただし、ラムダによってキャプチャされた場合は、この変数を使用するコードは保持されて、あとで実行されます。
final変数をキャプチャすると、その値はそれを使用するラムダのコードとともに保持され、final変数でない場合はその値を変更できるようにとくべるなラッパーに囲まれ、ラッパーへの参照がラムダとともに保持されます。


注意点

ラムダがイベンハンドラのように用いられて、非同期に実行される場合、ラムダが実行された時に初めてローカル変数への変更発生します。
例えば以下のようなコードを書くと、この関数は常に 0 を返します。

fun countButtonClicks(button: Button): Int {
    var clickCount = 0
    button.onClick { clickCount++}
    return clickCount
}

onClickハンドラはclickCount(クリック数)の値をインクリメントして変更しますが、関数が返された後に onClickハンドラが呼び出されるため、変更されたクリック数を観測することはできません。


まとめ

Kotlinにおけるラムダのスコープ内の変数アクセスは、変数に対するキャプチャによってJavaと異なる操作が可能であることがわかりました。

vimでの改行コードの可視化

今回のエントリは、MacOS環境で試してますので、Linux環境だと挙動が違うところある可能性があります


vimでファイル触っているということは大概の場合において、行末尾の改行コードが LF なわけですけど。
WIndowsで作成したテキストファイルを作成すると 改行コードは CR+LF です。

場合によって、改行コードの LF と CR+LF が混在したファイルができていたりします。


vimで対象ファイルの改行コードを可視化する場合、以下を実行します

:set list


改行コードがLFの場合は、以下のように表示されます。($ が LF を意味しています)

aaaaaaa$
bbbbbbb$
ccccccc$
aaaaaaa$
aaaaaa$
1234567$
8901111$


行末尾が CR+LF だと以下のように表示されます。(^M1がCR, $ が LF, を意味しています)

aaaaaaa^M$
bbbbbbb^M$
ccccccc^M$
aaaaaaa^M$
aaaaaa^M$
1234567^M$
8901111^M$


改行コードに LF と CR+LF が混在していると以下のように表示されます。

aaaaaaa^M$
bbbbbbb^M$
ccccccc^M$
aaaaaaa^M$
aaaaaa^M$
1234567^M$
8901111^M$
^M$
^M$
abcdefg$
hijklmn$
opqr$


そもそも CR+LF のファイルであれば ^M は最初から表示されているはずです。

もし表示されていないようであれば以下を実行します

:edit ++ff=unix


ちなみに、fileコマンドで改行コードが CR+LF のファイルを確認すると以下のようになります。

$ file sample.txt 
sample.txt: ASCII text, with CRLF line terminators


fileコマンドで改行コードに LF と CR+LF が混在しているファイルを確認すると以下のようになります。

$ file sample3.txt 
sample3.txt: ASCII text, with CRLF, LF line terminators


というわけで、改行コードを可視化できたのでこれで良しです。
(普通は改行コードを変換するところまで書くのがワンセットな気がしますが笑)

「Clean Architecture 達人に学ぶソフトウェアの構造と設計」

かなり前に読み終えてはいたんですが、「Clean Architecture 達人に学ぶソフトウェアの構造と設計」の内容に関する今更ながらの自分用のメモです。

結構話題になった本だと思います。自分にとっても結構役に立つ内容が多かったです。
(ただ、まだ若干理解しきれない部分もありましたが。。。)

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計


書籍の内容紹介には以下のように書かれています

アーキテクチャのルールはどれも同じである!

書いているコードが変わらないのだから、どんな種類のシステムでもソフトウェアアーキテクチャのルールは同じ。
ソフトウェアアーキテクチャのルールとは、プログラムの構成要素をどのように組み立てるかのルールである。
構成要素は普遍的で変わらないのだから、それらを組み立てるルールもまた、普遍的で変わらないのである。
(本書「序文」より)


この本は、Clean Architecture という考え方に言及したのものですが、具体的な実装方法については記述されていない点には注意が必要です。
あくまで概念的な説明や抽象的な内容で、大規模ソフトウェア(長期的に運用するアプリケーション)を設計する際に気を付けなければならないポイントに焦点を当てて解説してくれています。
(※パッケージ構成やクラス間の依存関係について説明のある章はあります)

そのため、プログラムの初学者や未経験者が読むには適していません。
一定の経験を積んだソフトウェア開発者が読むのが良いと思われます。
プログラム初学者がいきなり手を出すと、読んでいる最中に眠くなるんじゃないかな・・と思います。


章立ては以下のようになっています。

  • 第1章: 設計とアーキテクチャ
  • 第2章: 2つの価値のお話
  • 第3章: パラダイムの概要
  • 第4章: 構造化プログラミング
  • 第5章: オブジェクト指向プログラミング
  • 第6章: 関数型プログラミング
  • 第7章: SRP : 単一責任の原則
  • 第8章: OCP : オープン・クローズドの原則
  • 第9章: LSP : リスコフの置換原則
  • 第10章: ISP : インターフェィス分離の原則
  • 第11章: DIP : 依存性関係逆転の原則
  • 第12章: コンポーンネント
  • 第13章: コンポーネントの凝集性
  • 第14章: コンポーネントの結合
  • 第15章 : アーキテクチャとは?
  • 第16章 : 独立性
  • 第17章 : バウンダリー:境界線を引く
  • 第18章 : 協会の解剖学
  • 第19章 : 方針とレベル
  • 第20章 : ビジネスルール
  • 第21章 : 叫ぶアーキテクチャ
  • 第22章 : クリーンアーキテクチャ
  • 第23章 : プレゼンターとHumble Object
  • 第24章 : 部分的な境界
  • 第25章 : レイヤーと境界
  • 第26章 : メインコンポーネント
  • 第27章 : サービス:あらゆる存在
  • 第28章 : テスト境界
  • 第29章 : クリーン組込みアーキテクチャ
  • 第30章 : データベースは詳細
  • 第31章 : ウェブは詳細
  • 第32章 : フレームワークは詳細
  • 第33章 : 事例:動画販売サイト
  • 第34章 : 書き残したこと

各章は、内部的にさらに細かな章で構成されています。
その最も細かく分類された章1つ1つをとって見ると別の書籍やウェブサイトですでに一般的に語られている内容が書かれていることも少なくないです。
この本は、基本的には本全体を通して読む必要があると思います。が、各章単体で見ても、ソフトウェア設計における重要な要素を示唆している場合もあります。

個人的には、第21章の「叫ぶアーキテクチャ」が好きです。
この章はものすごく短い内容ですが、大規模ソフトウェア(システム・サービス・アプリケーション)で、これが出来ていない、または、修正を繰り返すうちに、これが出来なくなっているというケースが少なくないなーという重要な指摘がされています。

他にも 第32章 : フレームワークは詳細 なども面白いです。


各章の詳細は、この本を読んでもらって把握してもらいたいのですが、
本書籍内で、私が気になった部分の抜粋を一部メモしておきます。(括弧部分は私の補足です)


  • ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守するために必要な人材を最小限に抑えることである
  • 設計の品質は、顧客のニーズを満たすために必要な労力で計測できる。必要な労力が少なく、システムのライフタイム全体で低く保たれているならば、その設計は優れている。逆にシステムごとに労力が増えるなら、その設計は優れていない。
  • 「あとでクリーンにすればいいよ。先に市場に出さなければ!」
    開発者たちはそうやっていつもごまかす。だが、あとでクリーンにすることはない。市場からのプレッシャーは止まらないからだ。「先に市場に出さなければ」ということは、後ろに競合他社が大勢いるということである。競合他社に追い抜かれないためには、これからも走り続けるしかない。
  • 崩壊したコードを書くほうがクリーンなコードを書くよりも常に遅い。
  • ソフトウェアはソフトでなければならない。つまり、簡単に変更できなければならない。ステークホルダーが機能を変更したいと思えば、その変更は簡単にできるようになっておくべきだ。変更の難易度は、変更の形状ではなく、変更スコープに比例しなければならない。
  • ビジネスマネージャーに変更を希望するかと聞くと、当然ながら「希望する」と答える。ただし、将来の柔軟性よりも現在の機能性の方が重要だと回答を補足するはずだ。とはいえ、ビジネスマネージャーが変更を求めたとき、あながた膨大なコストを見積もると、変更が非現実的になるまでシステムを放置したあなたに対して、ビジネスマネージャーは激怒するだろう。
  • これらのパラダイム(構造化プログラミング、オブジェクト指向プログラミング、関数型プログラミング)は、プログラマから能力を削除しているのである。新しい能力を提供しているものはない。それぞれがネガティブな意図を持ち、何らかの規律を課しているのである。これらのパラダイムは、何をすべきかを伝えるというよりも、何をすべきでないかを伝えているのである。
  • ソフトウェア開発は、数学的な構成要素を操作しているかのように思えるかもしれないが、実際には数学的な試みではない。むしろソフトウェア開発は科学のようなものである。どれだけ最善を尽くしても正しくないことを証明できないことによって、その正しさを明らかにしているのである。
  • 確かにOO(オブジェクト指向)は、プログラマがカプセル化されたデータを盗み見ないように、礼儀正しく振舞うべきであるかという考え方に依存している。だとしても、OOを提供すると主張している言語は、C言語で完ぺきに実現できているカプセル化を弱体化させてしまっているのである。
  • ポリモーフィズムは関数へのポインタの応用である。1940年代後半にノイマン型アーキテクチャが実装されて以来、プログラマはポリモーフィズムの振る舞いを実現するために、関数へのポインタを使用してきた。つまり、OO(オブジェクト指向)は新しいものを提供しているわけではないのである。
  • アーキテクチャの観点からすると、なぜこれ(不変性)が重要なのだろうか?なぜアーキテクトは、変数の可変性に配慮すべきなのだろうか?その答えは、簡単すぎるぐらいである。それは、競合状態、デッドロック状態、並行更新の問題の原因が、すべて可変変数にあるからだ。変数が変化しないのであれば、競合状態や並行更新の問題は発生しない。また、変更可能なロックがなければ、デッドロックになることもない。
  • モジュールはたったひとつのアクターに対して責務を負うべきである。
  • 変化しやすい具象クラスを継承しない。具象関数をオーバーライドしない。
  • 最終的にどのような形式でデプロイするかにかかわらず、よくできたコンポーネントは常に個別にデプロイできる状態を保っているため、個別に開発を進められる。
  • 多くのアプリケーションにおいて、再利用性よりも保守性の方が重要だ。アプリケーションコードが変更しなければならないときには、ひとつのコンポーネントに変更箇所がまとまっているほうが、あちこちのコンポーネントに散らばっているよりもありがたい。変更箇所がひとつのコンポーネントに閉じていれば、変更後にデプロイする必要があるのはそのコンポーネントだけになる。そのコンポーネントに依存していないコンポーネントは再デプロイする必要がない。
  • コンポーネントの依存構造をきちんと管理しておく必要がある。循環依存があってはいけない。
  • 循環依存があると、コンポーネントを切り離すのが難しくなる。ユニットテストやリリースも難しくなり、失敗に陥りやすくなる。さらに、モジュールの数が増えるにつれて、ビルド時の課題も幾何級数的に増加する。
  • アーキテクチャの主な目的は、システムのライフサイクルをサポートすることである。優れたアーキテクチャがあれば、システムを容易に理解・開発・保守・デプロイできる。最終的な目的は、システムのライフタイムコストを最小限に抑え、プログラマの生産性を最大にすることである。
  • ソフトウェアシステムが効果を生み出すためには、デプロイ可能な状態でなければいけない。デプロイのコストが高ければ、どの分だけシステムの有用性は低下する。ソフトウェアアーキテクチャの目的、システムを単一のアクションで簡単にデプロイできるようにすることである。
  • ソフトウェアシステムのすべてにおいて、保守は最もコストがかかるものである。永遠に続く新しい機能の登場と、避けられない欠陥や修正の繰り返しは、人的リソースを膨大に消費する。...
    アーキテクチャを慎重に考え抜けば、これらのコストは大幅に低下する。システムをコンポーネントに分離して、安定したインターフェイスを持つ独立したコンポーネントにしておけば、将来の機能の道筋が照らされ、意図せずに壊してしまうリスクを大幅に低減できるだろう。
  • 明らかに重複しているコードが異なる進化を遂げ、数年後には両者がまるで違ったものになっていることもある。これは本物の重複ではない。偽物の重複、あるいは偶然の重複である。
  • レイヤーを水平に分離していると、あるデータベースのレコードのデータ構造が、ある画面のデータ構造とよく似ていることに気づくことがある。ビューモデルを作成して要素をコピーするのではなく、データベースのレコードをそのままUIに渡したくなるが、注意してほしい。これは確実に偶然の重複である。ビューモデルを作成するのは大した労力ではないし、レイヤーを適切に切り離すのに役立つだろう。
  • 早すぎる決定とはどのようなものなのか?それは、システムのビジネス要件(ユースケース)と関係のない決定である、たとえば、フレームワーク、データベース、ウェブサーバ、ユーティリティライブラリ、DIなどに関する決定が含まれる。優れたシステムアーキテクチャは、このような決定を従属的かつ遅延可能なものにする。優れたアーキテクチャは、このような決定に依存しない。優れたシステムアーキテクチャは、重大な影響を与えることなく、このような決定を最終時点まで引き延ばせる。
  • アーキテクチャの目標は、下位レベルのプロセスを上位レベルのプロセスのプラグインにすることである。
  • ユースケースとは、自動化されたシステムを使用する方法を記述したものである。ユーザから提供された入力、ユーザに戻す出力、出力を生成する処理ステップなどを規定している。エンティティに含まれる最重要ビジネスルールとは違い、ユースケースにはアプリケーション固有のビジネスルールを記述している。
  • あなたのアプリケーションのアーキテクチャは何と叫んでいるだろうか?最上位レベルのディレクトリ構造と最上位レベルのパッケージのソースファイルは、「ヘルスケアシステム」「会計システム」「在庫管理システム」と叫んでいるだろうか?それとも「Rails」 「Spring/Hibernate」「ASP」と叫んでいるだろうか?
  • アーキテクチャはフレームワークに関するものではない。アーキテクチャはフレームワークから提供されるものではない。フレームワークは使用するツールであり、アーキテクチャが従うものではない。あなたのアーキテクチャがフレームワークにもとづいているのなら、そのアーキテクチャはユースケースにもとづくことはできない。
  • アーキテクチャは、システムで使用しているフレームワークではなく、システムそのものについての情報を伝える必要がある。たとえば、ヘルスケアシステムを構築しているのであれば、新しく参加したプログラマがソースリポジトリを見たときに、「ああ、これはヘルスケアシステムだ!」と思えるようにしておくべきである。システムの提供方法はまだわからなくても、システムのユースケースを全て把握できるようにしておくべきだ。
  • Mainコンポーネントは、究極的な詳細である。システムの最初のエントリポイントとなる。オペレーティングシステム以外に、このコンポーネントに依存しているもはない。FactoryやStrategyなどのグローバルな要素を作成し、システムの上位の抽象部分に制御を渡すことが、このコンポーネントの仕事になる。
    依存関係については、このMainコンポーネントにDIフレームワークを使って注入する必要がある。Mainに注入できたら、あとはフレームワークを使用せずに、Mainが通常のやり方で依存関係をちりばめる。
    Mainは、汚れ仕事が最も似合うコンポーネントだ。
  • ソフトウェア設計の第一のルールは、その理由がテスト容易性だろうと何だろうと、常に同じである。それは、変化しやすいものに依存しないだ。GUIは変化しやすい。GUIを使用してシステムを操作するテストスイートは脆弱である。したがって、GUIを使用しなくてもビジネスルールのテストができるように、システムとテストを設計しなければならない。
  • データ構造であるデータモデルは、アーキテクチャ的には重要である。だが、回転する磁気面上でデータを移動させる技術やシステムは、アーキテクチャ的には重要ではない。リレーショナルデータベースシステムは、データを表形式で管理して、SQLからアクセスするための仕組みであり、これはデータモデルよりも技術やシステムに近い。データこそが重要なのであり、データベースは詳細なのである。
  • (フレームワークの)作者にとって、フレームワークとの結合には何のリスクもない。むしろフレームワークとの結合を望んでいる。作者自身はそのフレームワークを好きなようにコントロールできるからだ。
    さらに作者は、あなたに対してもフレームワークとの結合を望んでいる。一度でも結合してしまえば、切り離すのはとてもむずかしくなるからだ。フレームワークの作者にとって、自分の作った基底クラスを大勢のユーザが継承することほど、自尊心が満たされることはない。

このメモをは自分用のものなので、これだけ読んでも何のこっちゃ という感じだと思いますので、
ぜひぜひ書籍を手にとって読んでもらいたいです。



関連リンク

「ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」」

「ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」」 を読んでみました。

ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」

ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」


内容紹介は以下のようになっています

●「ホウレンソウ」だけではチームは回らない
仕事をする上で、「ホウレンソウ(報告・連絡・相談)」は大切です。
こまめな報告があれば安心でき、
連絡が行き届くことで無駄もなくなり、
相談があることでいち早く問題を解決することができます。
ホウレンソウは社会人にとっての基礎スキルといえます。

ただ、ホウレンソウだけでは、
チームのコミュニケーションが機能しなくなってきています。

近年、チーム間で(とくに、上司と部下の間で)個人的な話がしにくくなっています。
働き方改革によって残業が減り、飲みニケーションや喫煙所での会話も少なくなりました。
ハラスメントに注意しすぎて仕事以外の話もしにくく、
つねに成果を求められているため、短期的な仕事の話が中心になっています。

こうしたコミュニケーションだけでは、
人を、成果を出すための道具としてしか見られなくなり、
やがてチームのモチベーションは下がっていってしまいます。
人としてコミュニケーションがとれる場を、
チームとして継続的に設けることが必要なのです。

●チームを活性化させる「ザッソウ」
具体的にいうと、それはチームにおけるコミュニケーションのあり方を
「ホウレンソウ」のステージから「ザッソウ(雑談・相談)」に上げる、ということです。

ザッソウを通して、メンバー同士が何を考え、
何を感じているのかを共有し、言いたいことを言い合える信頼関係をつくる。
それはチームに心理的安全をもたらし、メンバーのやる気を高めることにもつながります。

それに普段から雑談をしていれば、本当に困ったときに相談しやすくなります。
旧来のホウレンソウだけの状態では、信頼関係ができていないわけですから、
たとえ「いつでも相談していい」と言われていても、なかなか声をかけにくいものです。
つまり話しかける心理的ハードルを下げるためにも、ザッソウは有効なのです。

それだけではありません。新しいアイデアが出ない、専門的な知識がなくて困っている……
そんな問題を解決したいとき、ザッソウでコミュニケーションをとるうちに
価値が生まれることがあります。
ザッソウは、イノベーションにつながるアイデアが生まれ、
チームの生産性を高めることにもつながるのです。


本のカバーには以下のようにザッソウが定義されています。

  • ざっそう【ザッソウ】
    • 「雑談+相談」「雑な相談」
    • 雑談があることで相談がしやすくなり、人間関係が構築されて心理的安全性を高めることができる。
      チームビルディングを成功させるのはホウレンソウではなくザッソウ。


社会人になると、早い段階でまず耳にするであろうホウレンソウ(報・連・相)。
報告、連絡、相談 というのを適切なタイミングでやることを社会人として求められます。
なんとなく、部下が身につけておくべき基本的な姿勢という風に思われます。

が、実際のところ

そもそも「報連相」とは、山種証券(現・SMBCフレンド証券)社長の山崎富治氏が社内で「ほうれんそう運動」を始めたことがきっかけです。

下からの意見をどう吸いあげるか、みんなが働きやすい環境をどう作るか、暖かい人間関係をどう作るか、
少数精鋭で社員一人ひとりに厚く報いるには…と、
つね日ごろ頭を悩ませていたとき思いついたのが、”ほうれんそう”だった。

上司・部下の間で情報が行き来する風通しの良い職場環境を作ろうというスローガンで、部下への情報共有を義務付けるものではありません。

しかし、現在ではなんとなく部下への義務的な要件として浸透しています。

世間一般的に広まった ホウレンソウ ではなく ザッソウ によって
組織内の相互理解が高まる、心理的安全性が生まれる、率直に意見をぶつけ合えることで成果が出せる、
新しいアイデアが生まれる、組織を変える土台になる、、、ということが述べられています。

筆者が関わってきた事例などをベースにザッソウの重要性や必要性が述べられています。
割と薄い本ですが、内容は共感する部分が多いです。
多くの人に読んでもらいたい本です。


以下は私が書籍内で気になった部分の抜粋です。(自分用のメモです)

  • 1on1ミーティング という形で、上司と部下で評価面談と別にお互いに考えていることなどを共有する機会を作っている組織が多くあります。
    この1on1ミーティングこそ、中身はザッソウです。雑談であったり、相談であったり、特に決着をつけなくていいからこそ、気軽に話をすることができます

  • 気軽なフィードバックで仕事の質と速度が向上する

    • マネージャーや上司として困るのは、依頼や指示をした内容とまったく違うものが時間をかけた後に出てくるケースです。
    • 少しずつ確認していくことが手戻りを減らす最善手となります
  • 働きがいと働きやすさが両立したワクワクする職場には、事業を自分事として考えられる人たちがいる活気の良さと、経済的に安心できて家族や自分の時間を持つことができる制度があります。

  • 少なくとも手応えがあることは、働きがいの必須条件といえます。
    それはどのような形であれフィードバックがあることです。
    半年に一度の評価面談や定例会議などを持つことなく、気軽にザッソウしてフィードバックされる気合があればいいのです。

  • 心理的安全性を高める9つの観点

    • チームの目標がはっきりしている
    • 適度に対話しやすい人数である
    • 強みを知り、認め合っている
    • 強みだけでなく、弱みも見せる
    • プライベートなことも共有している
    • 情報がオープンになっている
    • 判断基準と価値観が共有されている
    • リアクションの意識がそろっている
    • 「肯定ファースト」と「NOと言うこと」
  • 自分の弱みを隠さないでいられれば、困ったときに気軽にザッソウできるようになるので成果も上げることができています。
    チームの利点は、仲間が集まることで、1人では実現できない挑戦ができることです。一方、弱ったときに助け合うことで、
    1人で潰れてしまわないようにするという利点もあります。そもそも助け合うためには、弱みを見せることは悪いことでは無いのです。

  • フォロワーもある意味でリーダーシップの1つの形態であると主張しています。

  • ザッソウあふれる職場やチームには、明るく穏やかな空気が流れています。
    その雰囲気を生み出しているのは、やはりリーダーの姿勢や人柄によるところが大きくなります。

  • しなやかなマインドセットの人には、人間の基本的な資質は努力次第で伸ばすことができるという信念があります。
    持って生まれた資質は違っていても、その後の努力と経験で伸ばすことができる。
    だから、現時点で足りていない・できていない自分でも認めることができるのです。ですから難しい問題に出会っても粘り強く立ち向かうことができます。

  • 自己組織化とは、もともと自然現象をモデル化した際に使われた表現で、自律的に秩序や構造を作り出す現象のことをいいます。
    それを組織やチームへ適用して考えてみると、組織を構成しているメンバーそれぞれが、場に備わったミッションや目的を達成するために、自律的に考えて行動しつつも相互に助け合い、作用し合っている状態と考えられます。

  • ネットワーク型の情報共有は、メンバー1人ひとりの情報リテラシーが問われます。情報を自ら収集する必要がありますし、その情報の正しさを精査して理解するところは各人に任されるからです。しかし、そうして分散化した方がスピードが速く、新しく価値が生み出される可能性すらあるのです。それはまさしくインターネットの世界で実証されています。

  • 人というのは、どれだけ外部から良い方法を教えたり、指導したところで行動を変えることは難しいものです。それは自分たちのことがわかっていないからです。必要なのは、自分たちのことを知る機会です。自分たちが本当にまずい状態だと思えば改善する意欲もわくでしょう。そうなって、ようやく変わる出発点に立ってくれます。鏡を見ることがなければ、自分の顔が汚れていることには気づかないものです。だから、ふりかえりとは、チームで自分たちの姿を鏡で見る機会でもあるのです。