エンジニア的なネタを毎週書くブログ

東京でWebサービスの開発をしています 【英語版やってみました】http://taichiw-e.hatenablog.com/

ISO25000を読んでみる - ISO25010 The quality model 前半

「『品質がいい』ってなんだよ!?」を定義したISO25000 の中に含まれる、ISO25010を読んでいます。
こちらのポータルサイトを中心に読み進めているのですが、
iso25000.com
抽象的な説明が中心(&英語)で理解しづらいところがあるため、「こういう意味かな? 例でいうとこういうことかな?」と考えたことをメモとして残します。

The quality model

「ソフトウェアの品質」を8つの項目に分類し、更に各項目が複数のsubcharacteristicsを持つ構成になっています。
f:id:taichiw:20190506235312p:plain
上記図はhttps://iso25000.com/index.php/en/iso-25000-standards/iso-25010より。

Functional Suitability

所謂「機能要件」。品質とかテストとか言うとこれが注目されがちですが、"Software Product Quality"として定義されている8項目の中の1つに過ぎません。

Functional Suitabilityを構成する3つのsubcharacteristicsのうち、
Functional completenessは、機能が網羅されたチェックリストにどのくらい『実装されていますチェック』を付けられるか
f:id:taichiw:20190504232011p:plain:w100
Functional correctnessは、そのリストになっている各機能がどれくらい正しい結果を返しているのか
f:id:taichiw:20190504232151p:plain:w100f:id:taichiw:20190504232216p:plain:w100
と解釈しました。

Functional appropriatenessは、

Degree to which the functions facilitate the accomplishment of specified tasks and objectives.

とあったのですが、この定義がよく理解できませんでした。

こちらのCase Studyを見ると、
http://www.aqclab.es/images/AQCLab/Noticias/SQP/software-quality-management-evaluation-of-software-product-functional-suitability-a-case-study.pdf

understood as the ability of the system to carry out the requirements that are needed for the different usage objects that have been specified.

とありました。ということは、先程の「チェックリストで定義された機能一覧」が、そもそもどの程度ユーザの要求を満たしているか、
要件定義そのものの品質チェック… ということでしょうか?

ISO25000を元にした、JISでは、

明示された作業及び目的の達成を,機能が促進する度合い。

と訳され、

例 不要な段階を除いて,作業を完成するために必要な段階だけを利用者に提示する。

という例がついていました。*1

Performance efficiency

「パフォーマンス」と言ってもいろいろあるようでして。

Time behaviourは速度とスループットが要求を満たしている度合い
f:id:taichiw:20190505000025p:plain:w100f:id:taichiw:20190505000151p:plain:w100

Resource utilizationはコンピュータのリソース消費に関する要求を満たしている度合い*2
f:id:taichiw:20190505000449p:plain:w100

で、最後のCapacityがまた分かりそうでわからない。

Degree to which the maximum limits of a product or system parameter meet requirements.

これだけ読むとナンノコッチャ って感じなのですが… またJISの怪しげな*3に頼りますと

製品又はシステムのパラメータの最大限度が要求事項を満足させる度合い。
注記 変数には,保存することができる項目の数,同時に利用する利用者の数,通信帯域,トランザクションスループット,及びデータベースの大きさを含む。

ということで、要は「いろんな値の最大値」がちゃんと満たされているかどうか ということのようです。

Compatibility

Co-existence

Degree to which a product can perform its required functions efficiently while sharing a common environment and resources with other products, without detrimental impact on any other product.

サーバの相乗りとか、あるいは一台のPCやスマートフォン上で複数のアプリが動く際に、他のソフトウェアに悪影響を与え(自分ばかりCPUやメモリを食うとか)ずに動作できる度合い…ということでしょうか。
f:id:taichiw:20190506230912p:plain:w100

Interoperability

Degree to which two or more systems, products or components can exchange information and use the information that has been exchanged.

と、定義されています。
ここまではすべて単体のシステムに対する指標だったのですが、"Degree to which two or more systems, products or components" なので、評価の対象が複数システムの指標のようです。複数システム間でどれだけ情報の共有がなされているのかを表す指標です。
f:id:taichiw:20190506231426p:plain:w100

