ソフトウェア工学

2024/05/06

「システムアーキテクチャ構築の原理」の感想part2~非機能要件がシステムのアーキテクチャに影響を与える観点をプロセス化する

システムアーキテクチャ構築の原理」を読んでる。
平鍋さんの記事「『ソフトウェアシステムアーキテクチャ構築の原理(第2版)』読んだ #Java - Qiita」を読み直して、理解が深まった。
平鍋さんの記事に触発されたので、理解できたことをラフなメモ。
間違っていたら後で直す。

【参考】
『ソフトウェアシステムアーキテクチャ構築の原理(第2版)』読んだ #Java - Qiita

「システムアーキテクチャ構築の原理」の感想: プログラマの思索

【1】「システムアーキテクチャ構築の原理」を読んでいて分かりにくかったことは、ビュー、ビューポイント、パースペクティブという概念が出てきて混乱したこと。
これらの言葉は何を表しているのか、具体的に理解できていなかった。

平鍋さんの記事「『ソフトウェアシステムアーキテクチャ構築の原理(第2版)』読んだ #Java - Qiita」では、概念モデルでまとめてくれているので理解しやすかった。

【2】図4-3.コンテクストにおけるパースペクティブが「システムアーキテクチャ構築の原理」のメッセージを全て表している。
平鍋さんの解説が分かりやすい。

43

(引用抜粋 開始)
「非機能要件がシステムのアーキテクチャに影響を与える」という観点を本書は、この言説を徹底的に解説したもの。

非機能要件に限らず、横断的な視点を「パースペクティブ」として捉えている

実際にアーキテクチャを記述しようとすると、1つの文書ではとっても複雑で巨大な説明になる。「ステークホルダー」の「関心事」毎に分割するために、「ビュー」と「ビューポイント」を導入する

「パースペクティブ」は、従来の言葉で近いものとして「非機能要求」「横断的関心事」がある。本書ではこの「ビューポイント」と「パースペクティブ」のカタログを作っています。
(引用抜粋 開始)

【3】図15-1.ビュー間の関係では、ビューを開発や運用の観点で分解している。
この図は、システム開発とシステム保守で分割すれば理解しやすい。
今ならDevOpsだから、開発も運用も一体化しているだろう。

151

【4】図7-3.アーキテクチャ定義のプロセスは、「システムアーキテクチャ構築の原理」が提唱している、アーキテクチャを定義し評価するプロセス。
アーキテクチャ設計の中で、特に非機能要件を含めた横断的関心事をいかにアーキテクチャに盛り込むのか、を考えた一連のプロセスになる。
プロセスの流れは、アーキテクチャ要素や横断的関心事を段階的詳細化して組み立てたあとにアーキテクチャを評価するので、違和感はない。

73

【5】「システムアーキテクチャ構築の原理」では上記3つの図が本書のメッセージになると思う。
本書のやり方を各システム、各案件にテーラリングして設計、実装する必要があるから、本書は、アーキテクチャ設計のメタ概念、メタプロセスの解説書みたいな感触を持っている。

【6】「システムアーキテクチャ構築の原理」の副題「ITアーキテクトが持つべき3つの思考」が指す「3つ」とは、「ステークホルダー」「ビューポイント」「パースペクティブ」と最初に書かれている。

その意図は、ステークホルダーの横断的関心事、特に非機能要求をユーザ観点のビューポイント、システム観点のパースペクティブで分解して組み立てて、トレードオフを考慮したアーキテクチャを設計すること、を意味していると考える。

他にも気づいた他内容があれば書いていく。

| | コメント (0)

「システムアーキテクチャ構築の原理」の感想

システムアーキテクチャ構築の原理」を読む機会があったので感想をラフなメモ書き。

【参考】
「システムアーキテクチャ構築の原理」の感想part2~非機能要件がシステムのアーキテクチャに影響を与える観点をプロセス化する: プログラマの思索

『ソフトウェアシステムアーキテクチャ構築の原理(第2版)』読んだ #Java - Qiita

アーキテクチャ構築の原理 第2版を読んだ - 勘と経験と読経

【0】「システムアーキテクチャ構築の原理」は最新版の第2版もある。
僕は確か、デブサミ2010の時に会場で購入した記憶があり、第1版を持っている。
その時から興味のある部分だけかいつまんで読んでいたので、全部を通して読んでいなかったので、輪読するのは良かった。

システムアーキテクチャ構築の原理」を読んで興味を持った部分はいくつかある。

【1】1つ目は、2008年の初版でありながら、マイクロサービスやサービス志向のアーキテクチャ設計を目指していること。
機能的ビュー、情報ビュー、並行性ビューなどのソフトウェア構造のアーキテクチャ設計の観点は、業務システム設計と微妙に違うな、と感じていたが、実際はクラウドベースのマイクロサービス設計を目指しているのだろう。
実際、並行性ビューでは、昔のバッチ処理設計よりもイベント駆動の並列性アーキテクチャに力点をおいている。
たとえば、REST APIやAdapter・Facadeパターンのようなアーキテクチャ設計を念頭に置いて実装しようとしている。

そう考えると、マイクロサービス設計における新たな設計思想はまだ含まれておらず、荒削りな内容を感じるが、文章の背後にある著者の思い、こういうことを言いたいのではないか、を推測しながら読むと理解できるのでは、と感じる。

【2】2つ目は、ATAMという非機能要件の設計技法を解説してくれている点だ。

データベースコンサルタントのノウハウちょい見せ アーキテクチャをレビューする方法(ATAM)

ATAMはシナリオベースで非機能要件を評価する設計技法。
僕の理解では、システムのアーキテクチャの特に非機能要件を品質特性ごとに分類し詳細化して、それをシナリオに落とす。
そのシナリオを優先度付けして、シナリオベースにアーキテクチャを評価して整合性を取ったり、システム設計を明確化する。

利点は、非機能要件をアーキテクチャとして評価する技法として、シナリオベースを用いているので、アジャイル開発をやっている人には取り組みやすいと思う。
デメリットは、CMMIを作ったSEIがATAMを提唱しているので、重たいプロセスになりがちで、テーラリングが必須であり、プロマネによってばらつきが出やすいこと。

