IT本

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)

2023/12/10

「GitLabに学ぶ 世界最先端のリモート組織のつくりかた」の感想

GitLabに学ぶ 世界最先端のリモート組織のつくりかた ドキュメントの活用でオフィスなしでも最大の成果を出すグローバル企業のしくみを読んだ。

【0】リモートワーク主体の組織運営をどうやってやるか、PDCAで整理した本と思う。
とは言っても、リモートワーク普及に奇策はない。

【1】Planでは、ガイドラインを定めて形式知化する。
リモート責任者など組織体制も整備する。
経営層が率先してリモートで働く。
利用するツールは絞り込む。

他にもいくつか施策はあるが、割りと形式知化を重視している点が印象に残った。
リモートだからこそ、対面でのやり取りがないので、どうしてもローコンテキストな対話にならざるを得ないだろうから。

コミュニケーションルールも定める。
非公開情報ではSAFEアプローチを取る。
Sensitiveなのか、Accurateなのか、Financialなのか、Effectなのか、の判断基準を定めて、情報を公開しても良いのか判断する。

【2】Doでは、従業員の動機づけ要因、衛生要因を整備する。
リモートに合った組織文化が根付くように実行する。
心理的安全性を重視する。
人材戦略、つまり従業員の動機づけ要因では、ダイバーシティ、インクルージョン、ビロンギングを重視する。

ダイバーシティは、人種や性別、年齢、宗教、性的指向などの多様性を認めること。
インクルージョンは、マイノリティもマジョリティもすべての従業員が活躍できる状態を目指すこと。
ビロンギングは、自分の居場所はここである、という感覚。
帰属意識みたいなものかな。
一昔前の日本の会社の愛社精神みたいなもの。
今風ならエンゲージメントかな。

面白い点は、ビロンギングを重視していること。
従業員の流動性が高くても、帰属意識を重視しているのはなぜか。
たぶん、マズローの欲求5段解説で考えれば、帰属欲求が満たさなければ、承認欲求や自己実現を満たす欲求に達しないからだろう。

他にも、イテレーション、透明性も重視している。
この辺りはアジャイル開発の文化に近いので理解しやすい。

コンディショニングを実現する章は衛生要因の話だろう。
長期休暇制度、人間関係の構築、運動の推奨。

【3】CheckとActoinでは、KPIを用いた評価制度を作り、イテレーションごとにフィードバックを回していく。

SMARTな目標を定めて成果を評価する。
GitLabで活躍できる能力や意欲があるのに、マネジメントの問題で活かしきれない状況を避けるために支援する。
マネージャはメンバーを支援する。

優れたマネージャのコンピテンシーは事前に把握しておく。
感情的知性(EQ)、コーチング、衝突の解決、フィードバック文化の体現、高業績チームの構築。

Actionでは、メンバーに精神的成長と技術的成長を促す。
技術的成長を促すには、現状のスキルレベルと目指すスキルレベルの可視化が不可欠。
しかし、日本企業はスキルマップが画一的だったりそもそもなかったり、メンバーのスキル保有を把握していない。

能力開発のプロセスでは、コルブの経験学習モデルが有効。
具体的経験→内省的観察→抽象的概念化→積極的実践のサイクルを回して、能力を高めていく。
日本と海外の差は、抽象的概念化と積極的実践の部分だろう。

抽象的概念化では、普通の業務では既に他の人や過去の人が既に実践しているから、ノウハウや問題解決の手順は既に知られている。
しかし日本ではわりと形式知化されていないので、一人で暗中模索して試行錯誤しながら解決策を導く手間がかかる。
海外では形式知化されたマニュアルや書籍、トレーニングが充実しており、それらを通じて先人が得た整理された知識まで早期に到達することができる。

積極的実践では、せっかく研修したのに、研修に対して意味がないと感じたりネガティブな印象を持ったりする。
座学の場合は特にそうだろう。
だから、研修を実務に適用し、研修転移を進めるために、マネージャや周囲が定期的にコミットメントしたりフィードバックするのが大事になる。
GitLabでは、個人開発計画を作成し、メンバーのキャリア開発について議論しているという。

【4】そんな話を読むと、GitLabではリモートワークを単に活用しているだけでなく、包括的にメンバーの意識付けからスキルアップまで組織的に考えていることが分かる。
おそらく長年の試行錯誤を経て、3000ページにのぼるGitLabのガイドラインにまとめられたのだろう。

また、この本では、既に知られているビジネスやマネジメントのフレームワークがふんだんに使われていて、情報が整理されて理解しやすいと感じた。


| | コメント (0)

『世界一流エンジニアの思考法』が学べる環境を手に入れてかつ継続する方法の感想 #devboost

デブキャリで牛尾さんの講演を聞いた。
世界一流エンジニアの思考法」を出版されている。

Developers CAREER Boost 2023 (2023.12.09)

デブキャリでこっそりシェアする三流エンジニアが『世界一流エンジニアの思考法』が学べる環境を手に入れてかつ継続する方法

話が上手いし面白い。
牛尾さんには15年以上前にXP祭り関西2006でXP寸劇にも参加して頂いたこともあり、あの頃の雰囲気を思い出した。

Subject: [ruby:1293] XP祭り関西2 006 in ワッハ上方