同じ区役所のビルの1階と3階と5階に、同じような内容をそれぞれ別のフォーマットで書いて提出しなくてはならない*4お役所のシステムはInteroperabilityが最悪なわけですね。何のためのマイナンバーですか。

Usability

なんとなく使ってしまう言葉ですね。

Degree to which a product or system can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use.

と、定義されていて、specifiedが何度も出てきます。
「『特定の』ユーザが、『特定の』状況において、『特定の』目的を達成する ことに対してどれだけ役に立つか」を表す指標なんですね。

逆に言えば、そもそもユーザとして想定されていない層の人達が「使いにくい!」と感じることは、この指標の観点に於いては問題ない ということになります。

subcharacteristicsは6つです。

Appropriateness recognizability : なにか達成したいことがあるユーザに、このプロダクト(システム)が使える! とそもそも認識してもらえる度合い。
f:id:taichiw:20190506232650p:plain:w100

Learnability : いざ使う気になってくれたユーザの、操作方法の学びやすさ。
f:id:taichiw:20190506232821p:plain:w100

Operability : 操作性。んー どういうのを指してるのかな…
スマートフォンのUIなのにやたらボタンが小さい上に並んでいて誤操作しやすい(PCでマウスだったら特に押すのが難しくない)」のは、Operatabilityが悪い例でしょうか。
f:id:taichiw:20190506233204p:plain:w100

User error protection : ユーザが誤った操作をしずらい度合い。
「数値しか受け付けないフォームは数字しか入力できないようにする」はここに入るでしょうか。

User interface aesthetics : "aesthetics"は「美学」という意味だそうです。狭義の「UIが良い/悪い」はここに入りそうです。

Accessibility :

Degree to which a product or system can be used by people with the widest range of characteristics and capabilities to achieve a specified goal in a specified context of use.

ということで、ここでは"people with the widest range of characteristics and capabilities"の広さが指標になっています。
Usabilityのはじめに、特定のユーザが、特定の状況で、特定の目的 と書きました。この『特定のユーザ』の範囲が広く、多くの人から使ってもらえる製品 = Accessibilityが高い製品 と言えるようです。
f:id:taichiw:20190506234501p:plain:w100

*1:英語でこれっぽい記述は見当たらないので、翻訳時に足されたのでしょうか

*2:例えばスマートフォンのアプリだと、過剰にCPUやメモリを使うアプリは困りますもんね。Webの、サーバサイドの開発が主な自分としてはハードウェアまで含めてまるっとシステムなのでちょっと感覚が違うのですが…。

*3:もしかして原文のPDFを見たら書いてあるのかな?

*4:詳細は忘れましたが、保育園関係の何かでした

リアルタイムにそこそこ重い処理を実行するためには、前処理が重要… なのかな? #jsug

JSUG勉強会 2019その3 LINEにおけるSpringの活用 に参加してきました。
ここがとっても気になったのです。

Personalized content recommender systemであるSmart Channelは、ユーザーの属性や趣味趣向を推定し、各個人に最適なコンテンツを推薦するServiceです。
LINEの膨大なトラフィックを受けながら、可能な限りリアルタイムにRecommendをするために、Architectureや実装にいくつかの工夫をしています。

「個人個人に違う結果を出すために、毎回リアルタイムで計算」ってどこかで(私が)(業務上)聞いたことある!
すごい気になる!

ということで行ってまいりました。初LINEさんオフィスです。
f:id:taichiw:20190325234503j:plain
f:id:taichiw:20190325234523j:plain
会場のカフェ。おしゃれだった。


さて、@hackmylife さんの Personalized content recommender system on Springです。

自分が気になっていた、以下にリアルタイムに処理をするか、という点。

以下の二点が特にミソなのではないか と感じました。

・Redisとの通信がWebflax形式のNon-Blocking. フィルタリングなどの処理はSubscribeしたときに動く。
・前もってTrainer側で、Rankerが「扱いやすいように」処理する。例えば、逆行列を求める処理がアルゴリズム上必要なのだが、これは事前に処理しておく。
この「事前処理」はスライドのこちらのページで触れられています。