ATAMに関する日本語書籍は「システムアーキテクチャ構築の原理」と「間違いだらけのソフトウェア・アーキテクチャ―非機能要件の開発と評価 (Software Design plus)ぐらいしかないので、貴重だと思う。

データベースコンサルタントのノウハウちょい見せ 書評「間違いだらけのソフトウェア・アーキテクチャ―非機能要件の開発と評価」

【3】3つ目は、2009年頃の書籍なので、UMLをベースとした設計を念頭に置いていること。
機能的ビューではコンポーネント図、情報的ビューではER図やDFDや概念クラス図、並列性ビューではステートマシン図を使うと良いと説明されている。
このあたりの意見は僕も同意するが、注意点はいくつかあると思う。

コンポーネント図は「アジャイルソフトウェア開発の奥義」でも重要視されている。
機能を1つのコンポーネントとみなし、コンポーネント間のインターフェイスを重視する設計は重要だと思う。
一方、コンポーネント図だけでは表現しきれない仕様や要件があり、不十分と感じる。

その点は「システムアーキテクチャ構築の原理」でも、メッセージングのやり取りは記述できないので補足説明や別の図が必要と書かれている。

並列性ビューに出てくるステートマシン図は、より詳しく書いていくと結局、詳細設計レベルになってしまう。
アーキテクチャ設計ではRFPに出てくる要件レベルまでで留めたいので、粒度を揃えるのが難しい場合が多いだろう。

【4】「システムアーキテクチャ構築の原理」を読んでいて思い出すのは、2000年代にソフトウェア・プロダクトラインが流行した頃に読んだ「 実践ソフトウェアアーキテクチャ」に出てくる一節だ。

そのボタンを押したら何が起きるのですか?~アーキテクチャは利害関係者のコミュニケーション手段: プログラマの思索

実践ソフトウェアアーキテクチャの解説記事: プログラマの思索

実践ソフトウェアアーキテクチャ」では、政府のある委員会の2日間に渡る討議の中で、新人のアーキテクトが、政府が作ろうとしているシステムのアーキテクチャをコンサル独自の記法でモデルを描いて委員会の参加者に説明していたところ、委員会の参加者たちは何が問題なのかに初めて気づいた。
そして、委員会の参加者たちは、新人のアーキテクトの説明を途中で止めさせて、システムのアーキテクチャの問題点を活発に議論し始めたという一節だ。
これが意味しているのは、アーキテクトの役割とは、システムのアーキテクチャ設計に関する最終責任者ではなく、各利害関係者の間でシステム要件のトレードオフを考慮させる調停者であることだ。

つまり、アーキテクトの役割はシステム要件を決めることではなく、システム要件のトレードオフを色んなステークホルダーに説明して理解させて、最終的な意思決定を引き出す調停者として振る舞うべきだ、ということ。
この一節は僕が一番好きなところでもある。

システムアーキテクチャ構築の原理」では、アーキテクトがすべてのパースペクティブやビューポイントを理解している全能の神のように思えてしまうが、実際はそうではなく、アカウンタビリティを持つ調停者という観点で捉えると理解しやすいと考える。

気づいた点はまた書き留めていく。

| | コメント (0)

2024/03/03

ソフトウェア工学の根本問題から最近のソフトウェア設計を考えてみる

ソフトウェア工学の根本問題は何なのだろうか?
僕は、ソフトウェアをいかに部品化して疎結合な構造とし、お互いの相互作用でいかに協調動作する仕組みを作るか、だと思う。
以下、直感的な思考を書き記しておく。

ソフトウェアの歴史をたどれば、構造化プログラミングからオブジェクト指向プログラミングへ発展した経緯を見ると、ソフトウェアの構造とソフトウェアを開発する仕組みをいかに透明化し、コントロールしやすくするか、に力点をおいているように思える。

@sakaba37さんから言われてはっと気づいたことは、ソフトウェアは密結合になりやすいこと。
トランザクションスクリプトのように、ちょっとしたロジックの処理を何も考えずに実装すると、密結合なプログラムになり、スパゲッティになりやすい。

そして、ソフトウェアを開発するプロセスも、ソフトウェアを開発する組織も、ソフトウェア構造を反映してしまうために、密結合なプロセス、密結合な組織になりやすい。

今、クラウドを基盤としたマイクロサービス設計が色々試されている。
マイクロサービス設計では、処理層とデータ層をまとめた一つのサービスを独立した単位とし、それらを協調動作する仕組みを作ろうとする。

しかし、今までのソフトウェアの歴史から類推すると、いかにソフトウェアを疎結合な構造にするか、いかにソフトウェアを管理するプロセスを透明化しコントロールしやすくするか、という根本問題から離れられていないように思える。

実際、マイクロサービスが独立した単位であっても、複数のサービスが協調動作させる仕組みをいかに安定して作るか、API設計や補償トランザクションなど、色々試行錯誤している。
ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析」を読めば、マイクロサービスをいかに安定して設計するか、を試行錯誤していることが分かる。

また、全てのマイクロサービスを横断して管理する仕組みとしてサービスメッシュという概念が導入されているが、それもサービスの耐障害性や可用性を担保するための監視サービス群のようなものだ。
ちょうど、Ciscoのネットワーク機器からなるネットワーク構造をSDN化したときに、データ層とコントロール層に分けて、APIを使ってコントロールしようとする仕組みと同じように思える。

他方、ソフトウェア開発の組織も今はスクラムをベースとしたアイデアに基づき、少人数のスクラムチームで開発するのが、特にマイクロサービス開発では相性がいい。
マイクロサービスでは、データ層も処理層も持つので、開発チームが必要なソフトウェア部品を全てコントロールできるからだ。
また、マイクロサービス同士のやり取りは、スクラムチームが協調動作する仕組みに置き換えられる。
実際、スクラムチームでは、プロダクトバックログというインプットとインクリメントとして付加価値を順次リリースするアウトプットが契約になるが、その中のプロセスは部外者は口出しできない。

つまり、スクラムチームは、まるで1つのソフトウェア部品のように中身はブラックボックス化されており、インプットとアウトプットというインターフェイスが保証されている仕組みと思っていい。
すなわち、スクラムチームという開発組織も、疎結合なソフトウェア部品と同様にみなせる。