XP祭り関西2006 in ワッハ上方 (プログラミング C# - 翔ソフトウェア (Sho's))

【告知】XP祭り関西2006 in ワッハ上方: プログラマの思索

牛尾さんの講演の気づきは3つ。

1つ目は、常日頃から職歴を更新して、アピールできるレベルに随時ブラッシュアップすること。
牛尾さんはアジャイルのエバンジェリストでは超一流だったが、自身曰く、プログラマのスキルは低かった。
だから、マイクロソフトでプログラマになるべく、Githubに書いてアップしたり、エンジニアが来日したらAttendeしたり、色々アピールした、と。
そのためにも、職歴に、第三のスキルを常に磨いて記載するようにした、とのこと。
職歴は、LinkedInのプロフィールみたいなもの。
私はこういう人です、こういうスキルがあります、こういう職歴を積んできました、とアピールできるもの。
自分がより良い職業や職場に行きたいなら、そういうアピールできるものが必要。

一方、会社は「こういう人が欲しい」というジョブディスクリプションを出す。
それを見て、そのジョブディスクリプションに応募する。
その時に、会社が提示したジョブディスクリプションに対し、2つ上のレベルを目指すようにする。
そうすれば他人の目を引くことができるから。

牛尾さんほどの優れたエバンジェリストのレベルであっても、地道に努力されているんだなと思った。

2つ目は、何をやらないか、が大事なこと。
Be Lazyと言っていた。

Xユーザーのakipiiさん: 「Be Lazy。何をやらないか。物量よりもインパクトが大事。日本人は勤勉重視、努力重視なので価値観が正反対だよね。染み付いた価値観を捨てるのは難しい。 #devboost」 / X

どうしても日本人は「努力」が好きなので、全部をやろうとしてしまう。
捨てるのが難しい。

物量よりもインパクト重視。
たくさんできるよりも、何か一つ目立つものが成果として出れば十分。
そういう発想が大事。

3つ目は、「チャンスの時に受けないと次に進まない。受けましょう。」

Xユーザーのakipiiさん: 「牛尾さんが最後に伝えたこと。チャンスの時に受けないと次に進まない。受けましょう。つまり、挑戦しましょう。実力がなくても英語力がなくても関係ないと。 #devboost」 / X

今、牛尾さんはマイクロソフトでAzureファンクションのプログラマをされていると聞いた。
そのきっかけは、米国チームから、新卒に教えるのが得意なエンジニアで採用されたのがきっかけ。
そこからチャンスを掴み、今プログラマとしてバリバリ働かれている。
気後れせずに、チャンスをつかめ、というメッセージとして受け取った。

牛尾さんがすごいなと思うのは、40代を過ぎてから、英語を習得し、エバンジェリストからプログラマへキャリアを転換されたこと。
今までの実績や経験をすべてアンラーニングして一からやり直されたのはすごいと思う。
普通は、今までのキャリアやスキルをベースに深めていくのが普通であって、最初からやり直すのは大変。

本当に自分がやりたいことは何なのか、を深く考えて実行されたのだろうと思う。

| | コメント (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/21

概念モデリングや設計原則は進化しているのか

最近、概念モデリングや設計原則の勉強会に参加して色々気づきがあった。
ラフなメモ書き。

【1】「実践UML第3版」を勉強会で読み始めた。
僕は「実践UML第1版」を購入して読んでいた。
思い出せば20年前になるのか。
そこから第2版も買ったし、最近第3版も買ってみた。
中身は変わってきているが、版を重ねるごとにオブジェクト指向設計の内容が洗練されて、RUPという開発プロセスに準じるように設計から実装、移行まで一気通貫する。

2020年代の現在、「実践UML」を再度読んで気づきがいくつかある。

【2】1つ目は、RUPはもう不要と思う。
スパイラル開発プロセスはWF型開発からの脱却という観点で重要だったが、Scrumを中心としたアジャイル開発が全盛の時代だから、わざわざテーラリングが必要な重厚長大なRUPを利用するメリットはないと思う。

【3】2つ目は、モデリングに必要なUMLのダイアグラムの力点が変わっていること。
「実践UML第1版」では、以前は協調図(コラボレーション図)、今のコミュニケーション図がオブジェクト指向設計で重要です、と主張していた。
理由は、コラボレーション図を描くことで、機能をどのクラスに割り当てるべきか、凝集度や結合度、生成などの観点で検討する時に有用だから。
オブジェクトからたくさんの指示が出ていれば責務が多すぎるね、と気づきやすいから、と。
当時の自分はすごく納得した。

実践UML第2版実践UML第3版では、クラス図やシーケンス図で説明する場面が多い。
コラボレーション図の話はなくなっていた。
たぶん、UMLの中でも重要度が下がったためだろう。

しかし、機能の割り当ての考え方は普遍的と思う。

【4】3つ目は、GRASPパターンは「情報エキスパート」パターンが一番大事ということ。
このパターンが「実践UML」の重要ポイント。

機能や責務はどのクラスに割り当てるべきか?
責務の遂行に必要な情報を持っているクラス、すなわち情報エキスパートに責務を割り当てるべきだ。

つまり、責務の遂行に必要な情報を自身のクラスの属性、関連先のクラスから取得した情報を自身のクラスで持ってること。
そして、処理を実行する時に、他クラスへメッセージを投げ出せること。

コミュニケーション図なら、情報エキスパートとなるクラスからメッセージという矢印が出ているだろう。
シーケンス図なら、情報エキスパートとなるクラスからメッセージが出て、他のクラスに処理が委譲されて、階段状の図になっているだろう。

その他のパターンも8つくらいあげられているが、そこまで重要ではないように思う。
生成、疎結合、高凝集度、多相性、コントローラは読めば分かる。
バリエーション防護壁はFacadeやAdapterみたいなもの。
純粋加工物、あるいは人工品は、機能の関連だけで構成するのではなく、ソフトウェアのプログラムの都合上、論理的なオブジェクトをワンクッション挟むようなもの。

【5】4つ目は、概念モデリングとデータモデリングは似ているようでやはり異なることだ。

「実践UML」では、概念モデリングでの注意点がいくつかある。

【6】属性とクラスは区別する。
一般に、ある概念をクラスの属性にするか、クラスで独立させるか、識別は間違いやすい。
「実践UML」の指針では、ある概念Xが現実世界では数値でもテキストでもなければ、Xは概念クラスであり、クラスの属性ではない、と言い切っている。

これは重要と思う。
初心者だった頃、どれをクラスにすべきか迷ってしまう時が多かった。
迷って、概念をクラスの属性にしてしまいがちな時が多い。

例えば、Destination、AirportはFlightに含めるべきか。
それぞれクラスとして独立させて、関連で結ぶべき。

実際は、1つの概念はクラスのロール名としていろんな別名として現れる。
例えば、企業クラスは顧客だったり仕入先だったり、取引先だったり、もしかしたらグループ内企業だったりする。
つまり、企業クラスはいろんなロール名として呼ばれる時がある。

【7】属性にはプリミティブ型を使わず、データ型を使う。
たとえば、属性にはDate型、Number型、String型を使う。
あるいは、Address、Color、PhoneNumber、UPC、SKU、ZIP、列挙型を使う。
区分値は列挙型を使う場合が多いかな。

例えば、会員クラスの会員名、会員IDみたいなものだろう。
でも、同じ会員名であっても、実際の人物は異なるケースもある。
だから、ValueObjectを別で用意して利用する場合もあるだろう。
ドメイン駆動設計なら、ValueObjectをかなり頻繁に使うだろうと思う。

【8】概念クラスの関連付けに外部キーや複合キーを書かない。
概念クラスの関連付けは、属性ではなくクラス間の関連で書く。

この部分がデータモデリングと異なるし、引っかかるところと思う。
一般にオブジェクトには唯一の主キーとなるサロゲートキーが割り当てられる場合が多いだろう。
すると、データモデリングで考えた時、外部キーや複合キーがなく、全てサロゲートキーなので、クラス間の制約条件が分かりにくくなる。
RailsのActiveRecordがそういう例になるだろう。
データモデリングなら、サロゲートキーを使っている場合、外部キーのペアが複合キーの役割を持つので強属性になるような制約をもたせるだろう。

では、概念モデルから実装モデルへ詳細化されていくうちに、関連はどう変わっていくのか?
概念モデルの関連から相手先のロール名が割り当てられて、最終的には関連はどこかのメソッドとして実装されて、そのメソッド内でロール名は変数名と同一視されて利用されるだろうと思う。

【9】概念クラス図でも、関連クラスのように、複合キーを使った事例はある。
しかし、関連クラスを多用すると、クラス図から読み取りにくくなる。
一方、データモデリングの観点では、関連クラスを複合キーを持つクラスと置き換えれば、明確な意味を読み取りやすくなる。

【10】概念モデリングでは、クラス間の関連と多重度でクラス間の制約条件を読み取る場合が多いように思う。
慣れるまで大変だけど。

【11】そんなことを考えてみると、概念モデリングや設計原則は以前よりも変化していないように思う。
UMLが流行していた2000年代からモデリング技法は進化しているのだろうか?

オブジェクト指向設計とデータモデリングの違いは他にも整理してみる。

| | コメント (0)

2023/09/18

ビジネス書の名著はどれ?

山口周さんがお勧めのビジネス名著をリストアップされていたのでメモ。

自分が読んだ経験のある本があったので、共感できた。

経済学をベースにした戦略論、組織論は好き。
人間の意志を超えた次元で、自然法則のように戦略も組織も縛られる。
そういう原則を抑えていれば、悪循環に陥る状態を防ぐことができるはず。
マンキュー入門経済学
戦略の経済学
イノベーションのジレンマ
組織の経済学
組織は戦略に従う

戦略/組織/人事と組織の経済学シリーズを読んでいる: プログラマの思索

組織論一般の理論を解説しているのが分かりやすかった。
組織行動のマネジメント

とても薄い本なのだが、アイデアがどうやって生まれるか解説してくれている。
アイデアの作り方

佐藤さんの解説記事がわかりやすい。
素早く考える能力、じっくり考える能力 : タイム・コンサルタントの日誌から

IT業界の営業戦略、プロセス導入ではキャズム理論が必須と思う。
パッケージ製品の営業だけでなく、新しい開発運用プロセスを導入する時もキャズムの法則に似たような事象が見られるから。
キャズム

キャズムの感想~イノベータ理論とホールプロダクト理論: プログラマの思索

伝記本として読んだ。
スティーブ・ジョブズ I」「スティーブ・ジョブズ II

岩波文庫なので文章は硬い。
プロテスタンティズムの倫理と資本主義の精神
君主論

自分が弱いのは意思決定、ゼネラルマネジメント、財務会計の分野かな。
全部読み切るには10年ぐらいかかりそうな感じ。

| | コメント (0)

2023/06/10

「ゲームをテストする バグのないゲームを支える知識と手法」の感想

「ゲームをテストする バグのないゲームを支える知識と手法」を読んだ。
JSTQB FoundationLevelを取得した後に読んだので、ソフトウェアテストの基本を抑えていて、かつ、ゲーム業界特有の考え方や組織、技術に関する話があって面白かった。
ラフな感想をメモ書き。

【1】僕は業務系システム開発しか経験がないので、ゲーム業界のことは知らない。
「ゲームをテストする バグのないゲームを支える知識と手法」を読むと、ゲーム業界特有の特徴がいくつかあると感じた。

業務系システム開発では、機能の網羅性、性能要件やセキュリティ要件などを踏まえた品質担保を重視する。
決められた要件があって、その要件に基づいた機能の網羅性の品質を担保することをすごく重視する。
つまり、当たり前品質の確保にかなり重点を置くように思える。

一方、ゲーム業界の品質は単に機能が網羅されていることが重要視されているわけではない。
UIや面白さなどの魅力的品質がかなり重視される。
だからゲームでバッグのように、開発中のゲームをプレイしてバグを探すように、ユーザが楽しめるプレイを中心に見る。
そこには機能の担保ももちろんあるがUIや楽しさもかなり重視しているように思える。
この辺りは業務系システムがBtoBビジネスに対し、ゲームソフトがBtoCビジネスであることから生じている事情もあるだろう。

しかし、ゲームソフトのソフトウェアテスト専門会社が出現し、品質向上や品質の可視化を目的として目標とする品質を定め、専門的な技術を使ってその品質レベルに到達するために必要なテストを計画したり設計するようになってきたという。
つまり、ゲームソフトでも品質管理や品質保証という考え方がビジネスとして必要になってきたわけだ。

【2】「ゲームをテストする バグのないゲームを支える知識と手法」では、JSTQBのソフトウェアテスト体系に基づき、ソフトウェアテスト7原則、ソフトウェアテストの専門体制、テストの種類、テストの活動、ソフトウェアテストの技術が紹介されている。
ゲーム業界特有のゲームでバッグの話は面白い。
一方で、ゲーム業界に限らず、JSTQBのソフトウェアテスト体系に基づいて内容が紹介されているので、その知識があれば、より理解しやすくなるだろうと思う。

たとえば、テストの体制には、テストマネージャ、テストリーダー、テスト担当者ごとに役割がある。
テストの種類(テストレベル)には、機能テスト、非機能テスト、探索的テストなど各種テストがある。
テスト活動には、テスト計画→テスト分析→テスト設計→テスト実装、テスト管理などがある。
この辺りはJSTQBの話と全く同じ。
換言すれば、こういうソフトウェアテストの専門知識を持ってゲームソフトのテストを専門的に実施しているならば、かなり組織的にテストをやっているわけなので、品質管理や品質保証もかなりレベルが高いのではないかと思う。

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

【3】ゲーム業界のテスターのキャリアマップは興味深かった。

管理系・技術系のキャリアに分かれている。
管理系キャリアは、テストマネージャやテストリーダー。
技術系のキャリアは、テスターから始まり、テスト設計者、自動化エンジニア、ゴッドハンドデバッガー。
この観点は一般的なプログラマやSEのキャリアに似ている。

【301】個人的に興味を引いたのは自動化エンジニア。
彼の役割はテスト自動化ツールを活用してプログラムを実装して自動テストを実現する。
Pythonの利用が多いらしい。
また、昨今はAIを活用したテスト自動化技術が注目されているらしい。
mablとかもそうなのかなと思う。

アジャイルチームのためのインテリジェントなテスト自動化ソリューション | mabl

テスト自動化が今後重要な役割を持つだろうと直感する。
ソフトウェアテストはどうしても手動テストや手動デバッグが多く、人海戦術になりがち。
そういう部分をプログラムそのもので自動化すれば品質が担保されるし、回帰テストによりデグレードも防げるメリットがあるのは誰もが理解する。
一方、テスト自動化は技術の難易度が高いし、やみくもにテスト自動化してもコスト削減効果がさほど得られない話もよく聞く。

テスト自動化の8原則という概念も初めて知った。
この辺りも色んなノウハウがあると思うので調べてみる。

テスト自動化研究会 - テスト自動化の8原則

テスト自動化の8原則について解説

【4】テストエンジニアの年収が記載されていたのも目を引いた。
一般アルバイトなら時給1072円、テストリーダーなら時給1172円。
年収は225万~400万円程度。
テストマネージャなら月給30万~50万レベルとのこと。
今はインフレなのでこれよりも高いだろうが、まだまだ低い気がした。
ソフトウェアテストの専門性が認知されれば、今後も上がっていくのだろうと思う。

| | コメント (0)

2022/12/25

JavaGold SE11の感想

JavaGold SE11を無事に取得できた。
試験勉強を通じて、有意義な経験を得られたと思う。
ラフなメモ書き。
間違っていたら後で直す。

【参考】
Java歴13年がJava Gold(SE 11)を受けてみた - yucatio@システムエンジニア

JavaGoldSE8に受かったので(前編) - Qiita

JavaGoldSE8に受かったので(中編) - Qiita

JavaGoldSE8に受かったので(後編) - Qiita

JavaSilverの感想~Javaはオブジェクト指向と関数型言語の2つの性格を持つ: プログラマの思索

Javaはなぜ関数型言語になろうとしているのか: プログラマの思索

【1】受験のきっかけ
コロナ禍がずっと続いて、リモートワークになりプライベートでも対面の付き合いがほとんどなくなって、余った時間を有効活用したい。
過去にJavaで開発していた頃はせいぜいJava5くらいで、それ以降のバージョンは完全に理解できていなかったので、ラムダ式等をきちんと習得したい。
15年以上前にSunのJava試験を受けて落ちたのでリベンジしたい。

【2】勉強方法
オラクル認定資格教科書 Javaプログラマ Gold SE11(試験番号1Z0-816)」(通称、紫本)と『徹底攻略Java SE 11 Gold問題集[1Z0-816]対応』(通称、黒本)を最終的に5回転以上回した。
黒本だけでは理解できず、紫本を5回転以上回して慣れる必要があった。
なお『徹底攻略Java SE 11 Gold問題集[1Z0-816]対応』の「総仕上げ問題」は実際の試験問題に似ているのでやるべき。

【3】JavaSilverは「Javaはオブジェクト指向である」ことを設計でもコーディングでも理解できれば合格できる。
しかし、JavaGoldは「Javaは関数型言語である」こと、特にラムダ式を使って設計でもコーディングでも理解する必要があった。
頻出論点は、ストリームAPIと関数型インターフェイス、モジュールシステムだったと思う。
僕には正直難しかった。
理由は、オブジェクト指向プログラミングはUMLによるモデリングを通じて経験していたが、関数型言語プログラミングのお作法もその概念も理解していなかったから。
「OptionalはMaybeモナド、ストリームAPIはMapReduceでありリストモナド、入出力APIはIOモナド」ということを最終的に理解する必要があるのではと思った。

【4】 第1章 クラスとインタフェース

なぜ内部クラス(inner class)が必要なのか?
2つのクラスソースファルを1つにまとめる必要がある時に使う。

内部クラス→static内部クラス→ローカルクラス→匿名クラス→ラムダ式 の順に昇華されていく。
よって、ラムダ式の発端は内部クラスにある。

インナークラスのインスタンス化には、エンクロージングクラスのインスタンス化が必要である。
つまり、無意味なインスタンス化のロジックが発生する。
そこで、インナークラスをstaticインナークラスにすれば解決できる。
staticインナークラスならば、エンクロージングクラスのインスタンス化無しで、インナークラスのインスタンス化ができる。
staticインナークラスにすれば、staticなインナークラスのフィールドやメソッドをエンクロージングクラスでそのまま参照できる。

staticなインナークラスでは、フィールドやメソッドの参照はコンパイルエラーになる。
一方、staticでないインナークラスでは、フィールドやメソッドを参照できる。

Effective Javaでは、「内部クラスにはstaticを付けるべき」というプラクティスがある。

内部クラスにstaticを付けると、内部クラスから外部クラス(エンクロージングクラスとも言う)のフィールド変数にアクセスできなくなる。
つまり、スコープが小さくなる。

ローカルクラスから参照するローカル変数は、実質finalが必須。
実質finalでなければコンパイルエラーになる。
ローカルクラスから参照するローカル変数を、ローカルクラスの後で変更するとコンパイルエラーになる。
この仕様は関数型言語のイミュータブルな性質に似ているので、そのような仕様にJavaが合わせたのではないか。

一方、RubyやPythonのクロージャでは、ローカル変数を変更しても問題なく動く。
Rubyのブロックはメソッドによる手続きブロックとは異なって、ブロックの外側で定義されたローカル変数をブロック内で参照・変更できるという性質を有する。ただブロック内で定義された変数はその外側で参照できない。

無名クラスは、メソッド内に無名のインナークラスを定義するので、ラムダ式。と実質同じ。
Effective Javaでは、「無名クラスよりもラムダを選ぶ」プラクティスがある。
無名クラスは冗長な記述であり、ラムダ式の方が簡潔に書けるからだ。

匿名クラスにコンストラクタは定義できない。
しかしインスタンス初期化子を使えば、似たような処理を行うことが出来る。

インターフェイスのdefault/privateメソッドは、Scalaのtrait, Rubyのmoduleと同じ。
ただし、インターフェイスを継承した2階層下のクラスや2階層下のインターフェイスでは使えない。
インターフェイスのstaticメソッドは、継承直下の子クラスのみ利用できる。
privateメソッドはdefaultメソッドから呼び出されることを前提としている。
インターフェイスは型の提供が目的であり、メソッドの実装は基本は実装クラスが提供する。
インターフェイスのstaticメソッドとラムダ式のおかげで、Factroyクラスが不要になった。

なぜJavaのインターフェイスがのstatic/default/privateメソッドを必要とするのか、理由が分からなかった。
たぶん、Scalaのtrait, Rubyのmoduleを真似て、共通ロジックをわざわざインスタンス化して利用する面倒な手続きを減らしたい意図があるのだろう。

Enumはシングルトンクラス。
Effective Javaでは、Enumに独自に新規メソッドを実装するプラクティスがある。

Javaのenum型はシングルトンクラスみたいだ: プログラマの思索

Effective Java 第3版 第6章enumとアノテーション - Qiitaでは、int型をEnu型で書くべき、というプラクティスは理解できる。
しかし、「拡張可能なenumをインタフェースで模倣する」プラクティスのように、通貨クラスに「+」「-」のようなメソッドを独自で実装するという発想はなかった。
こういう考え方がドメイン駆動設計の値オブジェクトの実装に役立つのだろう。

【5】 第2章 関数型インタフェースとラムダ式

Javaのラムダ式は、関数型インフェーエイスの宣言とインスタンスの生成を同時に行う文法とみなす。
つまり、ラムダ式=関数型インターフェイス(抽象メソッド1個だけ)+インスタンス生成。

ラムダ式を使えば、Factroyクラスは不要になる。
つまり、DIを実現するために、Factoryパターンを使い、その実装にラムダ式を使う。
ラムダ式を使えば、Strategyパターンを短く書ける。
ラムダ式をメソッドチェーンで書けば、Builderパターンを短く書ける。

Javaのラムダ式のローカル変数は、スコープ外では実質finalとして扱われる。
ローカル変数の値を更新するとコンパイルエラーになる。
この性質は関数型言語の特徴に似ていると思う。

@FunctionalInterfaceを付けたインターフェイスは、自動的に関数型インターフェースとして使用できるが、抽象メソッドは1個だけ限る。
他言語では関数1個で定義できるが、Javaは必ず関数をclassで囲む必要があるので、関数型IFで定義する必要がある。

Javaの関数型インターフェースの抽象メソッドで注意すべき点は、java.lang.Objectのメソッドはカウントされない。
たとえば、public abstract String toString()があれば、抽象メソッドにカウントしない。

ラムダ式を使うと何が嬉しいのか?
1.抽象メソッドを実装したクラスを最小のコード量で実装できる
2.抽象メソッドの実装と、メソッドを使うところを一つにできる

関数型インターフェイスには1つしか抽象メソッドがないので、戻り値・引数の型と順番を、関数型インターフェイスの型からJavaコンパイラが推測できる。この仕組みが型推論なわけだ。
だから、Haskellのような関数型言語はコンパイラを作りやすいという理由は、型推論が強力な特徴があるからだろう。

通常パターン;
* Function, XXXFunction :apply()
* => 戻り値:R
* Supplier:get()
* => 戻り値:T
* Consumer, XXXConsumer :accept()
* => 戻り値:void
* Predicate, XXXPredicate :test()
* => 戻り値:boolean

特殊パターン:
* ToXXXFuntion:applyAsXXX()
* ToIntFunctionならapplyAsInt()のような感じ。
* XXXSupplierの形だけ注意! => getAsXXX()
* IntSupplier:getAsInt()
* DoubleSupplier:getAsDouble()
* LongSupplier::getAsLong()

UnaryOperator、BinaryOperator=引数と戻り値の型が同じ。
引数と戻り値の型が同じなので、Gnericsは1つで良い。

【6】 第3章 並列処理

並行処理(concurrent):処理を切り替えて同時に動いているように見せる。Threadクラスと同じ。
並列処理(parallel):複数のコアで同時に処理を行う。ストリームAPIでparallelメソッドを使う。

Executor によって処理されるタスクの状態遷移図
created(タスク生成) 
→ submitted(キューにタスクを登録) 
→ started(タスクのrun実行)
→ completed(タスクの終了)

Thread.run()がキューに登録されて、Thread.start()で、run()が実行される。
キューに登録されたRunnable.run()が実行される。

なぜ、並列処理はラムダ式や匿名クラスを使うのか?
スレッドのタスクは、関数型インターフェイスRunnnableのラムダ式で実装されるから。

Future=スレッドを生成したメソッドが、新しく作ったスレッドの結果を保持する。
submitの戻り値=Future => Future.get()で取得できる。
list.add(services.submit( XX -> XX))を実行できる。
一方、executeの戻り値=無し。

Runnable.run()はvoidなので、何も返さないから、Future.get()はNULLを返す。
Callable.run()は戻り値があるので、Future.get()は結果を返す。

Future fut = ex.submit( () -> {処理}, 0); は、第2引数0を返す。

Callableで定義したタスクで例外が発生した時、ExecutionExceptionでキャッチする。

CyclicBarrier=スレッドを待機させる。
java.util.concurrent.CyclicBarrierクラスを利用すると、複数のスレッドが特定のポイントまで到達するのを待機させることができる。
CyclicBarrier=複数のスレッドが特定のポイントまで到達するのを待機できるようにする同期化支援機能を持つスレッドクラス。
スレッドN本目を通過すると、await()の待機は解除される。

* バリアー:複数スレッドの待ち合わせポイント
* バリアーアクション:待ち合わせ後に実行される処理

マルチスレッドで扱うクラスのフィールドにvolatile修飾子を付けると、キャッシュされなくなる。
これにより並列処理時にどちらかがキャッシュを読み込むことによる不整合をなくせる。

【7】 第4章 ストリームAPI

ストリームAPIとは何なのか?
一言で言えば、JavaのMapReduce用APIと思えばいい。
大量データをリストで引数として設置して、Mapで処理させて並列処理できるようにばらして、並列処理の結果をreduceで1つにまとめて戻り値に返す。

実際の問題では引っ掛けパターンが多い。

ラムダ式のローカル変数は実質finalなのに、2回代入している
ただし、ローカル変数が配列ならポインタ参照なので、2回代入はOK。
たとえば、ArrayListやint[]の場合。

ラムダ式を{}で書いたのに「;」なし。

ラムダ式の中で、varの引数はコンパイルOK。
つまり、ラムダ式内の処理の引数は型推論される。
ただし、varはメソッド引数やメンバ変数に使うとコンパイルエラーになる。

Stream<型>のようなGnericsで引っ掛けるパターンが多い。

* map(T -> R)とflatMap(T -> Stream)
* mapToInt()とmapToObject()
* mapToInt(ToIntFunction)とmap(T, R)
* pararell(Stream --> Stream)とpararellStream(Collection --> Stream)
* reduce(BinaryOperator --> Optional)とreduce(DoubleBinaryOperator -->DoubleStream)

終端操作を2回実行すると実行時に例外が発生する。
例:anyMatch, count, reduce, forEach, collect

中間操作だけで終わると、値は返却されない
例:peek

終端操作countだけ実行しても出力されない。System.out.println(count)が別途必要。

List.stream().pararell() <=> List.pararellStream()は同じ。

boxed()は、XXStream -> Streamへ変換する。
逆の操作は、Stream --> mapToInt(IntToIntFunction)--> IntStream。

reduce().orElse()でint型、double型を返す。

Javaのsumはreduceで置き換えられる: プログラマの思索

Javaのreduceの使い方は2種類ある: プログラマの思索

モナドとは「メソッド内の副作用の存在を戻り値の型で表現する」ためのデザインパターン。
「関数に副作用がある」ことを「戻り値の型」で表現している。
Genericsを使って、戻り値の型を増やしている。

なぜ関数型IFではGenericsが頻繁に使われるのか?
理由は、関数の副作用を戻り値の型で表現するために、Genericsを使って戻り値の方の個数を増やしているからと考える。

OptionalはMaybeモナド。
Optionalの語源:値がないかもしれない => オプションの値を作りましょう。

StreamはListモナド。
MapReduceの戻り値はOptionalを返す。
それにより、Nullの戻り値はなく、ヌルポを防げる。

IOはIOモナド。
入出力処理における副作用は、戻り値の型をGenericsで表現する。

StreamAPIはメソッドチェーンで書かれるので、処理の途中でどのように戻り値の型が変換されて遷移するのかわかりにくい。
そこで、StreamAPIはバラして考えるとよい。
Eclipseの「ローカル変数の抽出」を使って、メソッドチェーンをばらすといい。

【8】 第5章 入出力

java.ioパッケージは古い機能。
たとえば、Fileクラスは、ディレクトリやファイルへのパスを扱うだけで、ファイル自身を表すのではない。

java.nioパッケージは新しい機能なので、痒い所に手が届くようになっている。
nio.Filesクラスは新しい入出力API => 同じパスに同じファイルがあれば作成時に例外を発生させて検知してくれる。
NoSuchFileException - ファイルが存在しない場合
DirectoryNotEmptyException - ファイルがディレクトリで、ディレクトリが空でないために削除できなかった場合

FileクラスとFilesクラスの違いは覚える。
Fileクラス提供のisXXXメソッドは、引数を取りません。
* 例:File.isDirectory() : boolean
* 例:File.isFile() : boolean

Fileクラス提供のメソッドは、renameTo(dest)以外はほとんど引数を取りません。
* 例:dirFile.mkdir()
* 例:dirFile.mkdirs()
* 例:file.renameTo?(File dest)
* 例:dirFile.listFiles()
* 例:file.getAbsolutePath()
* 例:file.toPath()
* => new File("ファイル名").toPath()の形式でPathオブジェクトを生成する

Filesクラス提供のメソッドは、全て引数を取ります
これ覚えとくだけで事前にコンパイルエラーかわかるようになった。
* 例:Files.isDirectory(Path dirPath)
* 例:Files.deleteIfExists(Path path) =>ファイルやディレクトリが存在している場合だけ削除する
* 例:Files.list(Path dirpath): Stream =>ディレクトリ内の全てのパスを表示
* 例:Files.find(開始パス、深さ、BiPredicateオブジェクト、オプション): Stream
* 例:Files.isSameFile(path1 : Path, path2 : Path) : boolean : path1とpath2が同じか否か
* Files.move?(Path source, Path target, CopyOption... options)
* Files.copy?(Path source, Path target, CopyOption... options)

Files.walk(), Files.find()は引数を覚えるのが重要。
Filesクラスのwalk()は再帰的にパス情報を取ってくる。
Files.walk(開始パス、深さ、オプション):サブディレクトリまで展開したパスを再帰的に表示
指定された開始ファイルをルートとするファイル・ツリーを参照することで Pathが遅延移入されるStreamを返します。

Filesクラスのfind()は再帰的にパス情報を処理して、判定条件に合致したファイルだけを探す。
Filesクラスのfind()の引数の順番は覚えたほうが良い。
Files.find(開始パス、深さ、BiPredicateオブジェクト、オプション):サブディレクトリまで展開したパスを再帰的に処理して必要なフィルのみ表示
指定された開始ファイルをルートとするファイル・ツリー内でファイルを検索することで Pathが遅延設定されるStreamを返します。

XXのようにStreamがついてなければCharacterストリーム。
XXStreamのようにStreamがついていればByteストリーム。

getDefault()は、FileSystemsクラス, Localeクラスにある。
SystemDefault()はZoneIdクラスにある。

Serializableのtransient修飾子は、シリアライズ対象から外す。
デシリアライズ後はnullになる。
static変数は、シリアライズ対象外になる。
∵static変数はグローバル変数なので値は保持される。

【9】 第6章 JDBCによるデータベース連携

Statement ◇--PreparedStatement, CallableStatement

Statement 単純な実行計画を行いたい時(select * from ... を 1 回だけ など)
PreparedStatement 複数回に渡る実行計画を行いたい時, ? のパラメーター解析を使いたい時
CallableStatement ストアドプロシージャを実行

Statementは静的なSQLを扱い、PreparedStatementはプレースホルダを使った動的SQLを扱えます。
基本は、Statementクラスを用いずにjava.sql.PreparedStatementクラスを使用する。
∵SQLインジェクション対策になる。
∵名前の通り、SQLがDBにキャッシュされるため、繰り返し同じSQL文を発行する場合に処理速度が速くなる。
PreparedStatementはDBMSが理解できるようにSQL文をあらかじめコンパイルするから。

まあ、今ならベタなPreparedStatementで実装することはなく、フレームワークで書くのが普通だろう。

【10】 第7章 汎用とコレクション

Genericsの使い道は2種類しか思いつかない。
ListやMapの型安全。
関数型IFの引数、戻り値の型定義。

Cell と Cellは全く別のクラスになる。
Genericsを使う時に、初心者が間違えやすいらしく、僕も最初はハマった。

Cellにすれば、パラメータに全てのクラスを扱える。
しかし、Cellではパラメータにクラスの制約がないのは不便。
そこで、Cell,Cellを使って、パラメータに使えるクラスの範囲に制約をかける。

一般的に PECS という呪文が存在し、上限付き境界ワイルドカード型をProducerと呼び、下限付き境界ワイルドカード型をConsumerと呼ぶことがあるらしい。
Producer - 値の生成専門
Consumer - 値の受取専門

PECS(Producer extends and Consumer super)とは、Javaのジェネリックスプログラミングにおいて、ジェネリッククラスのメソッドに柔軟性を持たせるための原則である。基本は以下の通り。
メソッドが値を取得するコレクション(Producer)は型にextendsをつける
メソッドで値を設定するコレクション(Consumer)は型にsuperをつける

Javaジェネリクス:PECSって何? - Qiita

java - What is PECS (Producer Extends Consumer Super)? - Stack Overflow

JavaジェネリックスのPECS原則、extendsとsuperの勘所 -- ぺけみさお

Genericsの型推論は、ダイヤモンド演算子<>を記述すると、下記が推論される。
* 変数への代入 =>例: var a = new ArrayList<>();
* メソッドの戻り値 =>例: return new ArrayList<>();
* メソッド呼び出しの引数 =>例: execute(new ArrayList<>());

ComparableとComparatorの違いも注意。

ComparableとComparatorの違いは何か: プログラマの思索

【11】 第8章 アノテーション
【12】 第9章 例外とアサーション
【13】 第10章 ローカライズ
は省略。

【14】 第11章 モジュール・システム

JavaのモジュールシステムでSPIとDIを実現するやり方: プログラマの思索

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

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

【15】 第12章 Java SEアプリケーションにおけるセキュアコーディング
は省略。

| | コメント (0)

2022/12/17

「Redmineハンドブック」は良い本です

9月に出版された「逆引きでわかる! Redmineハンドブック バージョン5.0対応」を@agilekawabataさんから献本して頂きました。ありがとうございます。
読みどころを書きます。

【1】「Redmineハンドブック」の一番良い点は、こういうことがしたいんだけどRedmineの機能は何だっけ?と疑問に思った時に、逆引きで探せること。

たとえば、期日が切れたチケットを表示したり、放置されたチケットを表示したり、チケット同士を関連付けたり、チケットに先行後続の関係を付けるとか、探す時に便利。
Redmineのようなチケット管理ツールに慣れていれば、すぐに分かるけれど、初心者や慣れていない人にとっては、知らないことがすごくストレスになる。
たぶん、目次や索引から探すようになるだろう。

【2】「Redmineハンドブック」では細かいノウハウが紹介されている点も良いと思う。
たとえば、親子チケットの設定では、大日程だけで概算見積して親チケットの開始日・期日を設定した後、小日程計画で小チケットに細かくブレイクダウンして期間を設定すると、親チケットの開始日・期日が消えてしまう。
なぜなら、Redmineの初期設定では、親チケットの情報は子チケットをロールアップされる仕様だから。
よって、管理画面で、親チケットの開始日・期日を独立させるような設定をする必要がある。

また、大人数のユーザや多数のユーザグループを作った場合、細かくロール設定するのが面倒だ。
そんな場合、JAXAのロール設定の事例の話が「Redmineハンドブックで紹介されている。

CODA チケット管理システム | JSS@JAXA
「CODA: JSS2の運用・ユーザ支援を支えるチケット管理システム: Redmineの事例と利用のヒント」

JAXAのRedmine運用事例の分析~「ロール設定のORルール」と「カスタムフィールド設定のANDルール」: プログラマの思索

JAXAのスーパーコンピュータ活用課でRedmineを使ったチケット管理システムの経験論文: プログラマの思索

【3】「Redmineハンドブック」では、WF型開発やアジャイル開発の運用方法が紹介されている点も良い。
慣れていない人にとっては、やはり実際にどのように運用できるのか、イメージが湧きやすいと思う。

WF型開発では、WBSをチケットに落とし込んで、ガントチャートで管理するのが一般的だ。
ガントチャート画面にイナズマ線が表示される機能も紹介されている。

一方、アジャイル開発では、スプリントはバージョン、タスクはチケットに対応付けて、チケット一覧でスプリントごとにグルーピングしてタスク管理するのが一般的だ。
チケット一覧ではやりにくい場合は、かんばんプラグインを入れて、タスクボードをかんばんで見立てるとよりアジャイルな雰囲気が出てくるだろう。
たとえば、アジャイルウェア社のLycheeかんばんもあるし、フリーでいくつかのプラグインがある。

チケットパネル (Redmineプラグイン) - ファーエンドテクノロジー株式会社

[Redmine] チケットをかんばん表示にするプラグイン | 適当に書き連ねるネタ帳のようなもの

GitHub - happy-se-life/kanban: Kanban plugin for redmine

【4】「Redmineハンドブック」で面白いと思った点は、最終章にGTDのタスク管理が紹介されている点だ。
やっぱりチケット管理はGTDのようなライフハック的なタスク管理のほうが向いていると思う。
Redmineにガントチャートはあるが、タスクをチケットでサクサク登録して更新してCloseしていく方が開発のリズムが生まれる。
すると、粒度の小さいチケットをたくさん作り、バックログとして一列に並べて、上から順にチケットをこなしていったり、溜まったチケットは定期的に棚卸しして作業しやすくする、といった運用方法になってくる。
つまり、自然にGTDのようなタスク管理に近づくわけだ。

さらに「Redmineハンドブック」では、仕事に追われない仕事術 マニャーナの法則 完全版 | マーク・フォースター, 青木 高夫 |本 | 通販 | Amazonをもとにいくつかの役立つ概念を紹介している。

タスクチケットは期日や重要度、優先度、ステータスによって種類がいくつかある。
それらをリストに分類し、リストに名前付けして管理するわけだ。
たとえば、オープンリストとクローズリスト、マスターリストとフィルターリスト、いつややることリスト、ペンディングリストなど。
初歩的なやり方ではあるが、割と使える方法だと思う。

というわけで、手元に1冊あると役立つ本だと思います。

| | コメント (0)

より以前の記事一覧