"User traffic" を起点に動作する、CRS Engineが見に行く"CRS Model Redis Parameter"。
こちらに格納されているデータが、「CRS Engineが扱いやすいように処理された」ものなんだそうです。

IntelliJ IDEAのSequenceDiagramプラグインが便利

この、SequenceDiagramプラグインで、
vanco.github.io

こんな感じのシーケンス図が描けます。
f:id:taichiw:20190301195001p:plain

素敵なのが、

  • 好きなメソッドから始められる
  • 深さが選べる

f:id:taichiw:20190301195116p:plain
点です。

コードレビュー時などに、深さ2でServiceクラスから始めると、私の好きな感じのコードになっているかどうかがよくわかります。
参考:持論:Application Layerがシンプルなコードは読みやすい - エンジニア的なネタを毎週書くブログ


以前は、こういったコードから自動生成された図は、ノイズが多くて使い物にならない…と思っていました。
けれども最近は、
「自動生成された図が汚い、ということはそもそもコードが悪いのでは?」
と思うようになってきました。

f:id:taichiw:20190301195934p:plain
例えばこれ。
右から左に呼び出しが伸びてるのが気持ち悪いです。
以前の私であれば、「この呼ばれているクラスを右に持っていければいいのに… ツールがイケていない!」と思っていたところでしたが、
そもそもこんな向きに呼び出しがかかる、元のコードが悪いのではないでしょうか。

こういう考え方になってきたのは、12月のJJUG CCでirofさんの「JIGを使った設計」を聞いたからなのかなぁ… と思います。

【極論ですけど】JavaでforEachを使ったら負けだと思う

正直使い所がわからないんですよね、forEach.
ログとかprintfとかする以外は…

コレクションを更新するな

未だに時々見るのがこういうコード。

List<X> list = new ArrayList<>();
適当なコレクション.forEach()
  .map(t -> list.add(t.getXXXX()));

これとっても良くない。

スレッドセーフでない

上記をあまり深く考えずにパラレルストリームにしちゃいますと

List<X> list = new ArrayList<>();
適当なコレクション.forEach().parallelStream()
  .map(x -> list.add(x.getXXXX()));

ArrayListに対する追加処理がスレッドセーフでないため、確率的に不具合が起きてしまいます。*1

パラレルにしなければいい…のですが、Project Lambdaの目的の一つがマルチコアへの対応なわけで、「parallelStreamを使って並列化できないものはラムダ式で書くな」くらいに私は思っています。(私の勝手ルールではありますが)

Lambdaで更新するの「関数」でない

Lambda式内では外で定義した変数に代入ができません。
これは、「状態」を極力排除することによって、バグの入り込む余地を減らすため… と私は認識しています。
ですが、上記のようにコレクションに対する操作や、Setterでの代入はJavaの言語仕様上できてしまいます。

…とはいえ、できるからやっていい、というものでもないと思います。

「リストを作る」と明確に書く方法がある

List<X> list = 適当なコレクション.stream() //parallelも可
  .map(X::getXXXX)
  .collect(Collector.toList());

そもそもこのように、リストを作るための書き方が用意されているのに、これを使わずに汎用的なforEachでなんとかする… というのは美しさに欠けます。

更新しないとなると、forEachは出力くらいしか使いみちがないのでは

上で書いたとおり、コンパイルエラーにはならない… とはいえ、Lambda式内で何かを「更新」するのは不適切と考えます。
そうなると、冒頭に書いたとおり、何かの出力くらいしか使いみちがないなぁ… ということになり、
よっぽどのことがない限り、「forEachを使ったら負け」だと思うのです。

*1:私が経験したことのある事象だと、「適当なコレクション」よりも多い要素がlistに追加されるという謎現象が発生し、その要素をgetするとnullが入ってる → ヌルポで落ちる というものを何度かみました。

"Rename Hackathon"をしてみました

チーム内で、お祭り的なイベントとして、"Rename Hackathon"というイベントをチーム内でしてみました。