そんなことを考えると、僕はクラウドやマイクロサービス設計の経験がないけれど、今までのソフトウェア開発の歴史を踏まえた根本問題から、マイクロサービス設計やその開発プロセスでは、過去の根本問題をどのように解決しようとしているのか、という観点で考えていた。
そして、その考え方から類推されるボトルネックは、昔の技術から現代のアーキテクチャに変わったとしても、症状として現れる事象が変わっただけであって、その本質は変わっていないはずだと思っている。


| | コメント (0)

2024/01/02

マイクロサービス設計は従来のアーキテクチャ設計と何が違うのか

マイクロサービスの設計は理解できていなかったし、今も理解が中途半端。
理解できたことだけをメモする。
ラフなメモ書き。

【1】「ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析」を友人と輪読しているが、まだ理解できたという気がしない。
今までのオンプレ環境で業務系Webシステムの設計や開発をしてきた経験、Java+Oracle+Linuxでベタに開発した経験をベースに理解しようとしていた。

そういう観点で読むと、「8章 再利用パターン」が一番理解しやすい。
なぜならば、コンポーネントやサービスの再利用性は、オンプレ環境のWebシステムであれ、クラウド環境のマイクロサービスであっても、同様の観点が通じるからだ。
たとえば、バージョニング戦略は、まさにソフトウェア構成管理と同じ。
後方互換性を見極める、Javaの非推奨(deprecated)のアノテーションのように廃止されたAPIは使わない、枯れた最新バージョンを使う、定期的にパッチ収集とパッチ適用の運用ルールを定める、とか、どこでも同じ。

しかし、マイクロサービスの本質はそういう所ではないはず。

【2】マイクロサービスを僕が理解できない原因は2つあると思っている。
まず、マイクロサービスを実装したモデルを考えようとすると、AWSサービスを使った実装を考えることが普通。
しかし、AWSサービスに特化しすぎると、AWSはサービスが多すぎて、どの場面にどのサービスを使うと良いのか分からなくて、混乱してしまい、何が重要なのか分からなくなる。

他方、AWSサービスのような具体的なサービスを外して、抽象的なマイクロサービス設計技法を考えると、逆に具体的なイメージが思い浮かばず、ふわふわした議論になってしまう。
オンプレ環境の経験を元に比較理解しようとするだけで、その本質までたどり着けない。

マイクロサービスの直感的イメージは、一昔前のSOAPでやり取りするWebサービスとほぼ同じと思っている。
現在なら、SaaSはほとんどがマイクロサービスで実装されているのではないだろうか。
たとえば、検索サービス、顧客サービス、商品サービス、在庫サービスなど、リソースやイベントの単位で区切られたドメインをマイクロサービスへ分割し、それらの間はRESTでデータをやり取りし協調しながら1つのユースケースを実現しているイメージ。
だから、マイクロサービスだからといって、そんなに難しかったり、高尚な概念でもないはず。

では、現代のクラウド上のマイクロサービス設計では、かつてのオンプレ環境のWebサービスと何が異なるのか?
ここさえ抑えれば理解できる、と思える本質的内容は何なのか?

【3】「絵で見てわかるマイクロサービスの仕組み」を読みながら、理解したことを書いておく。
今の自分のレベルではこれくらい噛み砕いたレベルでないと理解しにくかった。

絵で見てわかるマイクロサービスの仕組み」で自分に響いた内容は3つ。

【4】1つ目は、マイクロサービスは、数秒後から数時間後に動機が取れていればいいとする結果整合性が許容できる場面で活用すべき。
つまり、マイクロサービスではACID特性を厳格に守るのは難しいし、そういう場面では有効とは言えない。

よって、マイクロサービスが使えるユースケースは、業務が並列処理で動作しても良いケース、頻度は少ないが一時的にアクセス数や負荷がかかる時にCPUやメモリを動的に増やすスケールアップやサーバ台数を動的に増やすスケールアウトするケースなどだろう。
すなわち、性能要件を動的に拡張したいケースが当てはまるのではないか。
AWSやAzureのようなクラウドであれば、そういう拡張は、クラウド基盤が提供するマネージドサービスで簡単に実現できる。

一方、デメリットは、ACID特性ではなく結果整合性でしか担保しないので、基幹系システムでは難しいかもしれない。
たとえば、あるマイクロサービスで障害が起きてデータの不整合が発生した時、ロールバックをDBMSやフレームワークではなく、自分たちで作り込む必要があるかもしれない。
絵で見てわかるマイクロサービスの仕組み」では、異常系処理やロールバック処理を補償トランザクションで実現する方法が紹介されていた。
この辺りは実際の実装方法がよく分かっていないが、結局、自分たちでフレームワークを組み込んでいるのと同じような印象を受ける。

【5】2つ目は、コンテナオーケストレーションは、複数コンテナをクラウド基盤のAPIやマネージドサービスで制御する設計思想であること。

絵で見てわかるマイクロサービスの仕組み」では、コンテナ<Pod<ノードの順でグループ化されていた。
すると、複数のコンテナを手動で管理するのは面倒だし、ミスも多くなる。
また、頻度は少ないがアクセス数が一時的に増える場合にスケールアウトするようにコンテナを動的に増やす場合、コンテナのIPアドレスは一時的に付与されるので、管理する手法も特有の考え方が必要になるだろう。
よって、複数のコンテナをAPI経由のプログラムで一括管理したくなる。

そこで、コンテナオーケストレーションという概念で包括的に管理する。
絵で見てわかるマイクロサービスの仕組み」では、コンテナオーケストレーションを適用するユースケースとして、
・コンテナの作成とデプロイ
・負荷に応じたスケールアウトやスケールダウンやロードバランシング
・ホストやコンテナのヘルスチェック
があげられてたい。
つまり、動的にコンテナを作成しデプロイして、負荷に応じてスケールアウト・ダウンし、負荷分散させる。
また、コンテナのヘルスチェックのように、サーバー監視の管理サービスも実現してくれる。

コンテナオーケストレーションの実装例としてKubernetesがあげられている。
Kubernetesの優れた汎用的な機能のおかげで、AWSでもAzureでも一般的なクラウドにもコンテナ群をそのまま移行できる、という発想なのだろう。
コンテナの実装は、yamlやJasonなどでドメイン特化言語のように記載されて実現されるのだろう。
それゆえに、yamlなどのドメイン特化言語で、マイクロサービスのコンテナ群を全て実装すれば、検証環境であれ本番環境であれすぐにクラウド上に実装できるはず。

ではそれで全ての問題が解決するのか?
変化の早いビジネス環境において、マイクロサービスを組み合わせることで即座に稼働しやすいだろうが、複雑性は増すだろう。
数多くのコンテナを協調させながら稼働させるには、コンテナの中身を記載したyamlは相当複雑になるだろう。
一昔前に、Antでビルド&デプロイのタスクを書いていた時、宣言的に書いて楽だなと思っていたのに、環境が増えるごとにIF文がAntタスクに紛れ込んでどんどん複雑化したような経験を思い出す。
たぶん、それに似たような事象がKubernetesでも起きるのではないか、と思ったりする。

【6】3つ目は、サーバレスアプリケーションはBPMNのようなワークフローに並列処理を組み合わせたワークロードみたいなものではないか、と思う。

絵で見てわかるマイクロサービスの仕組み」では、サーバレスアプリケーションの基本アーキテクチャは、BaaSとFaaSの2種類があげられている。
BaaSは外部サードパーティのサービスを使うパターン。
FaaSはビジネスロジックをイベントドリブンで実装するパターン。

BaaSはたとえば、Googleアカウント認証やTwitter認証などの外部認証サービス、PayPalのような外部決済サービスがあげられるだろう。
外部サードパーティサービスの方がセキュリティ要件も性能要件もいいならば、そちらのサービスを利用することで、ユーザの利便性も増すだろう。
他方、ユーザ認証やクレジットカード情報を自社システムに持たないデメリットがあるので、顧客情報をより包括的に収集できないデメリットもあるだろう。

FaaSは、BPMNのようなワークフローに並列処理を組み合わせたワークフローに思える。
マイクロサービスをつないで、イベント駆動でマイクロサービスをキックし、一連の業務が流れる感じ。
その場合、並列処理で動くので、商品を購買している間に、検索したり、在庫に問い合わせたりして並列で動かすケースもあるだろう。

サーバーレスアプリケーションはFaaSを想起させる。
AWSならLambdaになるのだろう。
メリットは、アプリケーション開発者はアプリ層のマイクロサービスの実装だけに特化すれば良く、インフラ基盤は考えなくてもクラウド基盤がマネージドサービス等で勝手に管理してくれる、そういうイメージなのだろう。

他方、開発時のデバッグや障害時の復旧はかなり面倒になることが想像される。
複数のマイクロサービスを通したシステム全体テストをやるには、ローカルPCでは無理で、クラウド上に本番同等の検証環境が必要になるだろう。
その分コストも増える。
また、イベントドリブンで連なる一連のマイクロサービスのうち、途中のマイクロサービスで障害が発生して、データの同期が取れなくなった場合、データのロールバック処理は複雑になるだろう。
本来は、データ復旧や障害復旧もクラウド基盤が勝手に自動で上手くやって欲しいが、手作業で設計して入り組んだ複雑なワークフローになっていると難しいだろう。

そんなことを考えると、全てがバラ色の世界ではないだろうと思う。

【7】マイクロサービス設計は従来のアーキテクチャ設計と何が違うのか?

違いの一つは、マイクロサービス設計では、インフラ基盤をクラウドのマネージドサービスで自動化したり、APIで監視サービスやコンテナオーケストレーションを実装できる点にあるだろう。

つまり、従来のオンプレ環境のインフラ基盤は、アプリ開発者の手によって操作できるようになった点が違いになるだろう。
アプリ層からインフラ層まで全て、アプリ開発者がコントロールできるようになったこと。
そんな開発者はフルスタックエンジニアと呼ばれるのだろう。
また、DevOpsとは、そういうフルスタックエンジニアがアプリ層からインフラ層までコントロールして、開発も運用も一体化するプロセスを指すのだろう。

| | コメント (0)

2023/11/12

「ソフトウェアアーキテクチャ・ハードパーツ」の情報リンク~マイクロサービスの設計技法の課題は何なのか

ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析を読んでいて、まだ中身を理解できていない。
ネット上の感想記事を自分用にリンクしておく。

【参考】
『ソフトウェアアーキテクチャ・ハードパーツ』 - Don't Repeat Yourself

(引用開始)
また、最近話題になっていた『ソフトウェアアーキテクチャの基礎』(以降、「基礎」)を執筆した著者陣が書いたもう一冊の本でもあります。
「基礎」はアーキテクトとしての姿勢や、それぞれのアーキテクチャの簡単な概要が中心でしたが、この本はより実践に近く方法論寄りです。「基礎」が「What」を扱うとすれば、本書は「How」を扱うといった関係性でしょうか。
(引用終了)

(引用開始)
現代ではデータをどのように設計し、分割しつつ整合性を保って保管しておくかといった一連の流れの重要度が増しています。この問題についても本書は拾い上げるよう努力しています。[*1]
従来のアーキテクチャの議論では、マイクロサービスはどう分割するかとか、コードの関心事がどうこうとかそういったアプリケーションに限った範囲が中心だったように私は思っています。が、そうではなくデータをどう分割、配置、保管していくかといった問題についても議論に含めるようにしています。
(引用終了)

『ソフトウェアアーキテクチャ・ハードパーツ』完全に理解した - Mirai Translate TECH BLOG

(引用開始)
一言で言うと
「マイクロサービスの大きさと通信方式をどう決定するか」について書かれた書籍です。
(引用終了)

ソフトウェアアーキテクチャ・ハードパーツ - Forkwell Library #12に参加してきた - 天の月

(引用開始)
レガシーで大規模なモノリシックシステムをどう解決していくか?というのを物語形式で紹介してくれているということです。

ソフトウェアの中でも土台となるような部分の決定は「モノリシックなシステムをどう分解していくか?」で前半部分に表現され、「ソフトウェアアーキテクチャをどう決めるか?」は分散システムで直面する難しい問題をどのように決定するか?で後半部分に表現されているということです。

もう少し具体的に言うと、前半部分は戦術的フォークとコンポーネントベース分解を中心に登場人物がトレードオフ分析を行なっている様が描かれており、後半部分は、粒度分解要因と粒度統合要因のバランスによって決定されるという前提をもとに、分解をどこまでするかが具体的に描かれているそうです。
(引用終了)