ルール

  • 参加者は30分間ひたすらプルリクエストを送り続ける
  • 「リネーム」のみ許可。名前を変更する対象は、クラス、メソッド、変数名、パッケージ名 など何でも良い
  • 1つのプルリクエストは、1単語だけ直して良い。複数の単語を修正したプルリクエストはルール違反として却下*1
  • 30分後の「リネームタイム」の後に通常のコードレビューを行い、Approveされたものだけがマージされる
  • 同じ箇所を複数人が直した場合は投票でどちらを選ぶか決める
  • 最もマージされた数が多かった人は表彰

結果

  • 参加者 : 6人(因みに…4名は日本オフィス。2名はインドオフィス。リネームタイムはリモートで同時に。)
  • 30分間に出された総プルリクエスト数 : 32
    • ルール違反 : 2件(複数箇所修正、パッケージを1回層削除)
    • 重複したため投票で却下 : 2件
    • コードレビューで却下 : 8件(まだ一部レビュー中なので増えるかも)
    • ということで残ったプルリクエスト数 : 12 ~ 20
  • 修正の例
    • クラス
      • 不要(しかも意味不明)な接頭辞や接尾辞の削除
      • 省略されすぎていて分かりにくい名前を展開
    • メソッド
      • booleanを返すcheckXXXX メソッドを isXXXXX メソッドに
    • 変数
      • i などの無意味な名前を 意味のある名前に

所感

楽しかった

お祭りみたいで楽しかったです。ある程度ゲーム性のあるルール*2をしっかり作ったので、数を競うのも楽しんでくれた感がありました。

コードがきれいになった

これはもちろん。本来なら最初のコーディング時に埋め込まれるべきでない名前もちらほらありましたが、どうしてもできてしまうのは避けられないもの。
また、開発者のドメインナレッジが増すことによってより良い名前を後から思いつくこともあります。
そういった、普段のもやもやを片付けられた良い機会でした。

初級者の学びに

32件中8件はコードレビューで却下ということで、たかだかRenameなんですが、意外と他の人の了承を得られていないんですね。*3
「良い名付けとはなにか」の学びができた、良い機会になったと思います。

*1:プルリクエスト単位でマージの可否を判断するため

*2:本来の目的は安全にリファクタリングをするため

*3:レビューは参加者同士の相互レビューです

「解決策から考える病」に名前をつけたい

…って、タイトルで名前つけちゃってますが。

どうしても人間、「なんとなく思いついたソリューション」に飛びついちゃうんですよね。

寝坊しまくってるから目覚まし時計を買わなきゃ…! ってなりがち。
f:id:taichiw:20190206235438p:plain

その前に、そもそもなぜ寝坊しているか? について考えないといけない。*1
f:id:taichiw:20190206235455p:plain

※上の画像は以前に書いたこちらの資料より。もともとKPTのやり方を説明した資料ですが、根本的な考え方は共通だと思います。

自分がこの考え方ができるのは… 弊社の入社前課題でもらったこの本のおかげっぽいです。
他にも色んな経験が元になっているのだとは思いますが、「なんで自分、こういう考え方をするようになったんだっけ?」と思案したときに、思い出すのはこの本です。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

世界一やさしい問題解決の授業 [ 渡辺健介 ]
価格:1296円(税込、送料無料) (2019/2/6時点)


適当にググってたらこんなブログも見つけました。(Baseball Studyで知ってる方だ…!) nihonbuson.hatenadiary.jp

*1:実際のチームだと…「そもそも寝坊は悪いことなのか? 悪いとしたらなぜ?」まで一旦掘り下げたいところです

JavaのHashMapは無限ループを引き起こす

知らんかった。理由がぼんやりはイメージ湧くけどしっくり来てないので後でちゃんと調べ…たい。(だいたいやらないパターン…)

d.hatena.ne.jp
www.atmarkit.co.jp
wadahiro.hatenablog.com


回避方法はいろいろあるみたいだけど、ConcurrentHashMapをつかってスレッドセーフにするのが楽なのかな?
web.plus-idea.net