「ソフトウェアアーキテクチャの基礎」読書感想

【1】「マイクロサービスの大きさと通信方式をどう決定するか」が根本テーマであるとすれば、マイクロサービスの設計上の課題や留意点がテーマになる。

2020年代の現在では、マイクロサービスの実装はAWSなどのクラウド基盤が前提条件だろう。
AWSならEC2ではなく、CloudFormationを使って各種サービスを組み合わせて一体化したシステム設計をするのではないか。
一方、オンプレ環境のシステムでは、弾力的なスケーラビリティ向上、つまりスケールアップやスケールアウトを動的に変更するのは非常に難しい。
逐一サーバースペックをサイジングしてどれだけのスペックを持つべきか見積もりして導入するまでに非常に手間がかかる。

では、マイクロサービスの落とし穴はどこにあるのか?
マイクロサービスの利点や美味しいメリットを得るにはどんな留意点があるのか?

モノリシックな基幹系システムやモノリシックな巨大なシステムをビジネス上の観点でサービスごとに分割して、分散サービス化した時、それぞれのサービスの粒度は小さくなるので運用保守しやすくなる点もあるだろう。
昨今のDevOpsの観点では、小さな開発チームが設計や開発から運用までを担当する流れなので、チームが担当するシステムのサイズは小さい方が実現しやすい。

一方で、複数のサービスを連携して初めて、顧客が満足する1つのユースケースが成り立つような場合、途中でサービスが停止すると成り立たなくなる。
分散サービスのアイデアは20年以上前のCORBAやEJBからずっと言われていては失敗してきたが、クラウド基盤でようやく実現可能な設計手法になった面もあると思う。
僕はまだAWSやクラウド基盤のことは無知なので、今までのオンプレ環境で構築するシステム設計とは違った観点がマイクロサービスの設計にはあるのだろうと思う。

理解できた内容はBlogに残しておこうと思う。


| | コメント (0)

2023/10/14

パッケージ原則とクラス原則の違いは何なのか

パッケージ原則とクラス原則の違いについて考える時があった。
直感的なラフなメモ。

【参考】
パッケージ設計の原則を本で学ぶ - Qiita

イラストで理解するSOLID原則 - Qiita

パッケージ原則を見ると、パッケージの凝集度3つ、結合度3つの観点に分けられる。
その内容は、クラス原則であるSOLID原則をパッケージ版に拡張したように思える。

実際、単一責任の原則はパッケージの凝集度に関連するし、開放閉鎖原則はパッケージ版も同様だ。
インターフェイス分離の原則やLiskocの置換原則は、パッケージの結合度に関連してくる。

ただし、その違いはある。
1点目は、パッケージやコンポーネントの観点では、リリースできる単位が再利用できる観点と同一になる原則が最も重要になる。
理由は当たり前で、リリースして他ユーザが使えるようにするからには、他の人が再利用できる観点と同一にならざるを得ないから。

リリースモジュールは単独で動くものである一方、クラスは単独では動作できず、複数のクラスを結合して初めて一つの画面や帳票、バッチなどの機能を形成する。
この違いは大きく、再利用の観点も他者に利用してもらえる観点と、他者に読んで保守してもらえる観点の違いになる。

もう1点は、パッケージとクラスを保守する人の単位が異なる点だ。
クラスを修正する人は基本的には1人であり、コードのレビューアも関わるだろうが、1人が責任を負う。
その修正履歴はコミット履歴に残る。

一方、パッケージを保守する単位はチームや部署の単位になる。
普通は、リリースモジュールの単位はサブシステムであるから、システムごとに担当する部署があるだろう。
大規模な基幹系システムを持つ企業であれば、数多くの部署ごとに担当するシステムが異なるだろう。
つまり、サブシステムというリリースモジュールを保守するのは複数人であり、アプリ層だけでなくフロント層、インフラ層など数多くのメンバーが関わって初めて一つのシステムが動く。

すると、システム単位に開発チームが存在するので、コンウェイの法則に従うことになるだろう。
つまり、アーキテクチャ(システム)は組織に従うわけだ。
この特徴により、サブシステム間が部署間の壁となり、IFとなるので、IF連携は認識齟齬が起きやすいリスクが発生しやすい。
部署ごとにシステムが分かれることにより、システムは局所最適化されやすくなる。

そんなことを考えると、パッケージ原則とクラス原則は同じような観点が多い一方、クラス担当者やシステム担当チームの違いを認識することも必要だろうと思う。

| | コメント (0)

2023/09/30

パッケージ設計の原則の意義は変化しているのか

パッケージ設計の原則についてちょっと議論する場があり、色々考えるものがあった。
考えたことをラフなメモ書き。

【参考】
パッケージ設計の原則を本で学ぶ - Qiita

パッケージ設計6つの原則~ポイントは関連性/依存性/抽象度 | プレイン・プログラム

コンポーネントに関する6つの原則 - Qiita

【1】パッケージ原則6個の復習。

1. パッケージ再利用等価原則 Release Reuse Equivalency Principle
* 再利用の粒度はリリースの粒度と同じ
2. 共通閉鎖原則 Common Closure Principle
* クラスは共に変化し、共に存在する
3. 共通再利用原則 Coomon Reuse Principle
* 共に再利用されないクラスを同じグループに入れるべきではない
4. 非循環依存関係原則 Acyclic Depenedencies Principle
* パッケージ間の依存関係は循環してはいけない
5. 安定依存関係原則 Stable Dependencies Principle
* 安定している方向に依存する
6. 安定抽象原則 Stable Abstracttions Principle
* 安定したパッケージは抽象的であるべきだ

【2】パッケージ再利用等価原則が最も基本の原則と考える。

ちょっと昔のJavaシステム開発であれば、リリースモジュールwar/earがリリースの単位であり再利用の単位になる。
サブシステムごとにwar/earをビルドして検証環境でテストした後、オンプレの複数台のサーバー環境ごとに、複数のAPサーバーへwarを手動でデプロイしていた。
ロードバランサーからデプロイするサーバーを切り離して、1つずつwarファイルをデプロイして起動確認し、確認OKならば外部通信できるように設定していた。
つまり、そういう面倒な手動のリリース作業があった。

オンプレのサーバ環境にwar/earファイルをデプロイする単位は普通はサブシステム単位なので、そういう粒度で再利用しやすくする。
その場合、war/earファイルはできるだけサイズは小さい方がAPサーバ再起動時間も短くなるし、リリース作業も短くなるので、リリース作業ミスの確率も減らせる。

特に最近はAWSのようなクラウド環境では、サーバ環境そのものを使い捨てみたいにコンテナから自動生成するので、コンテナ(リリースする単位)のサイズが小さいほどサービスの再起動時間が短くなり、サービス停止時間も短縮化でき、顧客満足度も高くなる。
JavaGoldを取得した時に、モジュールの話で、モジュールサイズをできるだけ小さくしたい要望がある理由がそこにあると聞いて納得したことがあった。

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

Javaのモジュールシステムは複雑性をより増している: プログラマの思索

Javaのモジュールシステムの考え方をまとめてみた: プログラマの思索

【2】ただし、リリースモジュールの保守性や分割についてトレードオフがある点は理解できる。

実際、サブシステム単位にリリースモジュールwar/earをビルドする場合が多いので、普通はリリースモジュールのファイルサイズは非常に大きくなりがちだ。
なぜなら、リリースモジュールには、Apacheの共通ライブラリ、会社特有の共通ライブラリなどのJarという共通コンポーネントを多数含んでいるからだ。
同様に、RailsのようなWebアプリでも、bundlerの中には共通ライブラリGemを多数含んでいる場合が多い。

すると、リリースモジュールのファイルサイズを小さくしたくなる。
簡単に思いつくのは、リリースモジュールから他のサブシステムと共通で使う共通ライブラリは別出しして、デプロイする時は共通ライブラリは再リリースしなくて良いようにしたい。
APサーバ上に共通ライブラリを別で配置して事前ロードしておいたり、別APサーバ上に共通ライブラリを配置するケースも考えられるだろう。

メリットは、リリースモジュールのうち共通ライブラリは既にAPサーバにデプロイされているので再リリースは不要であり、リリースモジュールのサイズを小さくできる。
その分、ビルド作業時間、リリース作業時間を短縮でき、リリース作業ミスのリスクも減らせるだろう。

一方、デメリットは、共通ライブラリに手を加えた場合、既にデプロイ済みのサブシステムのwar/earファイルに影響が発生してしまう。
デグレがないか事前確認が必要だし、共通ライブラリがサブシステムのAPサーバとは別APサーバにデプロイされていて、共通ライブラリが複数のサブシステムから呼び出されているならば、複数のサブシステムに影響が発生してしまう。
共通ライブラリのリリース作業中にAPサーバを停止する事態が発生すれば、呼び出し側の複数のサブシステムで業務停止してしまうリスクが発生する。

また、共通ライブラリにサブシステムA向けのAPIを追加したり改修して、他のサブシステムB向けのAPIは触らない場合であっても、共通ライブラリをリリースする時にサブシステムAもBにも影響が発生してしまう。

だから、一般には、サブシステムごとに共通ライブラリを含んでリリースモジュールをビルドする場合が多いと思う。
すると、たとえば、サブシステムAの共通ライブラリXのバージョンは1.1、サブシステムBの共通ライブラリXのバージョンは1.2、みたいにコンポーネントのバージョンがサブシステムごとに違ってくる場合も発生するだろう。

つまり、サブシステムで利用する共通ライブラリのバージョン管理、構成管理が重要になってくる。
この仕組みがMavenであり、Railsならbundlerなのだろうと思う。
ライブラリやコンポーネントの構成管理というソフトウェアの複雑性をビルド管理の仕組みで補っているわけだ。

【3】では、昨今のアジャイル開発、DevOps、クラウドなどにより、パッケージ設計の原則の意義は変化しているのか?

メタな観点ではパッケージ設計の原則の意義は変わらない。
リリースモジュールは再利用できる単位であることは変わらないし、モジュールの分割方針やデプロイ方針も基本は変わらない。
しかし、具体的なリリース手順や開発プロセスは影響を受けていると思う。

例えば、SaaSビジネスでは、リリース作業時間は極力短くしたい。
リリース作業時間は広義の意味では、顧客に機能を提供するリードタイムと同じ。
BtoCのSaaSビジネスならば、機能改善の要件定義からリリースまでのリードタイムを短縮化する事は売上に直結する。
ちょっとした機能改善を即座にリリースできれば、顧客満足度も上がり、ユーザ数増加が売上につながるから。

また、特に昨今はクラウドでサーバーごとの仮想化するなどして丸ごとコンテナ化し、コンテナを使い捨てみたいにいくらでもデプロイできるから、リリース作業時間はできるだけ短くしたい。

これは、DevOpsの考え方と非常に相性が良いと思う。
DevOpsで開発チームがシステム運用と一体化したプロセスになるし自然にアジャイル開発になるはず。
つまり、アプリ開発者はアプリも開発するし、クラウド上でインフラ基盤もサーバー基盤もコンテナをプログラム化して自動配置できるようにすれば、開発も運用も一体化できるはず。

そして、リリース作業時間と言うKPIを開発チームが毎回計測し監視すれば、改善すべきか評価できるはず。
リリース作業時間、ビルド時間、デプロイ時間などはアジャイル開発の主要なメトリクスの一部と捉えられるだろう。
システム停止やデータ移行の時間も含めてリリース作業時間に3日間かかっていたのを、1時間で終わらせたり、わずか5分で終わらせれば、その分システム停止時間も短くでき、顧客の業務や顧客の操作時間への影響を減らせる。

そんなことを考えると、アジャイル開発やDevOpsという考え方は、サーバの仮想化やクラウドの技術のおかげで進化している部分も大きいのだろうと思う。
こんなことは既に当たり前の考え方と思うけれど、アプリ層の設計技法もインフラ基盤の仮想化技術に相当影響を受けているのではないか、と思う。

| | コメント (0)

2023/08/21

QAエンジニアの役割は開発チームのガードレールみたいなものという考え方

@kz_suzukiさんのツイートからQAエンジニアの役割は開発チームのガードレールみたいなものという考え方を知ったのでメモ。

【参考】
自信を失っていた人間が1人目QAとして再スタートを切るお話|MNTSQ, Ltd.(モンテスキュー)

Kazu SUZUKIさんはTwitterを使っています: 「一人目QA物語はどれも勉強になるな。「最後の砦」意識から、「ガードレール」としてのQAに考えを進化させていく様子が良いなあ。/ 自信を失っていた人間が1人目QAとして再スタートを切るお話|MNTSQ, Ltd.(モンテスキュー) https://t.co/WL4Do4swkJ」 / Twitter

「ゲームをテストする バグのないゲームを支える知識と手法」の感想: プログラマの思索

(引用開始)
様々な経験を経た結果、「最後の砦」ではなく「開発チームのガードレールと動力」が私の中で目指すQA像になっています。
※「ガードレール」は前職の同僚が言って「これや!!」ってなった言葉でした。

開発のスピードを上げていくために、品質観点から改善点を探し、
スピードを上げすぎたことにより崖から落ちてしまわないように守る人材でありたいと今は思っており、実現のために日々奔走しているところです。
QAは品質にこだわることで開発のスピードを落としてしまいがちと思われがちですが、品質を守ることによってエンジニアの方がより開発しやすく、スピードをあげることができると思っています。
(引用終了)

QAエンジニアのキャリアはあまりイメージが付いてなかった。
せいぜい、開発者やプロマネが開発できなくなってテスト分野に移るみたいなイメージしか正直持っていなかった。

QAという仕事はどうしても開発チームのサポート役という役割になりやすい。
その分、存在意義に悩むだろうなと思ったりもする。

しかし、QAエンジニアは、品質を守る最後の砦という役割だけでなく、品質を守ること開発チームが開発しやすくする環境づくりを支援するという役割がある。
こういう考え方が新鮮だった。
確かに、システム開発のQCDのバランスを保ちながら、品質が良ければ、他の要素は自然に上向く。

心理的安全性はQAエンジニアが守る、という観点もあるのかもしれない。

| | コメント (0)

2023/07/02

テストアーキテクチャ設計モデルとJSTQB概念モデルの比較

平鍋さんのテストアーキテクチャ設計モデルと、自分が書いてみたJSTQB概念モデルを比較してみた。
気づきをラフなメモ。

【参考】
JaSSTで話題になったテスト設計をモデル化してみた - Qiita

JSTQBのテストプロセスの概念モデルを描いてみた: プログラマの思索


テストアーキテクチャ設計モデルはかなり抽象化されたモデルと思う。
テスト評価層、テストアーキテクチャ設計層、テスト種別層、テストケース層に分かれている。

テストアーキテクチャは、システムアーキテクチャに基づくテスト設計かな?
たとえば、システム特性ごとにテストアーキテクチャは全く異なる。
組み込みソフトウェアであれば生命に関わるようなリスクは極力避ける必要があるから、安全性の観点のテスト設計が多くなるだろう。
一方、マイナンバーカードシステムのようなBtoCの基幹系システムであれば、個人情報保護が非常に重要だから、セキュリティの観点のテスト設計が多くなるだろう。
つまり、テストアーキテクチャはシステム特性に大きく依存しているはず。

テストアーキテクチャはテスト評価層で評価される観点が興味深い。
テストアーキテクチャ記述とステークホルダーが結びついている。
つまり、マネージャ、利用ユーザ、プロダクトオーナー、品質保証部門などの観点でテストアーキテクチャ記述はレビューされて評価される。
ステークホルダーごとにレビュー観点は異なるから、そういう視点が反映されている。
この点は非常に重要だ。
「このテストは誰のためにあるのか」という問いにつながるからだ。

テストコンテナという概念でテスト種別を表す点も興味深い。
最初に見た時、テストコンテナとは何だろう?と思った。
テストコンテナは、コンテナ分割方針によってグループ化されており、コンテナ分割方針はテストレベル、テストサイクル、テストタイプなどがある。
つまり、テストコンテナは、工程や品質特性、テスト期間の観点で組み立てられたテスト方針のように思えた。
おそらく、システム特性に応じたテストアーキテクチャを具体的に実装する場合、具体的にどんなテストが必要になるのか、というテスト内容が含まれていると考える。
すなわち、システムやプロジェクトごとにテスト方針がテーラリングされていることを示しているのだろう。

テストタイプにソフトウェア品質特性が関連付けられているのもミソだ。
つまり、8つのソフトウェア品質特性の観点に対応付けられた非機能テストがあることを示している。
たとえば、性能テスト、負荷テスト、耐障害性テスト、セキュリティテスト、移植性テストなど。
この考え方は「ソフトウェアテスト教科書 JSTQB Foundation 第4版 シラバス2018対応」にもあったから、自分のJSTQB概念モデルに取り入れさせてもらった。

テストケース層でテストスクリプトが中核にあるのは、自動テストを意識されているからだろうと思う。


一方、自分のJSTQB_テストプロセスの概念モデルはかなり具体的だ。
テストプロセス層とテスト成果物層で分けている。

テストプロセス層では、テストプロセスを中核として、テストプロセスを分析する観点が盛り込まれている。
テストプロセスとは、テスト計画~テスト完了までの一連のテスト活動から成り立つ。

そのテストプロセスは、テストレベルという工程ごとにコンポーネントテスト、統合テスト、システムテストなどで具体化される。
また、テストタイプというテスト種類ごとに、性能テスト、負荷テスト、使用性テストなどの品質特性ごとのテストプロセスもある。
一方、テストプロセスはテスト戦略で規定される。
テストアプローチはPJごとのテスト戦略のインスタンスとみなすから、テスト戦略とテストアプローチは継承関係にした。

テスト成果物層は、主にテスト項目書から成り立つテスト成果物だ。
テスト項目書、つまりテスト仕様書は、下記の観点で分解してみた。

テストアイテムとは何か?概要や定義、現場での使われ方について解説

テストケースを各要素ごとにばらす。
・テスト対象=対象画面・帳票
・テストアイテム=画面・帳票項目
・テストスイート=特定のテストサイクルで実行されるテストケースやテスト手順のセット
・テストサイクル=テストの開始日時、終了日時

ソフトウェアテスト教科書 JSTQB Foundation 第4版 シラバス2018対応」では細かい内容が多く、現場で使われる用語と違うので、概念モデルを書かないと理解しにくい。

たぶん、自分のJSTQB_テストプロセスの概念モデルをもっと抽象化して洗練させれば、テストアーキテクチャ設計モデルとマッピングできるだろうと直感している。
この辺りは気づきを残していく。

| | コメント (0)

2023/06/24

パターンカタログよりもモンスターカタログの方が面白いね #jasstkansai

Jasst関西がオフライン開催だったので10年ぶりに参加してきた。
感想をラフなメモ。

【参考】
JaSSTソフトウェアテストシンポジウム-JaSST'23 Kansai

知識は経験よりも大切か、経験は知識よりも勝るのか、SECIモデルは相互作用を語る: プログラマの思索

「大人の学びパターン・ランゲージ」の感想~知識と経験を行ったり来たりするタイミングを大切にする: プログラマの思索

現場の経験知をパターン言語にするコツが分かった #agileto2014: プログラマの思索

パターン言語の構造と事例集: プログラマの思索

SECIモデルは知識の再利用モデル、または、実践知を生み出すモデルだ: プログラマの思索

【1】今回のテーマは「思考停止」。
正直難しいテーマだったかなと個人的印象を持った。
基調講演の山口鉄平さんの話を聞くと、説明に苦労されている印象があって、本来は「ソフトウェアテストをカイゼンする50のアイデア」本から色んな改善事例を出してもらえるともっと聞きたかったのにと思った。

今の日本の社会情勢であれば、「思考停止」というテーマはたくさんの事象が出てくるだろう。
たとえば、円安やインフレ、少子高齢化による社会保障制度の不安、コロナ補助金不正、マイナンバーカードの名寄せ問題、EV車やAIに対応できていない製造業やIT企業、を見れば「思考停止」の事例はいくらでもあるだろう。
つまり、そういう問題に対し、本来の課題(イシュー)は何なのか、その課題を解決する時に一番効果のある対策は何か、予防策は何か、まで突き止めて考えなければならないのに、前提条件や制約条件を無視した議論がすごく多い。

一般に、日本の組織論で有名な「失敗の本質」本を読めば、日本人の「思考停止」の例はすぐに2つは思いつく。
1つは、個人では意見を持っていても、同調圧力に流されて集団浅慮やリスキーシフトに陥ること。
もう一つは、一般兵士のような下級レベルの労働者や兵士は真面目で優秀だが、戦略の目的に合致しない行動を取っているために、いくら真面目に働いても生産性や投資効果が低いこと。
野中先生が指摘した日本人の弱点は、1945年当時から80年たった今でも変わらない。

akipiiさんはTwitterを使っています: 「日本人が思考停止に陥りやすい例が自分のイメージと違っている気がした。日本人は集団浅慮に流されて自分の意見を言わないとか、一生懸命働くけど生産性を意識せず働く場合が多いんじゃないかな? #jasstkansai」 / Twitter

こういう思考停止の事例を分析するには、なぜなぜ分析が結局使われると思う。
なぜなぜ分析で自分の言動を問い詰めて、最終的にはその人の油断、プレッシャー、焦りなどの心理背景まで突き止められるのではないか、と思う。

OL参加者の意見として、フレームワーク思考を習慣的な思考と考えて、思考停止になっているのではというツイートもあって面白かった。

akipiiさんはTwitterを使っています: 「#jasstkansai なるほど、フレームワーク思考は習慣的な思考と捉えるのか。SECIモデルならどれに相当するのか?形式知を組み合わせる連結化?形式知を暗黙知にする内面化?」 / Twitter

【2】今日のJasst関西で最も印象に残ったのが、「思考停止からの脱出 ~ あなたの"問い”が自律へと導く ~」ワークセッション。
テーマは「思考停止を題材にして、問題事象をモンスターで書いてみよう」。

「思考停止」というテーマを各人の体験から問題事象を洗い出し、それらの問題事象にモンスターとして名前付けする。
そのモンスターには、名前とモンスターの絵があり、モンスターのプロフィールとして得意技・どんな時・他の特徴という説明文が付与される。
そのモンスターに対し、必殺技でやっつける、という流れ。

僕は「打合せ大好きマン」というモンスターを書いてみた。
伝わるかな?

20230624_jasst_kansai

これはアンチパターンと言えるだろう。
つまり、モンスターの名前はアンチパターン名。
得意技は問題事象。
どんな時は、問題事象が発生するタイミング。
他の特徴は、問題事象の影響事例。
必殺技は、解決策に相当するだろう。
フォースに相当する項目があればなおいいね。

僕もパターンは好きだし、パターンを自分で作れないか、パターンカタログのようなものを作れないか色々考えていた時期があった。
しかし、深く考えるほど難しいなと思う。
モンスターにアンチパターンを当てはめると、ロールプレイングゲームのように気楽な気持ちでパターンカタログを作り出すことができる。

この発想は他のワークショップでも使ってみたいなと思う。
プレインステーションなどのゲーム経験が深い人ほど馴染みやすいかもしれないから。
もっと気楽にパターンを考えてもいい。

【3】久しぶりにオフラインでコミュニティに参加して気づいたことはいくつかある。

1つ目は、参加者に若い人もいるけれど、年齢層が割りと高そうなこと。
アンケートでは、SE経験が10年以上の人が参加者の半分を占めていた。
本来は20~30代の人たちが半分以上を占めていて、経験が少なくてもノリが良くて活気があるのが普通だが、ちょっと落ち着いていた感じ。
久しぶりに会った方と話していたら、最近は若い人が少ないですよ、とのこと。
昨今の日本社会の情勢である少子高齢化が出ているのだろうか?

2つ目は、オンライン開催のチャネルが勉強会コミュニティで必要になってきたこと。
コロナ禍を経て、開催側もオンライン開催の手段がすごく簡単と分かったし、参加者も簡単に集めやすいと分かった。
参加者もオンライン開催であれば、スマホさえあれば作業しながらでも聞ける。
わざわざ交通費を払って時間を拘束させる必要もない。

今後の勉強会の運営は、Jasst関西のようにハイブリッド開催が当たり前になってくるだろうと思った。

| | コメント (0)

より以前の記事一覧