<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>okuzawatsの日記</title><link>https://okuzawats.com/</link><description>Recent content on okuzawatsの日記</description><generator>Hugo</generator><language>ja</language><copyright>© 2019 okuzawats</copyright><lastBuildDate>Thu, 09 Apr 2026 20:15:00 +0900</lastBuildDate><atom:link href="https://okuzawats.com/index.xml" rel="self" type="application/rss+xml"/><item><title>開発速度の暴力</title><link>https://okuzawats.com/blog/speed/</link><pubDate>Thu, 09 Apr 2026 20:15:00 +0900</pubDate><guid>https://okuzawats.com/blog/speed/</guid><description>常日頃、より良いプロダクトを、より速くデリバリーしたいと考えて、プロダクト開発に関わっています。そのような中で、稀に、「より良いプロダクト」をすっ飛ばした（ように見える）人たちが、圧倒的・暴力的な速度でデリバリーする事例を目にします。
「品質は誰かにとっての価値である」とG.M.ワインバーグは言いました。速度もまた、誰かにとっての価値となるでしょう。速いこと自体が価値となり得るのです。
圧倒的・暴力的なデリバリー速度に対して、「拙速である」と断じることもできるでしょう。しかしながら、自分は「こんな奴らには勝てっこない」と戦慄します。プロフェッショナルとして確立してきた、守るべき規律が足枷となり、圧倒的・暴力的なデリバリー速度に屈することがあり得ると思うのです。
答えの出ない文章になりますが、時には自己の規律を見直して再構築することも必要かもしれない、と愚考する次第です。</description></item><item><title>蔵書印を作りました</title><link>https://okuzawats.com/blog/library-stamp/</link><pubDate>Wed, 14 Jan 2026 21:56:00 +0900</pubDate><guid>https://okuzawats.com/blog/library-stamp/</guid><description>蔵書印を作りました。
きっかけは漫画「本なら売るほど (1)」 (児島, (2025)) を読んだことです。これは詳細を省きますが、その第一話では、主人公である古書店の店主が、亡くなった読書家の蔵書を査定している際、蔵書に蔵書印が押されていることに気が付く場面があります。
このエピソードを読み、本題とは少しズレる形ですが、「蔵書印って個人でも作って押せるんだ！」というひらめきが舞い降りました。そしてすぐに蔵書印を作ってくれる業者を探して注文しました。
できた蔵書印がこちらになります。
印影はこんな感じです。弔事用の薄墨を使っているので少し薄いですが、いい感じに押せてます（ちょうど良いインクが手元には弔事用の薄墨しかなかったんです）。
自分は本、特に紙の本が好きです。読むのはもちろんですが、集めたり、本棚に並べて眺めたり、本棚に並べた本を並べ替えたり、ただ触ったり、というのが好きなんです。何年もずっとこの紙の本が好きということは変わりません。蔵書印を押す、というのは本好きにとってプリミティブな喜びがありました。どんどん本を読んで、どんどん蔵書印を押していくぞ！
ちなみに、スタンプスタンダードさんというところで作った蔵書印です。リーズナブルなお値段で作っていただけました。1,650円で蔵書印を作ることができました（デザインは選べませんが）。
蔵書印 ゴム印01/アールデコ そのうち自分の手で蔵書印を彫ってみたいです。新しい人生の目標ができました。
Reference 児島青, (2025), 本なら売るほど (1), KADOKAWA スタンプスタンダード 蔵書印 ゴム印01/アールデコ, retrieved from https://www.creema.jp/item/11365694/detail（最終アクセス日：2026年1月14日）</description></item><item><title>2025年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2025/</link><pubDate>Mon, 29 Dec 2025 23:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2025/</guid><description>2025年のふりかえりです。
2024年のふりかえり 2023年のふりかえり 2022年のふりかえり 2021年のふりかえり 2020年のふりかえり 転職しました これは詳細を省きますが、今年の秋頃に転職しました。
現職でも同僚に恵まれ、チームメンバーとランチを食べたり、おやつタイムをしたり、麻雀を打ったり、楽しく働いています。仕事納めの日の朝会では涙が出るほど笑わされました。年が明けたらいよいよ忙しくなってきそうな予感がしますが、楽しくやっていけると思います。
そうそう、スキルスタックとしてはFlutterを使っています。仕事としてFlutterを書くのはひさしぶりですが、思っていたよりも「やれているぞ」という感覚があります。Dartを書くだけじゃなく、もっとこう&amp;hellip;開発プロセスを考えたり組織を考えたりするところも含めて、持ち前のガッツと明るさで頑張ってます。
技術顧問業を終了しました これについても詳細を省きますが、副業としてお受けしていた技術顧問先との契約を終了させていただきました。
当面は副業で仕事をお受けすることはないと思います。単純に本業でキャパシティーがいっぱいです。
興味の移り変わり 去年くらいまでは仕事でもプライベートでもコードをたくさん書いていたんですが、今年になってからは前職・現職を通じてコードを書く時間がだんだんと減ってきました。AI Agentが実践投入されるようになったことも大きいですし、開発プロセスや組織に関する何かをやることが増えてきたこともあります。自分の興味もどちらかというとそちらに寄りになってきているというのも正直なところです。
とはいえ、まだまだモバイルアプリケーション開発の最前線に立っていこうという気概はあり、コードをモリモリと書いたりテクノロジーマネジメントをしたりといったことに加えて、開発プロセスや組織に関するところでもバリューを発揮していこうという感じです。
終わりに 2026年も頑張ります。それでは、良いお年を！</description></item><item><title>『「わかってもらう」ということ』とソフトウェア開発</title><link>https://okuzawats.com/blog/communication/</link><pubDate>Wed, 17 Dec 2025 22:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/communication/</guid><description>川添愛『「わかってもらう」ということ』を読みました。氏の著作は「精霊の箱 チューリングマシンをめぐる冒険」「自動人形（オートマトン）の城 人工知能の意図理解をめぐる物語」「白と黒のとびら」を読んでおり、情報科学を元にした面白い話を書く方であるなと思っていました。もっとも、氏の専門は情報科学というよりは言語学で、「言葉」というものに焦点を当てた著作が多いようです。『「わかってもらう」ということ』もそのような一冊です。
本書では、「わかってもらう」ことを「言葉を使うことで、他の人たちと、そして自分自身とうまくやっていくこと」 (川添, (2025), p.18) と定義しています。言葉を使うことで他者との関係性をマネジメントすること、なんとかすることと言えるでしょう。また、「言葉というものは本質的にあいまいなもの」 (川添, (2025), p.42) とも言っており、「わかってもらう」とは、そのあいまいな言葉を用いた上で他者との関係性をなんとかするということになります。
さて、話はソフトウェア開発に移ります。
アジャイルソフトウェア開発宣言に署名したひとりであり、クリスタル手法やヘキサゴナルアーキテクチャでも知られるアリスター・コーバーン氏は、「アジャイルソフトウェア開発」の中でソフトウェア開発について、コミュニケーションによる協調ゲームであると言っています。
コミュニケーションとは、人と人とが言葉を用いて相互に理解し合う、つまり相互に「わかってもらう」ことです1。したがってソフトウェア開発とは、言葉を使って他者との関係性を相互にマネジメントした上で、協調ゲームをプレイすること、というように言えそうです。
また、広木大地「エンジニアリング組織論への招待」では、ニクラス・ルーマンを引いて人間のコミュニケーションは以下の3つの不確実性に起因していると言っています（孫引き失礼します）。
他者理解の不確実性：人は他人や事象を完全には理解できない 伝達の不確実性：コミュニケーションが到達するとは限らない 成果の不確実性：仮に理解されたとしても予想されたように行動するとは限らない 同書では、ソフトウェアエンジニアリングにおいてはコミュニケーションの不確実性を減らしていくことが重要な態度であることを指摘しています。「コミュニケーションの不確実性を減らしていく」とは、まさに「わかってもらうこと」に他ならないでしょう。
ソフトウェア開発において「わかってもらう」ことが非常に重要であることがわかりました。ここで話は再び川添愛『「わかってもらう」ということ』に戻ります。
本書では、川添は自身が言葉によってわかってもらうことに失敗した豊富な経験を示しながら、言葉によってわかってもらうための方法論を論じています。それは言い換えれば、他者との関係性をマネジメントするための言葉の使い方であり、コミュニケーションの不確実性を減らしていくための言葉の使い方であると言えます。ソフトウェア開発がコミュニケーションによる協調ゲームであるとすれば、ソフトウェアエンジニアこそ言葉の使い方に意識的であるべきでしょう。
というようなことを考えさせられた、『「わかってもらう」ということ』でした。
References 川添愛, (2025), 「「わかってもらう」ということ」, KADOKAWA アリスター・コーバーン, (2002), 「アジャイルソフトウェア開発」, ピアソン・エデュケーション 広木大地, (2018), 「エンジニアリング組織論への招待」, 技術評論社 川添愛, retrieved from ウィキペディア（最終アクセス日：2025/12/17） 「人と人」以外でもコミュニケーションは成り立ちますが、ソフトウェア開発の文脈なのでここでは「人と人」に話を限定しています。ソフトウェア開発をするのは人なので。少なくとも、今のところは。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>ピザ2枚ルールを超えて〜ピザ2.3枚ルールの提案🍕</title><link>https://okuzawats.com/blog/two-pizza-rule/</link><pubDate>Wed, 05 Nov 2025 21:43:00 +0900</pubDate><guid>https://okuzawats.com/blog/two-pizza-rule/</guid><description>「スクラムの拡張による組織づくり」 (粕谷 (2023)) には、以下の脚注があります。
アメリカのピザのサイズは大きいので日本人の感覚だとあと1枚ピザを増やしても良いかもしれません。(粕谷 (2023), p.27)
アメリカのピザのサイズ感がわからないと、日本ではピザを何枚にすれば良いのかわかりません。そこで、本記事ではアメリカと日本のピザのサイズ感を踏まえて、日本にピザ2枚ルールを適用する場合のピザの枚数を提案したいと思います。
さて、適切なリンクを貼ることができないのですが、アメリカにおけるドミノピザの大きさについてGoogle検索した結果を以下に総合します。州にもよるようですが、おおよそ以下のサイズ感（直径）のようです。
Small: 10 inch = 25.40 cm Medium: 12 inch = 30.48 cm Large: 14 inch = 35.56 cm X-Large: 16 inch = 40.64 cm 一方、日本のドミノピザのサイズ（直径）は以下です。
S: 約23 cm M: 約27 cm L: 約32 cm アメリカはMedium、日本はMを標準的なサイズと見做し、それぞれのピザの面積を比較します（ピザ1枚あたりのカロリーは面積に比例するため）。
項目 アメリカ (Domino&amp;rsquo;s Medium) 日本 (ドミノ M) 直径 30.48 cm 27 cm 面積 729.66 cm² 572.56 cm² 確かに、アメリカのピザは日本のピザと比較して27%ほど大きそうです。
一方で、チーム1人あたりのピザの消費量はどうでしょうか。ピザの大きさが大きくとも、1人あたりの消費量がそれと比較して大きいのであれば、ピザ2枚チームの人数は少なくなるでしょう。なんとなく、アメリカ人は日本人よりもたくさん食べそうな気がします。
国立研究開発法人医薬基盤・健康・栄養研究所の調査によると、アメリカ・日本における20歳以上の平均摂取カロリーは以下のとおりです。予想通り、アメリカの人は日本の人よりもたくさん食べてそうです。
アメリカ: 2,036 kcal 日本: 1,893 kcal 単純にこれを3で割って（1日は3食なので）、1食あたりの摂取カロリーをそれぞれ678 kcal、631 kcalとします。さらに、日本のドミノピザの「アメリカン」（ピザの種類の名前）のMサイズの1ピースあたりのカロリーが148 kcalであること、Mサイズ1枚は8ピースであることから日本のピザ1枚のカロリーを1,184 kcalとします。さらに、アメリカのピザ1枚のカロリーをピザの面積で比例計算して1,508 kcalとします。</description></item><item><title>Spotifyモデルにおけるギルド</title><link>https://okuzawats.com/blog/guild/</link><pubDate>Wed, 29 Oct 2025 21:48:00 +0900</pubDate><guid>https://okuzawats.com/blog/guild/</guid><description>「Spotifyは最早Spotifyモデルを使っていない」「Spotifyモデルは失敗だった」というのは一定の定説として流布しています（ 参考文献2、参考文献3）。Spotifyモデルがうまくいかなかった原因として、一般的には、チームの強すぎる自律性による組織全体の生産性低下、マトリクス型組織によるマネジメント不全などが挙げられます。
ここで、Spotifyモデルでは公式な組織としてスクワッドやチャプターがありますが、Spotifyモデル内でもより形式ばらない非公式な組織として存在する、ギルドについてはどうでしょうか。チャプターと異なりマトリクス組織の公式な枠組みからは外れていますし、参考文献においても特に失敗の原因として挙げられることはないように思います。
画像出典：Henrik and Anders (2012)
Spotifyのホワイトペーパーでは、ギルドについては以下のように触れられてます。
スクワッドの自律性を犠牲にせず、会社をつなげ、スケールメリットを与えるもの 関心に基づくコミュニティであり、知識、ツール、コード、慣習などを共有したいと考えている人々のグループ Spotifyモデルを解説した書籍「ユニコーン企業のひみつ」(Jonathan (2021)) では以下のように触れられています。
「同じ専門分野に興味のあるメンバーからなるグループで、組織を横断して形成される」（p.65） 「ギルドの役割としてさらに重要な点は、ギルドがメンバーに学習と成長への道のりを与えていること」（p.66） 「エンジニアリングマネージャーのしごと」(James (2022)) では以下のように触れられています。
「ギルドはサイロを防ぐ簡単で強力な方法」(p.256) ギルドを作るのが良い選択肢になるのは、チームが車輪の再発明をしている時、チームの技術選択が組織全体から見て乖離し始めている時、設計・互換性・速度などの観点からコードのマージ時に予想外のことが起こっている時、エンジニアが自身の仕事と他のチームの仕事とがつながっていないと感じている時（p.257） 複数のプロダクトを複数のチームで、またはひとつのプロダクトを複数のチームで開発している場合は、チームを横断したつながりを意図して作らなければ、容易にチームがサイロ化します。これは、車輪の再発明が行われる、知識の共有がなされない、など組織のスケールメリットを十分に活かせていない状態です。
チームを横断して同じ分野に興味を持つメンバーが集まり情報を交換することは、スケールメリットを得る機会を提供し、またメンバーの成長の機会も提供します。これがギルドを作ることの意義であり、今もって有効であると考えます。Spotifyモデル自体は失敗したのかもしれませんが、Spotifyモデルに内包されていたギルドという考え方には今も価値がありそうです。
References Henrik Kniberg, Anders Ivarsson, (2012), &amp;ldquo;Scaling Agile @ Spotify with Tribes, Squads, Chapters &amp;amp; Guilds&amp;rdquo; Jeremiah Lee, (2020), &amp;ldquo;Failed #SquadGoals Spotify doesn’t use “the Spotify model” and neither should you.&amp;rdquo;, retrieved from https://www.jeremiahlee.com/posts/failed-squad-goals/ （最終アクセス日：2025年10月29日） mtx2s, (2025), &amp;ldquo;チームの自律性を重んじるだけでは組織がうまく回らない / 「Spotify’s Failed #SquadGoals」を読み解く&amp;rdquo;, retrieved from https://mtx2s.hatenablog.com/entry/2025/10/02/201310 （最終アクセス日：2025年10月29日） Jonathan Rasmusson, (2021), &amp;ldquo;ユニコーン企業のひみつ Spotifyで学んだソフトウェアづくりと働き方&amp;rdquo;, オライリー・ジャパン James Stanier, (2022), エンジニアリングマネージャーのしごと チームが必要とするマネージャーになる方法, オライリー・ジャパン</description></item><item><title>ツールとしてのカンバン、思想としてのカンバン</title><link>https://okuzawats.com/blog/kanban/</link><pubDate>Wed, 15 Oct 2025 21:33:00 +0900</pubDate><guid>https://okuzawats.com/blog/kanban/</guid><description>ツールとしてのカンバン ツールとしてのカンバンとは、チケットの進行状態を可視化できるツールのことです。「カンバンボード」と呼ぶこともあります。TODO、In Progress、Doneといった進行状態別にカラムを持ち、左から右へとチケットを移動していくものです。
具体的な実装として、WebサービスのJiraやasanaがあります。GitHubのプロジェクトでもカンバンボードを使えますし、Obsidianのプラグインでもカンバンボードの機能を提供しているものがあります。JavaScriptのライブラリも存在します。カンバンボードは世にありふれています。
気の利いたカンバンボードであれば、チケットの変更を追跡し、分析の基盤を提供してくれます。
思想としてのカンバン 思想としてのカンバンは、トヨタ生産方式に端を発し、制約条件の理論やリーンソフトウェア開発の考えを取り入れた、プロセス改善のためのプロセス（メタプロセス）です。特徴的な語彙として、見える化、リードタイム、ボトルネック、WIP制限などがあります。
思想としてのカンバンは、見える化のためのツールとして「ツールとしてのカンバン」（カンバンボード）を使います。しかし、カンバンボードを使っているだけでは、思想としてのカンバンを実践しているとは言えません。チームの活動を見える化し、リードタイムを計測し、ボトルネックを特定し、WIP制限をプロセス改善の議論のきっかけとする&amp;hellip;ということを繰り返すことで、プロセスを改善するというのが思想としてのカンバンの実践でしょう。
References Marcus Hammerberg, Joakim Sundén, (2016), 「カンバン仕事術 チームではじめる見える化と改善」, オライリー・ジャパン Eric Brechner, (2016), 「カンバンによるアジャイルプロジェクトマネジメント」, 日経BP David J.Anderson, (2014), 「カンバン ソフトウェア開発の変革」, リックテレコム Henrik Kniberg, (2013), 「リーン開発の現場 看板による大規模プロジェクトの運営」, オーム社</description></item><item><title>Dartのオプショナルタイピング（任意の型付け）</title><link>https://okuzawats.com/blog/dart-optional-typing/</link><pubDate>Thu, 25 Sep 2025 21:09:00 +0900</pubDate><guid>https://okuzawats.com/blog/dart-optional-typing/</guid><description>Dartでは型付けは任意であり、型付けしても良いし、しなくても良いです。この型付けをしてもしなくても良いということを、 オプショナルタイピング（Optional Typing） と呼びます。Dartの初期からDartはオプショナルタイピングです。
プショナルタイピングは、Dartが当時altJSを目指して開発されていた中で、戦略的に導入された言語機能なのかもしれません。またそれもあってか、元々の言語設計者の意図としては、「型付けありがデフォルト」というより、「型付けなしがデフォルト」であるという思想を感じました。なお、この1パラグラフは完全に個人の感想で根拠は全くありません。
さて、具体的なコードの例としては以下の関数定義です。この関数定義は完全に正しいDartのコードです。それぞれ void 、 String に型付けをしていませんが、Dartのコードとして実行可能です。
a() =&amp;gt; print(&amp;#39;a&amp;#39;); b() =&amp;gt; &amp;#39;b&amp;#39;; 型付けが任意であるということは、型付けをしても良いということです。
void a() =&amp;gt; print(&amp;#39;a&amp;#39;); String b() =&amp;gt; &amp;#39;b&amp;#39;; 変数は var または final を用いて以下のように宣言できます。
var n = 42; final n = 42; 変数に型付けをする場合は、以下のように宣言します。
int n = 42; final int n = 42; Effective Dartでは、ほとんどのローカル変数については型付けすべきでないとしています。
Most local variables shouldn&amp;rsquo;t have type annotations and should be declared using just var or final.
逆に言えば、それ以外の場合については型付けした方が良いでしょう。
一般論として、スコープが広くなるほどコードのコンテキストを把握するための認知負荷は高まります。型付けは、人間がコードを読む時の大きなヒントとなります。ローカル変数であればコンテキストの把握に大きな認知負荷はかからないので型付けをしなくても読める、または型付けをしない方が素早く読める場合もあるのでしょうが、スコープが広い場合は人間がコードを読むためには型付けがあった方が好ましいと考えています。
また、関数や変数のスコープが広い場合はその型が暗黙のうちに変わってしまうことの影響が大きく、型付けによって型を明示的に宣言することは有益です。
Reference The Dart type system（最終アクセス日：2025年9月25日） Google Dartのエッセンス:アプリケーションの構築、スナップショット、Isolate（最終アクセス日：2025年9月25日） DO follow a consistent rule for var and final on local variables（最終アクセス日：2025年9月25日） Chris Buckett, (2014), 「プログラミング言語 Dart」, 角川</description></item><item><title>マインスイーパーで不確実性との付き合い方を考える💣</title><link>https://okuzawats.com/blog/minesweeper/</link><pubDate>Mon, 18 Aug 2025 22:32:00 +0900</pubDate><guid>https://okuzawats.com/blog/minesweeper/</guid><description>マインスイーパーで、こんな状況（以下の図を参照）に陥ることがあります。2つのマスのうちどちらか1つに爆弾が置かれており、かつどちらのマスに爆弾が置かれているかを絞る情報がない状況です。このような状況に陥ってしまった場合は、運否天賦で指運に任せてどちらかのマスを開けるしかありません。
このような場合に、他のすべてのマスを確実に開けてから最後の最後に2択を迫る&amp;hellip;ようにプレイしてしまいがちなんですが、さっさと2択を済ませてしまった方が良いです。どちらのマスに爆弾が置かれているかを事前に知ることができないマスがあるという状況において、これらのマス以外、すなわち論理によって確実に進めることのできる部分を進めることの利益は少ないです。言い換えると、「確実に進めることのできる部分」を進めるために費やした時間が、最後の2択で無駄になる可能性があります。
広木 (2018), 「エンジニアリング組織論への招待」から引用します。
無意識的あるいは意識的に、リスクの低いものを優先してやると、結果的に手元には「一番大きな不確実性」が残ります。そのため、膨大なコストを費やした後に、最も大きなリスクに直面することになるのです。(広木 (2018), p.217)
ソフトウェア開発であれば最初に最も不確実な部分1に着手することが経済合理的であり、マインスイーパーであれば運に頼るマスを先に開けることが経済合理的であるということになります。最も不確実な部分を最後に残して確実な部分を先に完了したい、という直感に反して、最初に最も不確実な部分を完了すべきである（経済合理的である）、ということです。
Reference マインスイーパ（最終アクセス日：2025年8月18日） 広木大地, (2018), 「エンジニアリング組織論への招待」, 技術評論社 ソフトウェア開発における「不確実さ」はいくつかに分類されます。詳しくは「エンジニアリング組織論への招待」を参照してください。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>DartでFizzBuzz</title><link>https://okuzawats.com/blog/dart-fizzbuzz/</link><pubDate>Wed, 11 Jun 2025 13:31:00 +0900</pubDate><guid>https://okuzawats.com/blog/dart-fizzbuzz/</guid><description>FizzBuzzを書いてDartを味わっていきます。
まずは引数として整数 n を受け取り、整数 n に対するFizzBuzzを返す関数を実装します。結論から言うとこんな感じで実装しました。
/// 整数[n]に対するFizzBuzzを返す。 /// /// [n]が3の倍数の場合は&amp;#34;Fizz&amp;#34;、 /// 5の倍数の場合は&amp;#34;Buzz&amp;#34;、 /// 3の倍数かつ5の倍数の場合は&amp;#34;FizzBuzz&amp;#34;、 /// それ以外の場合は[n]の文字列表現を返す。 /// @param n FizzBuzzの元となる整数値 /// @returns [n]のFizzBuzz String fizzBuzz(int n) { var s = &amp;#39;&amp;#39;; if (n % 3 == 0) s += &amp;#39;Fizz&amp;#39;; if (n % 5 == 0) s += &amp;#39;Buzz&amp;#39;; return s.isNotEmpty ? s : &amp;#39;$n&amp;#39;; } 見どころがいくつかありますが、まずドキュメンテーションコメントです。Dartにおけるドキュメンテーションコメントに関するガイダンスがEffective Dart: Documentationに示されており、上記のコードではそのガイダンスの一部に従っています。
ドキュメンテーションコメントは /// で始める 最初の1行にサマリーを書き、1行開けて詳細を書く [] を用いて説明内で引数を参照できる @param @returns で引数や返り値の説明を追加することができる 次に、ローカル変数 s を var s = ''; で宣言しています。Effective Dartでは、 var を使って型注釈なしでローカル変数を宣言することが推奨されています。ローカル変数であれば final も使わなくてOKです（今回のコードだと再代入を行なっているのでそもそも final にはできませんが）。</description></item><item><title>DartでHello World</title><link>https://okuzawats.com/blog/dart-hello-world/</link><pubDate>Sat, 07 Jun 2025 23:14:00 +0900</pubDate><guid>https://okuzawats.com/blog/dart-hello-world/</guid><description>ひさしぶりにDartを書きたい気持ちがむくむくと湧いてきたので、まずはHello Worldしてみます。
動作環境：
MacBook Pro 2022 Apple M2 macOS 15.5 Dart SDKのインストール Build a web app with Dartに従うと、Homebrewを用いて以下のようにDart SDKをインストールできます（できました）。
% brew tap dart-lang/dart % brew install dart が、この方法でインストールした場合、Dartのバージョンをプロジェクトごとに管理したい&amp;hellip;という時に困ることになります。なので、今回はこの方法は採用しません。上記のコマンドでインストールしたDart SDKは消しておきます。
% brew uninstall dart % brew untap dart-lang/dart 代わりに asdf を使います。 asdf をまだ使ってない場合は、Getting Startedに従ってセットアップします。セットアップしたら、以下のコマンドでDartをインストールします。
% asdf plugin add dart % asdf install dart 3.8.1 % asdf set dart 3.8.1 .tool-versions が作成されて、その中身はこんな感じになってます。 .tool-versions の挙動については asdf のドキュメントを参照してください。
dart 3.8.1 DartでHello World Dart SDKをインストールできたので、Hello Worldします。こんな感じのコードを helloworld.</description></item><item><title>虫の目・鳥の目・魚の目👀</title><link>https://okuzawats.com/blog/eyes/</link><pubDate>Sat, 07 Jun 2025 05:13:00 +0900</pubDate><guid>https://okuzawats.com/blog/eyes/</guid><description>「経済を見る3つの目」(伊藤(2014))という書籍に、「虫の目・鳥の目・魚の目」という考え方が紹介されています。経済を理解するためには3つの目が必要である、その3つの目とは「ミクロを見る虫の目」「マクロを見る鳥の目」「流れを見る魚の目」である、というものです。この考え方は経済だけでなくさまざまに応用できる気がするので、この記事ではソフトウェア開発についてこの3つの目を考えてみたいと思います。
虫の目🐛 まずは虫の目。これはミクロに物事を見る目です。経済学ではミクロ経済学という分野があり、「生産者（企業）が経済的な取引を行う市場に着目する」ものです（「ミクロ経済学 - Wikipedia」より引用）。価格理論、ゲーム理論、契約理論がその主要分野です。経済における個々のプレイヤーの動きに着目する、と言えば良いでしょうか。
ソフトウェアに例えると、個々のコンポーネントに着目することに相当すると考えます。
例えば、サーバーがあり、Webフロントエンドがあり、iOSアプリがあり、Androidアプリがあり&amp;hellip;という場合のサーバー、Webフロントエンド、iOS、Androidがそれです。サーバーサイドにはサーバーサイドの技術があり、WebフロントエンドにはWebフロントエンドの技術があることでしょう。サーバーサイド特有の知識があり、さらに特定の技術（GoとかRuby on Railsとか）についての知識があります。モバイルについても、モバイル特有の知識があり、さらに特定の技術（Android SDKとかFlutterとか）についての知識があります。
個々のコンポーネントに着目し、そのコンポーネントに対する理解を深めることがソフトウェア開発における虫の目と言えます1。
鳥の目🦆 次に鳥の目。これはマクロに物事を見る目です。経済学ではミクロ経済学に対してマクロ経済学という分野があります。マクロ経済学は、「個別の経済活動を集計した一国経済全体に着目するもの」です（「マクロ経済学 - Wikipedia」より引用）。個々のプレイヤーの動きに着目するミクロ経済学に対して、その総和である経済全体に着目するのがマクロ経済学である、といったところでしょうか。
ソフトウェアに例えると、システムのアーキテクチャに着目することに相当すると考えます。
ここでは、個々のコンポーネントを抽象的に考え、システムの目的を実現するためのアーキテクチャとして捉えます。実務で置き換えて考えると、サーバーサイドエンジニア、Webフロントエンドエンジニア、モバイルエンジニアを集めてひとつのプロダクトを作っていく状況がわかりやすいでしょうか。個々のコンポーネントの詳細を把握する必要はなく、それらのインターフェース設計と全体の構成を考えることになるでしょう。
個々のコンポーネントを抽象化し、その統合としてのアーキテクチャに対する理解を深めることがソフトウェア開発における鳥の目と言えます2。
魚の目🐟 最後に魚の目。これは「潮の流れをしっかり見極める眼力、あるいは経済の流れを見る力」 (伊藤(2014), p.15)です。これが一番大切な視点である、とのこと。
ソフトウェアに例えると、コンポーネントとアーキテクチャに対する、技術マネジメントと言ったところでしょうか。技術マネジメントとは例えば、ビジネス要件の変化に伴いアーキテクチャを進化させる判断、技術的負債の返済に対する投資判断、モダン技術の採用とリプレイスの判断、などを指します。
ビジネスや技術は、常に変わり続けます。その流れの変化を見極めて、コンポーネントとアーキテクチャも変化・進化させていく技術マネジメントを行うことは重要でしょう。こういった技術マネジメントがソフトウェア開発における魚の目と言えます3。
まとめ またポエムを書いてしまいました。
Reference 伊藤元重, (2014), 「経済を見る3つの目」, 日本経済新聞出版社社 伊藤公平, (2022), 2022年度大学院入学式 式辞（最終アクセス日：2025年6月7日） ミクロ経済学 - Wikipedia（最終アクセス日：2025年6月7日） マクロ経済学 - Wikipedia（最終アクセス日：2025年6月7日） 他の切り方もあると思います。&amp;#160;&amp;#x21a9;&amp;#xfe0e;
異論は認める。&amp;#160;&amp;#x21a9;&amp;#xfe0e;
本当か？&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>テスト駆動開発（TDD）と五輪書</title><link>https://okuzawats.com/blog/the-book-of-five-rings/</link><pubDate>Sun, 02 Mar 2025 16:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/the-book-of-five-rings/</guid><description> 宮本武蔵は『五輪書』の中で、戦いで生き残るためのたった1つの方法は「はたして自分は生き残れるのだろうか」という雑念を取り除くことだと述べている。生き残れるかを心配していると、まばたきをするくらいほんの一瞬の躊躇が生と死を分けることになる。
プログラミングも戦いである。それも人間の心の中で起こる戦いだ。個人やチームの強さと勇気で、自信喪失や欲望、傲慢などの悪魔の囁きを打ち負かすことができるかを試す戦いである。宮本武蔵の戦いと同じく、勝ち負けの心配から自分を断ち切ることが、勝利への鍵である。
(Kent Beck, 「eXtreme Programmingテスト技法」(日本XPユーザーグループ (2001)) の序文に寄せて)
Kent BeckがXPのプラクティスであるテスト駆動開発（TDD）に関して、宮本武蔵の五輪書を引いた味わいの深い文章です。自分も大いに感銘を受け、このテキストを何度も読み返して、プログラミングに対して向き合っていました。
当然、原典である五輪書にも当たるべきです。五輪書（ごりんのしょ）は、宮本武蔵による兵法書であり、その剣術の奥義をまとめたものであると言われています。原文は読みにくいので、現代語訳(大倉, (2012)) を入手して読んでみたところ&amp;hellip;Kent Beckの序文に相当するテキストは見当たりません（見つけた方は教えてください）。
かろうじて近い内容の言葉を探すと、水の巻に見られます。五輪書は、地の巻、水の巻、火の巻、風の巻、空の巻の5章から構成されており、水の巻では心の構えや身体の構えについて論じられています。
兵法における心の持ち方。兵法の道において、心の持ちようは平常の心と変わってはならない。平常のときも戦いのときも少しも変わらず、心を広く素直にして、緊張しすぎず、少しも弛まず、心に偏りがないように、心を真中におき、心を静かに揺るがせて、その揺るぎのなかにも一瞬たりとも揺るぎを失わないように、よくよく吟味すべきである。（大倉(2012),p.36）
Kent Beckが指しているのがこの一節であると言い切ることはできませんが、内容としては近いかと思います。原文も引用しておきます。
兵法心持之事。兵法之道におゐて、心の持様ハ、常の心に替事なかれ。常にも兵法之ときにも、少も替らすして、こゝろを廣く直にして、きつくひつはらす、すこしもたるます、心のかたよらぬやうに、心をまん中に置て、心を静にゆるかせて、其ゆるきのせつなもゆるきやまぬやうに、能々吟味すべし。（大倉(2012), p.139）
Kent Beckは、TDDによってプログラミングにおける不安を断ち切ることができると言っています。
時には勝ち、時には負ける。やりすぎてしまうこともある。興奮したり、不安になって先走ることもある。それでも、私には従うべき道がある。私が不安を断ち切ることができるように、自分を導いてくれる1つのプラクティスというテクニックが。
(Kent Beck, 「eXtreme Programmingテスト技法」(日本XPユーザーグループ (2001)) の序文に寄せて)
自分もこのような心境に至りたいものです。まだまだ鍛錬が必要です。
References 日本XPユーザーグループ, (2001), 「eXtreme Programmingテスト技法」, 翔泳社 宮本武蔵, 大倉隆二 訳, (2012), 「五輪書 現代語訳」, 草思社 五輪書 - Wikipedia（最終アクセス日：2025年3月2日）</description></item><item><title>アーキテクトは庭師のようにふるまう</title><link>https://okuzawats.com/blog/architect-and-gardener/</link><pubDate>Fri, 21 Feb 2025 16:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/architect-and-gardener/</guid><description>「ソフトウェアアーキテクトのための意思決定術」(（Perera, (2024)) に以下の記述があります。
ソフトウェアアーキテクトは、指揮官のように振る舞うのではなく、庭師のように振る舞うべきだと言われている。前者が定義し指示を与えるのに対し、後者は形を整え、選別し、雑草を取り除く。（Perera, (2024), p.257）
何となく言いたいことはわからないでもないですが、庭師の仕事に対する解像度が低いためモヤモヤが残ります。そこで最寄りの大型書店に足を運び、園芸コーナーから庭師の仕事がわかるような書籍を探してきました。「ビジュアル版 庭師の知恵袋」(日本造園組合連合会, (2008)) です。2021年時点で47刷・24万部のロングセラーだそうです。
本書を読み解きながら、ソフトウェアアーキテクトの振る舞いについて考えていきたいと思います。
道具を選ぶ、道具の使い方に習熟する 庭師の知恵袋は、はじめに道具の使い方から始まります。例えば、枝を切るために使用するハサミは4種類あり、目的によって使い分ける、というような内容です。それぞれのハサミの使い方も解説されます。また、それぞれの道具の使い方に習熟する必要がある、との言葉もあります。
ソフトウェアに置き換えると、事業やサービスの目的に照らして適切な技術選定を行うこと、選定した技術に対して習熟する必要があること、と言えるでしょうか。ソフトウェアエンジニアにとって、道具の選択肢を増やすこと、それぞれの選択肢に対する習熟度を高めることの重要性は議論を待たないでしょう。
庭木は自然のままではダメ 庭木の手入れに関する一節です。枝を正常に生育していくためにはこまめに手を加えなくてはならないということ、手入れを行った場合には周囲の庭木の生育の妨げとなる・住まいとの不調和につながることが述べられています。
ここでは庭全体に対する個々の木の手入れに目を向けています。ソフトウェアに置き換えると、ソフトウェアやサービスの全体に対する個々のコンポーネントに目を向けることにつながるでしょうか。また、手入れとは保守に他ならないでしょう。そう考えると、ソフトウェア・サービス全体を調和させ、全体として成長していくためには、個々のコンポーネントを適切に保守しなくてはならない、と置き換えて考えられるでしょうか。
樹木の生理を知れ 樹木の生理を学ぶべきであること、樹木の生理に逆らって剪定すべきではないことが述べられています。樹木の生理を知り、生育のサイクルに従って剪定することではじめて美しい樹形を実現できることが述べられています。
ソフトウェアでは、設計原則を学び、原理・原則に則ってコードを修正していくことで内部品質の高いソフトウェアを実現できる、と置き換えて考えることができるでしょうか。あるいは、ソフトウェア工学を学び、適用することと言えるかもしれません。
害虫との戦い 害虫の生態を理解した上で対策を行なっていく必要が述べられています。
ソフトウェア開発において「殺虫剤のパラドックス」というような言葉があるように、ソフトウェアの不具合を害虫と例えることは馴染みがあります。その例えに乗っかると、ソフトウェア品質保証・ソフトウェアテスト技法の理論を学び、適用していくことで高品質なソフトウェア・サービスを提供できるようになる&amp;hellip;と言い換えられるでしょうか。
植えるコツ、育てるコツ、手入れのコツ 植物を植えることと育てることと手入れすることでは、それぞれ異なったコツがあると言います。
ソフトウェアで言えば&amp;hellip;0-1 フェーズでの開発、サービスのグロース、保守運用ではそれぞれ異なったスキルセットが必要である&amp;hellip;と言えるでしょうか。
まとめ ちょっと苦しかったかもしれません。
References Srinath Perera, (2024), 「ソフトウェアアーキテクトのための意思決定術」, インプレス 日本造園組合連合会, (2008), 「ビジュアル版 庭師の知恵袋」, 講談社</description></item><item><title>Keychron K11 Max QMK/VIA ワイヤレスカスタムメカニカルキーボード（日本語配列）を買いました⌨️</title><link>https://okuzawats.com/blog/keychron-k11-max/</link><pubDate>Sun, 26 Jan 2025 22:15:00 +0900</pubDate><guid>https://okuzawats.com/blog/keychron-k11-max/</guid><description>Keychron K11 Max QMK/VIA ワイヤレスカスタムメカニカルキーボード（日本語配列） を買いました。2024年の振り返りで書いていた、2024年末に購入していたキーボードのことです。一ヶ月弱使ってみて、非常に良い、最高である、と思っています。1
見た目 何が最高かというと、まずは見た目です。こんな感じです。特に言葉はいらないでしょう。
Fig-1 Keychron K11 Max 画像出典：Keychron K11 Max QMK/VIA ワイヤレス カスタム メカニカルキーボード（65%| 日本語配列） – Keychron Japan
左右分離レイアウト Keychron K11 Maxは、キーボード本体こそ2つに分かれていないものの、キーは左右に分離されています。いわゆるエルゴノミクスキーボードです。ロジクールERGO K860ワイヤレススプリットキーボードを買った時にも書いていますが、自分の場合、キーボードは必ずしも物理的に2つに分かれている必要はなく、キーが分かれていれば十分です。
Keychron K11 Maxはそれです。
ロープロファイル Keychron K11 Maxはロープロファイルです。ロープロファイルであることで、手首が疲れにくいです。リストレストが必要かどうか？迷っていましたが、現在はリストレストを使っていません。リストレストなしでキーボードが打てるので、かつワイヤレスであることで、デスクの上を広く使うことができています。
とても快適です。
JIS配列 左右分離レイアウト・ロープロファイルでかつJIS配列のキーボードというものはあまりないんですが、Keychron K11 MaxのJIS配列版がありました。Keychron Japanのサイトを見ていたらJIS配列版があったため、即買いしてしまいました。
個人的には、日本語入力するためにはJIS配列のキーボードを使いたいです。
その他の細かいポイント 複数PC間の切り替え キーボードショートカットで切り替えられます。仕事用のMacとプライベートのMacの2台で使用していますが、便利に切り替えられています。
キーのリマップ 基本的にデフォルトのキーマップで使用していますが、どうしても指の運びが上手くいかない一箇所だけカスタマイズしています。Keychron公式のWebアプリを使って、一瞬でリマップできました。便利ですね。
打鍵感 赤軸を使っています。カチャパチ感が快適です。標準のキーキャップの触り心地も良いです。
まとめ Keychron K11 Max、とても良いです。日常使い用の他に、保管用・鑑賞用としてあと2台くらい買っておいてもいいかもしれませんね。
また新しいキーボードを買いたくなってしまう可能性は否定できません。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>2024年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2024/</link><pubDate>Mon, 30 Dec 2024 16:39:00 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2024/</guid><description>年末恒例のふりかえりです。このブログも開設から5年が経ちました。
2023年のふりかえり 2022年のふりかえり 2021年のふりかえり 2020年のふりかえり 仕事 仕事というか勉強的なところとしては、Luaでアルゴリズムの問題を解いたり、Go言語でインタプリタを作ったりといった基礎的なところをやっていた他に、SwiftUIやTCAを書いてiOS / Swiftへのキャッチアップを試みたり、React / TypeScriptでマークダウンエディタを書いてWebフロントへのキャッチアップを試みたりしていました。
コード以外のところでは、ワインバーグやLEADING QUALITYを読んで品質について考えを深めたり、DevOps、オブザーバビリティ、アジャイルテスト、リーン開発、アジャイル開発などを学んで、何をどう作るか？みたいなことについて考えを深めたりしていました。
仕事ではAndroidのコードも引き続き書いてます。コードを書く以外の仕事が多いですが、意識してコードを書くようにしないといけないなっと思ってます。
執筆 2024年は特に執筆活動をできていないんですが、2023年にSoftware Design誌に寄稿したクリーンアーキテクチャの記事がムック本として再録されました。今も執筆をしたい気持ちはありますが、2024年はどちらかというとインプットが多めでした。そのうちまた何か書きたいです。
［入門］ドメイン駆動設計 ――基礎と実践・クリーンアーキテクチャ ブログについては、本ブログに本記事を除いて16記事を書いた他、勤務先の技術ブログを2本執筆しました。
NANDからCPUを作る（前編） Androidアプリ開発部で合宿を行い、技術的負債についてみんなで考えました〜2024年冬〜 登壇 2024年は後半に勤務先主催または共催のイベントでのみ登壇しました。なるべく社外に出ていきたい気持ちはあるんですが、大きめのイベントではCfPを出しても通らなかったり、小さめのイベントではオフライン回帰や開催時間の問題があってなかなか参加しにくく、難しい状況でした。2025年はもう少し頑張って社外に出て行ってもいいかなっとは思ってます。頑張ります。
カンファレンス参加をいかに正当化するか 「Chatwork」Android版アプリを 支える単体テストの現在 Androidアプリのモジュール分割における:x:commonを考える キーボード 2024年は、キーボードをいくつか変遷しました。まず2024年年初は左右分離型のHatsukey70を組み立てるところから始まりました。久しぶりにハンダゴテを握り、部品をひとつひとつハンダ付けしていき、キーボードが出来上がる体験は最高でした。カスタマイズ性も高く、非常に楽しいキーボードです。
薄型の左右分離型キーボード「Hatsukey70」を組み立てました⌨️ Hatsukey70はお気に入りのキーボードではあるんですが、打鍵していると手首が疲れてしまうという問題に遭遇しました（自分特有の問題だと思います）。Hatsukey70を使い続けて何らかの方法で問題解決を図るか悩ましいところでしたが、ちょっと別の方向性のキーボードを模索してみることにしました。
この問題を解決するにあたって、「通常のキーボードは手前から奥に向かって傾斜する構造になっているが、もしかしたらこの構造が手首の疲れの原因なのかもしれない」という仮説を立てました。そこで、次にいわゆるエルゴノミクスキーボードを調べ、ロジクールのERGO K860に行き着きました。
「ロジクールERGO K860ワイヤレススプリットキーボード」を買いました⌨️ 結果としてERGO K860はとても良くて、このキーボードを使い始めてから疲れが非常に軽減されました。Hatsukey70とは異なりキーボードが物理的に割れてはいませんが、キーは左右分離レイアウトになっていて疲れにくいです。仕事用とプライベート用の2台のMacの切り替えも楽でした。
ERGO K860には基本的に満足していたんですが、さらに上を目指していきます。次の課題は、ERGO K860はテンキー付きのデザインであるため、右手側のスペースを多めに使ってしまいます。右手側にはトラックボールを配置しているんですが、ホームポジションからトラックボールまでの距離が長く、キーボードとトラックボールとの切り替えが素早くできないという点が改善点です。キーボードとトラックボールとの切り替えは1日に何度も行うので、この切り替えの時間は生産性にダイレクトに影響を与えると考えました。
そこで、今度はテンキーレスのキーボードを探します。ERGO K860はリストレスト一体型だったのでリストレスト不要である点は良かったところですが、次はリストレストをキーボードと別に用意することは許容して、テンキーレスかつ無線接続可能なキーボードを探します。いくつか候補はありましたが、勤務先の福利厚生で無償貸与できたHHKB Professional HYBRID Type-Sを使うことにしました。
HHKBの完成度の高さは知っていましたが、やはり完成度が高いです。基本的には満足しているのですが、HHKBは少し高さのあるキーボードであるため、前述の手首の疲れ問題が少し気になります。そうなるともう少しロープロファイルなメカニカルキーボードを試したくなってくるわけですが、ロープロファイルで、左右分離レイアウトで、無線で、メカニカルで、できればJIS配列が良いとなると流石に選択肢がない&amp;hellip;と思ってたんですが、見つけてしまったので自分へのクリスマスプレゼントとして即購入してしまいました。
まだ手元に届いてないので試せていませんが、はやく試してみたいものです。本当に届くのだろうか？
ブログ 地道にブログシステムにも手を入れ続けています。2023年はさくらのクラウドのウェブアクセラレータとオブジェクトストレージで配信するようにした点がハイライトでしたが、2024年も大きな改善を行なっています。
本ブログは静的サイトジェネレータのHugoを使って、Bear Cubというテーマをカスタマイズして使っています。このテーマに大胆に手を入れ、原型を留めないレベルで改修しました。具体的にはレイアウトをnew.cssというCSSフレームワークに完全に依存するようにして、HugoのテンプレートからはCSSをすべて無くしました。
あとは多言語対応したのも2024年だったかな&amp;hellip;？日本語の記事しか書いていないので、今のところ多言語対応した意味はありません。英語で記事を書きたい気持ちだけはあります。
ブログのコードも見た目もスッキリして、2024年の改修については自分的には大満足です。
健康 一念発起してダイエットを始めました。6月頃に体重がピークで、そこからダイエットを頑張ってピーク時から -6.1kg を達成しています。年末年始の休みでリバウンドしないかどうかが心配ですが、今のところは体重をキープしています。
終わりに 良いお年を！</description></item><item><title>「Go言語でつくるインタプリタ」を読みました📚</title><link>https://okuzawats.com/blog/writing-an-interpreter-in-go/</link><pubDate>Sun, 27 Oct 2024 15:53:00 +0900</pubDate><guid>https://okuzawats.com/blog/writing-an-interpreter-in-go/</guid><description>「Go言語でつくるインタプリタ」 (Thorsten (2018))を読みました。読みました、というか読んでインタープリタを実装し、一部の構文を追加で実装しました。書籍を購入したのが2022年5月、そこから一度チャレンジして諦め、2回目のチャレンジが2023年1月、3回目のチャレンジで読了できました。足掛け2年5ヶ月となかなか時間がかかり、途中しんどい時期もありましたが、読了できて良かったです。
ソースコードはこちらのリポジトリに置いておきました。GitHub Actionsで実装したインタープリタを実行して、FizzBuzzを動かすところまで書いてあります。
okuzawats/writing-an-interpreter-in-go インタープリタに関する学習の履歴 2022年5月にインタープリタを実装して学ぼうと思い立ち、最初に手に取ったのが本書「Go言語でつくるインタプリタ」でした（たぶん）。飽きたのか挫折したのか（おそらく後者）、最初のチャレンジは失敗に終わりました。
その後、「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」 (遠藤 (2017))という書籍に出会い、「Go言語でつくるインタプリタ」に再チャレンジする前に、こちらの本を先に読みました。
「RubyでつくるRuby」は、「Go言語でつくるインタプリタ」よりも入門的な書籍です。「Go言語でつくるインタプリタ」では構文解析のところから実装していきますが、「RubyでつくるRuby」では著者の実装したライブラリを利用することで構文解析の実装とその説明を省略し、読者は抽象構文木の評価のみを実装します。「RubyでつくるRuby」を読了すれば、Ruby（のサブセット）のインタープリタが完成します1。
「RubyでつくるRuby」を先に読んでおいて良かったと思ったことが一つあります。「Go言語でつくるインタプリタ」では構文解析の実装が終わらなければ動かすことのできない、実際にインタープリタを動かしてプログラムを実行する、というところを先にできたことです。実際、「Go言語でつくるインタプリタ」の後半の内容は、「RubyでつくるRuby」で学習済みの内容が多く、既視感を感じながら実装することになりました。
ゴールが見えていることで、「先の見えなさ」からくるモチベーションの低下がなくなりました。
何故、2回も「Go言語でつくるインタプリタ」のチャレンジに失敗したのか 内容を十分に理解できなかったこともありますが、同じような実装が続いて飽きてしまうためです。今回の3回目のチャレンジでも、飽きとの戦いがありました。しかし、前よりもインタープリタの理論を理解できてきたこと、Go言語についても理解を深めたことで、何とか読了することができました。
インタープリタを拡張した FizzBuzzを実装するために剰余演算子が欲しかったので、インタープリタを拡張して剰余演算子を実装しました。20分くらいで実装できて感動しました。
剰余演算子を実装・FizzBuzzを修正 最終的に、こんな感じでFizzBuzzを実装しました。
let fb = fn(n) { if (n &amp;gt; 1) { fb(n - 1); }; if (n % 15 == 0) { puts(&amp;#34;FizzBuzz&amp;#34;); return; } if (n % 3 == 0) { puts(&amp;#34;Fuzz&amp;#34;); return; } if (n % 5 == 0) { puts(&amp;#34;Buzz&amp;#34;); return; } puts(n); }; fb(100); まとめ 読んでいる途中は「楽しい」という感覚はあまりありませんでしたが、いざ完成して自分で書いたプログラムを動かせるようになるととても楽しいです！また、言語処理型の気持ちがすこしだけわかるようになった気がします🤏</description></item><item><title>[Kotlin] Non-Nullにこだわらず、適切にNullableを使う</title><link>https://okuzawats.com/blog/nullable-or-non-null/</link><pubDate>Wed, 09 Oct 2024 06:15:00 +0900</pubDate><guid>https://okuzawats.com/blog/nullable-or-non-null/</guid><description>Kotlinでは、Non-NullとNullableを区別します。Nullableな型は、型の末尾に ? を付けます。
var nonNull: Int = 42 var nullable: Int? = null 一般に、「NullableよりもNon-Nullが好ましい」とされます。それについては自分も同意します。しかし、無条件に同意するものではありません。例えば以下のコードです。この 0 が何の意味もない、いわば null の代わりとして使われているのであれば、Nullableとするよりも悪いと思います。
var a: Int = 0 上記の変数がNullableであれば、KotlinはNon-NullとNullableを区別するため、以下のようにnullチェックが強制されます。
if (a != null) { // do something here } 一方で、 null の代わりにデフォルト値（例えば 0 ）を使用した場合は、これは強制されません。簡単に言えば、このチェックは容易に忘れられます。
if (a != 0) { // &amp;lt;= このifは簡単に忘れ去れられる // do something here } デフォルト値が何らかの意味を持つ場合はNon-Nullとしてデフォルト値を用いることで問題ありません。一方で、型をNon-Nullにするためだけにデフォルト値を用いる場合、すなわちデフォルト値が何の意味も持たない場合は、Nullableよりも悪くなります。何の意味も持たないオブジェクトを容易に利用可能な状態となってしまうためです。
このような場合には、空の状態を表すためにNullableな変数を用いて null として状態を表す、または場合によってnullオブジェクトパターンの使用を考えるべきである、と思います。</description></item><item><title>goenvでGoのバージョンを管理する</title><link>https://okuzawats.com/blog/goenv/</link><pubDate>Mon, 23 Sep 2024 09:26:00 +0900</pubDate><guid>https://okuzawats.com/blog/goenv/</guid><description>趣味でGoを書く機会が増えてきたので、そろそろ anyenv 的な方法でGoのバージョンを管理するか&amp;hellip;と重い腰を上げました。Go言語のバージョンマネージャで広く使われているものは、 pyenv や rbenv などの流れをくむ goenv と nvm などの流れをくむ gvm があります。なお、自分の使っているOSはmacOS Sonomaです。
go-nv/goenv: :blue_car: Like pyenv and rbenv, but for Go. moovweb/gvm: Go Version Manager どちらもGitHubにリポジトリが存在しているので最近のメンテナンスの状況を見つつ、今回は goenv を用います。
Goのアンインストール まずはグローバルにインストールされているGoはもう不要になるので、アンインストールしておきます。
% go version go version go1.23.1 darwin/arm64 % brew uninstall go Uninstalling /opt/homebrew/Cellar/go/1.23.1... (13,231 files, 268.2MB) % go version zsh: command not found: go goenvのインストール Homebrewで goenv をインストールします。
% brew install goenv INSTALL.mdを参考にしつつ、自分はzshを使っているので ~/.zshrc に以下を書き込み、最後に source ~/.zshrc を実行します。</description></item><item><title>はじめてのSwiftUI</title><link>https://okuzawats.com/blog/swiftui/</link><pubDate>Fri, 16 Aug 2024 15:03:00 +0900</pubDate><guid>https://okuzawats.com/blog/swiftui/</guid><description>SwiftUIについて学んでいこうと思いますので、SwiftUIのコードを読んでいきます。まずはXcodeから新たにSwiftUIのファイルを作成すると、こんな感じのコードが生成されます。Xcodeのバージョンは 15.4 です。
import SwiftUI struct MyFirstSwiftUI: View { var body: some View { Text(&amp;#34;Hello, World!&amp;#34;) } } #Preview { MyFirstSwiftUI() } 1行目から見ていきます。1行目には import が書かれています。
import SwiftUI Swiftにおける import は、モジュールやフレームワークを使用可能にするためのキーワードです。ここでは、 SwiftUI を import しています。これによって、SwiftUIを使用できる状態になります。
空行を挟んで3行目には以下のコードが書かれています。
struct MyFirstSwiftUI: View { struct は、構造体を宣言するためのキーワードです。ここでは、 MyFirstSwiftUI という名前の構造体を宣言しています。また、 : View は、 MyFirstSwiftUI が View プロトコルに準拠していることを宣言しています。 View プロトコルに準拠している型は、Viewの表示内容を示すために後述する body を宣言する必要があります。
その body は、4行目で宣言されています。
var body: some View { some は、ここでは body が View プロトコルに準拠する何らかの型である、ということを表すSwiftのキーワードです。これは、Opaque Return Typeと呼ばれます。金田(2019)では、以下のように説明されています。</description></item><item><title>バグ修正は設計改善チャンス🐛</title><link>https://okuzawats.com/blog/embrace-bug-fix/</link><pubDate>Thu, 01 Aug 2024 06:12:00 +0900</pubDate><guid>https://okuzawats.com/blog/embrace-bug-fix/</guid><description>ソフトウェアを開発している以上、バグが混入することは避けられません。ですが、バグが混入しにくいコードを書くことは、プログラマーの努力によって可能です。バグ修正は、バグが混入しにくいコードに進化させる、設計改善のチャンスであると思います。
コードレビューをしている開発現場であれば、バグが混入するということは、
プログラマーがバグのあるコードを書く、あるいは既存のコードを修正する プログラマーが最低限の動作を確認する、あるいは単体テストを書く1 CIを行う レビュワーがコードレビューを行う etc というすべての工程をバグがすり抜けるということです。
プログラマーにプログラミング言語に対する基本的な理解があることを前提とすれば、プログラマーが自身の書いたコードのバグがあることを認知できないことは、コードの理解容易性が低い状態であることが一因として挙げられます。また、コードレビューは品質保証ではありませんが、レビュワーがバグの可能性を指摘できないこともコードの理解容易性が低いことを示唆します。
バグが混入した一因としてコードの理解容易性が低いことがあったと仮定するのであれば、（広義の）バグの修正には理解容易性の向上までをセットで考えることもできるのではないでしょうか2。そこまでできると、バグをenbraceすることができるようになると考えています。まあ、バグが発生しないに越したことはないですが。
単体テストのある開発現場であれば、ですが。&amp;#160;&amp;#x21a9;&amp;#xfe0e;
コメントを追加する、というような些細なことでも良いと思います。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>「手を動かしてわかるクリーンアーキテクチャ」を読みました📚</title><link>https://okuzawats.com/blog/get-your-hands-dirty-on-clean-architecture/</link><pubDate>Mon, 29 Jul 2024 21:41:00 +0900</pubDate><guid>https://okuzawats.com/blog/get-your-hands-dirty-on-clean-architecture/</guid><description>今月（2024年7月）に発売された「手を動かしてわかるクリーンアーキテクチャ ヘキサゴナルアーキテクチャによるクリーンなアプリケーション開発」（Tom Hombergs著, 須田智之訳）を読みました。同じく今月（2024年7月）に発売されたムック本「［入門］ドメイン駆動設計 ――基礎と実践・クリーンアーキテクチャ」のクリーンアーキテクチャの章に寄稿した著者のひとりとしては、是非ともチェックしておかなくてはならないという想いで読みました（宣伝失礼しました）。
「手を動かしてわかるクリーンアーキテクチャ」は、概念としてのクリーンアーキテクチャの解説書としての体裁を取りつつ、具体的な実装についてはヘキサゴナルアーキテクチャを採用して説明しています。この手の解説はどうしたって著者の主観・意見が強く反映される運命にあると思っているんですが、本書もその例に漏れず、著者の見解を交えて説明がなされていますが、筆者の見解については「筆者の見解である」旨が書かれているので親切です。また本書では訳注が多く追加されており、訳注をあわせて読むことで理解を深められる構成になっています。訳注がある分、原著で読むよりお得です。
保守容易性 本書の第1章「保守容易性」では、保守容易性がいかに大切か、他のソフトウェア品質要件と比較して保守容易性が何故特別なのか、といったことが主張の出発点として語られています。「優れたアーキテクチャを選択すれば、保守容易性は向上する」という理由から、クリーンアーキテクチャ・ヘキサゴナルアーキテクチャを採用する有用性も主張されます。
書籍「クリーンアーキテクチャ」の著者であるRobert C.Martinも、別の書籍「クリーンコーダー」の中で「構造を犠牲にして機能を届けるのはバカのやること」と書いて、保守容易性が大切であることを主張しています。「構造を犠牲にして機能を届けるのはバカのやること」、私の好きな言葉です。
一方、書籍「クリーンアーキテクチャ」では、優れたアーキテクチャでは、重要でない選択肢（技術的な詳細）については、できるだけ長い期間、できるだけ多く選択肢を残すことがソフトウェアの保守容易性を高めるためには重要である、という主張をしています（Robert, (2018), p.151）。言い換えれば、詳細と無関係に方針を定められることが大切である、ということです。「手を動かしてわかるクリーンアーキテクチャ」では強く主張されていない点かと思いますが、補足する価値がある点だと考えます。
多層アーキテクチャ 次に「手を動かしてわかるクリーンアーキテクチャ」では、従来の多層アーキテクチャの問題点を指摘しています。その詳細についてはここでは触れませんが、いくつかの落とし穴があることから、従来の多層アーキテクチャは保守容易性を低下させてしまうという旨の主張がされています。本書の出発点は、保守容易性は他のソフトウェア品質要件と比べても非常に大切であるということでした。本書の主張からすると、従来の多層アーキテクチャが保守性を低下させてしまうのであればそれは良いアーキテクチャではない、ということになるでしょう。
一方で書籍「クリーンアーキテクチャ」では、アーキテクチャの正当性を依存関係逆転の原則と安定度・抽象度等価の原則を用いて説明しています。書籍「クリーンアーキテクチャ」においては、ソフトウェアの設計原則として、SOLID原則、コンポーネントの原則が説明されています（「手を動かしてわかるクリーンアーキテクチャ」でも依存関係逆転の原則については説明されている）。
2冊の間で説明の仕方は異なりますが、同じ結論に至っているところは興味深いです。
ヘキサゴナルアーキテクチャ Robert C.Martinの説明するクリーンアーキテクチャは、オニオンアーキテクチャやヘキサゴナルアーキテクチャを一般化したものである、ということをご存知の方は多いと思います。私は、クリーンアーキテクチャの理解の難しさはそれが一般化されたものである故に具体的な実装が想像しにくいことにあるのではないかと愚考するものです。
本書では、クリーンアーキテクチャの具体的な実装としてヘキサゴナルアーキテクチャを用いています。これが本書の独自性を産んでいると共に、わかりやすくしている点であると思います。
クリーンアーキテクチャは一般化されたアーキテクチャであり、いわばメタ・アーキテクチャです。故に設計者・実装者によって様々な実装が可能である一方、理解の難しさにつながっている面もあると思います。また、クリーンアーキテクチャの説明においてドメイン駆動設計で示されるような設計パターンが部分的に取り入れられていたりすると、学習者としては「一体自分は何を学んでいるのだろうか？」という気持ちにもなるものです。クリーンアーキテクチャとドメイン駆動設計で同じ用語が異なる意味で用いられていることもあり、理解のしにくさに拍車がかかります。
本書ではヘキサゴナルアーキテクチャを用いて実装例が示されており、それがクリーンアーキテクチャに対する理解を助けてくれると感じました。また、ドメイン駆動設計で示されるような設計パターンについても、説明や訳注がなされており、これも理解を促進してくれます。
参考文献 Tom Hombergs, 須田智之(訳), (2024), 手を動かしてわかるクリーンアーキテクチャ ヘキサゴナルアーキテクチャによるクリーンなアプリケーション開発, インプレス Robert C.Martin, 角征典(訳), 高木正弘(訳), (2018), クリーンアーキテクチャ 達人に学ぶソフトウェアの構造と設計, アスキードワンゴ Robert C.Martin, 角征典(訳), (2018), クリーンコーダー プロフェッショナルプログラマへの道, アスキードワンゴ</description></item><item><title>GitHub Actionsでyamlにlintをかける</title><link>https://okuzawats.com/blog/run-yamllint-in-github-actions/</link><pubDate>Tue, 25 Jun 2024 05:07:00 +0900</pubDate><guid>https://okuzawats.com/blog/run-yamllint-in-github-actions/</guid><description>yamlのlinterとしてadrienverge/yamllint（以下、yamllintと呼ぶ）が広く使われています。また、yamllintをGitHub Actions上で実行し、GitHubのPull Requesetに指摘事項をコメントするためのactionとして、reviewdog/action-yamllint（以下、action-yamllintと呼ぶ）が存在します。
話としては「action-yamllintを使いましょう」で終わってしまうんですが、備忘のために使用例を示します。
まずはyamllintの設定用ファイルである、.yamllint を作成し、ルールを記述します。ルールの詳細については、yamllintのドキュメントを参照してください。また、このルールについては、GitHubActionsのCI/CDにyamllintを組み込んで作業の安全性を高めるを参考にして作成しました。
yaml-files: - &amp;#39;*.yaml&amp;#39; - &amp;#39;*.yml&amp;#39; rules: braces: level: warning min-spaces-inside: 1 max-spaces-inside: 1 brackets: level: warning min-spaces-inside: 1 max-spaces-inside: 1 colons: level: warning commas: level: warning comments: level: warning min-spaces-from-content: 1 comments-indentation: disable document-end: disable document-start: disable empty-lines: disable empty-values: disable hyphens: disable indentation: level: warning indent-sequences: consistent key-duplicates: enable key-ordering: disable line-length: disable new-line-at-end-of-file: level: warning new-lines: enable octal-values: disable quoted-strings: quote-type: double trailing-spaces: disable truthy: disable 次に、GitHub Actionsのワークフローを書いていきます。典型的な設定例だと思いますので、説明は割愛します。「TODO」としている箇所に、action-yamllintのステップを追加していきます。</description></item><item><title>「LEADING QUALITY（リーディングクオリティ）」を読みました📚</title><link>https://okuzawats.com/blog/leading-quality/</link><pubDate>Sat, 01 Jun 2024 05:27:00 +0900</pubDate><guid>https://okuzawats.com/blog/leading-quality/</guid><description>LEADING QUALITY（リーディングクオリティ）を読みました。2023年に読んで衝撃を受けた、ソフトウェア開発に関する3冊の本を紹介してみるでも紹介していたんですが、改めて本ブログにも感想を書いてみます。
まず本書がどんな本かというと、組織の品質文化をリードする人のためのガイドブックです。いかにソフトウェアの品質保証を行うか？ということを扱った書籍は多々ありますが、本書はそれらと異なります。高品質なソフトウェアを構築して事業の成長を支えることのできる、組織の品質文化をいかに醸成するか？ということに焦点を当てています。
何故、今「品質」なのか ソフトウェア開発において、品質の重要性が年々高まっています。本書によれば、ソフトウェアが複雑化しているためテストの難易度が上がっている中で、今や品質（テスト）がビジネスの中心になっているとのこと。すなわち、品質が課題となって事業成長を阻害することがあるため、組織の「品質文化」を醸成していく必要があるということです。
この組織の品質文化を醸成していく役割を担うのが、本書で言うところの品質リーダーであり、品質リーダーのためのガイドとなるのが本書です。
品質は何故難しいのか 品質は、時間と共に変化していくため、定義するのが難しいものです。ゴールポストが動き続ける中でシュートを決めなければいけないサッカーのようなものです。本書では、このような動き続ける目標を追い続けることで、高品質なソフトウェアを継続的に提供することが可能となると指摘しています。
品質が相対的なものであるという考え方は、ワインバーグの「品質は誰かにとっての価値である」とも通じるものがありますが、さらに時間軸や事業の成長によっても目指すべき品質が変わっていくということです。
ということは、時間軸や事業の成長に伴って、テスト戦略も成長させていく必要があるということです。本書でも、コンテキストに応じてテスト戦略を構築し、変わり続けるコンテキストにテスト戦略を適応させ続けることの重要性が指摘されています。
自動テストは銀の弾丸か テストをスケールさせるために、自動テストは重要です。すべてを手動でテストしていたらテストがスケールしません。しかし、手動テストのすべてを自動テストに置き換えることはできないと本書は指摘します。
テストには、2つの側面があると言います。
調査 プロダクトに関わる情報を得るため、創造性を発揮して行うテスト。 調査を行うことで、プロダクトに関わる情報が得られ、得られた情報を元に更なる探求が可能となる。 検証 期待通りであることをチェックする。 検証で問題が発見されたら、調査を行う必要がある。 自動化できるテストは後者の検証であり、人間が創造性を発揮して行うテストは無くすことができない、という主張です。これはリグレッションを防ぐためのテストではなく、品質を向上するためのテストは人間がしなければならない、という意味でしょうか。畢竟、自動テストはツールのひとつに過ぎず、コンテキストに応じて適切なテストツールを選ぶということに過ぎないのでしょう。
自動テストは銀の弾丸ではなく、コンテキストに応じてテスト戦略を変えていく中で選択可能な、ひとつの（強力な）ツールに過ぎないと言えます。
まとめ 本書「LEADING QUALITY（リーディングクオリティ）」には他にも「品質ナラティブ」の話や「本番でのテスト」の話など、ソフトウェアの品質を向上していく上でとても興味深いことが書かれています。興味を持たれた方は是非読んでみて、感想を教えてください。待ってます。
Reference Ronald Cummings-John, 河原田政典（訳）, (2023), LEADING QUALITY, KADOKAWA 2023年に読んで衝撃を受けた、ソフトウェア開発に関する3冊の本を紹介してみる（最終アクセス日：2024年6月1日） 「品質は誰かにとっての価値である」（G.M.ワインバーグ）（最終アクセス日：2024年6月1日）</description></item><item><title>定率成長配当割引モデル</title><link>https://okuzawats.com/blog/diviend-growth-model/</link><pubDate>Wed, 29 May 2024 06:13:00 +0900</pubDate><guid>https://okuzawats.com/blog/diviend-growth-model/</guid><description>定率成長配当割引モデルは、将来の配当を元に、企業の現在価値を評価するためのモデルです。ここで、企業は成長し続けるという期待があるため、それに伴い配当も毎年成長率 g で増えていくという前提を置きます。また、1年後の配当を現在価値に割り引くため、割引率を ρ　とします。
この時、1年後の配当の現在価値（Present Value）は以下のように表すことができます。 D は配当（Diviend）です。割引率を用いて配当を現在価値に割り引いています。
$$ \begin{equation} \begin{split} PV_1 = { \frac {D_1} {1 + \rho} } \end{split} \end{equation} $$
2年後の配当の現在価値は以下のように表すことができます。配当は成長率 g で成長します。
$$ \begin{equation} \begin{split} PV_2 = { \frac {{D_1} \cdot {(1 + g)}} {(1 + \rho)^2} } \end{split} \end{equation} $$
(1)式と(2)式から、以下のように書くことができます。
$$ \begin{equation} \begin{split} PV_2 = PV_1 \cdot { \frac {1 + g} {1 + \rho} } \end{split} \end{equation} $$
同様に、3年目の配当の現在価値も以下のように書くことができます。
$$ \begin{equation} \begin{split} PV_3 = PV_2 \cdot { \frac {1 + g} {1 + \rho} } \end{split} \end{equation} $$</description></item><item><title>数列、等比数列、等比級数、無限等比級数</title><link>https://okuzawats.com/blog/geometric-sequence/</link><pubDate>Sun, 26 May 2024 05:45:00 +0900</pubDate><guid>https://okuzawats.com/blog/geometric-sequence/</guid><description>本記事では、数列、等比数列、等比級数、無限等比級数の概要について記述します。
数列 数を列に並べたものを一般に数列と呼びます。例えば、フィボナッチ数として知られる数の数列は以下のようになります。
$$ 0, 1, 1, 2, 3, 5, 8, 13, {\cdots} $$
数列の最初の数を初項と呼びます。上記フィボナッチ数列の例では 0 が初項です。
等比数列 初項を a として、次の項が前の項の定数倍となっている数列、すなわち n 番目の項が n-1 番目の項の r 倍となっている数列を一般に等比数列と呼びます。ここで r を公比と呼びます。 例えば、初項を 1 、公比を 2 とした数列は以下のようになります。
$$ 1, 2, 4, 8, 16, 32, 64, 128, {\cdots} $$
等比数列の一般項、すなわち第 n 番目の項は、以下のように表すことができます。ここで a は初項、 r は公比です。
$$ \begin{equation} \begin{split} a_n = {a}{\cdot}{r^n} \end{split} \end{equation} $$
等比級数 第 n 項までの等比数列の和（等比級数）は以下のように表すことができます。
$$ \begin{equation} \begin{split} S_n &amp;amp;= a_0 + a_1 + {\cdots} + a_n \end{split} \end{equation} $$</description></item><item><title>「品質は誰かにとっての価値である」（G.M.ワインバーグ）</title><link>https://okuzawats.com/blog/what-weinburg-says-about-quality/</link><pubDate>Mon, 20 May 2024 05:09:00 +0900</pubDate><guid>https://okuzawats.com/blog/what-weinburg-says-about-quality/</guid><description>ソフトウェアの品質については、既に多くの定義が試みられています。例えばSQuaREや狩野モデルです。本記事では、その中でGerald M.Weinburgの定義に着目します。Weinburgは、ソフトウェアの品質を以下のように定義します。
品質は誰かにとっての価値である。（Weinburg, (1994)）
この定義を聞いたことがある方は多いかもしれません。わかりやすい定義ではありますが、もう少し詳しく考えてみます。Weinburg (1994)を読むと、Crosby (1980)に対する反論として上記の定義がなされていることがわかります。Crosby (1980)は以下のように品質を定義しています。ただし、ここでの品質は、ソフトウェアの品質よりも広い意味での品質を指しています。
品質は&amp;quot;要求に対する適合&amp;quot;である。（Crosby, (1980)）
Weinburgはここで、要求は誰かから、明示的あるいは暗黙的に示されるものであると指摘します。誰かとは、ユーザーや、開発者や、セールスなど、様々な主体です。
ソフトウェアにバグがないことは、ユーザーにとって価値があり、品質が高いと言えるかもしれません。美しいソースコードは、開発者にとって価値があり、品質が高いと言えるかもしれません。多機能であることは、セールスにとって価値があり、品質が高いと言えるかもしれません。このように、品質は主体によって変わるものです。Weinburgはこれを「品質の相対性」と呼びます。つまり、品質について話す時は、その背後にいる主体が誰なのかを考えなければならないということです。
ここで再びCrosby (1980)を考えます。この定義は、「誰の要求が重要なのか」ということについては何も言っていない、とWeinburgは指摘します。誰の要求が重要なのかがわからない以上、品質の相対性から、ソフトウェアの品質を定義することができないというわけです。そこで、品質を定義する上で要求という概念を考えるのを止め、以下のように定義します。
品質は誰かにとっての価値である。（Weinburg, (1994)）
Weinburgは、品質を定義するためには誰の意見が重要かを決定しなければならず、品質の定義は常に政治的・感情的なものになるとも指摘します。
References Gerald M.Weinburg, (1994), 「ワインバーグのシステム思考法 ソフトウェア文化を創る」, 共立出版 Philip B.Crosby, (1980), 「クオリティ・マネジメント よい品質をタダで手に入れる法」, 日本能率協会</description></item><item><title>「ロジクールERGO K860ワイヤレススプリットキーボード」を買いました⌨️</title><link>https://okuzawats.com/blog/ergo-k860/</link><pubDate>Mon, 15 Apr 2024 05:51:00 +0900</pubDate><guid>https://okuzawats.com/blog/ergo-k860/</guid><description>本ブログでは、Mistel Barocco MD770RGB、Hatsukey70とキーボード遍歴を披露してきたわけですが、先日、ロジクール製のエルゴノミクスキーボード「K860ワイヤレス」を購入しました。ここ一ヶ月ほどはK860ワイヤレスに落ち着いています！
Fig-1 ロジクールERGO K860ワイヤレススプリットキーボード 画像出典：ロジクールERGO K860ワイヤレススプリットキーボード
何が問題だったか これは自分の身体の使い方に起因する問題だと思うのですが、Mistel BaroccoからHatsukey70に変えてしばらく使い込んでいると、手首に疲れが溜まっていることに気が付きました。Mistel Baroccoと比較して薄型で手首への負担が少ない（と思っていた）Hatsukey70を使っているのに手首が疲れる。リストレストを使っても改善しない&amp;hellip;、ということがありました。
ここで改めてキーボードの形状を観察し、そして自分の身体の使い方を観察し、何故手首が疲れるのか？ということを考えていると、ひとつの結論に至りました。キーボードの奥側の高さが上がっていると、手首を反る必要があり、これが手首の疲れの原因になっていた、という仮説です。
この仮説に基づき、次は身体の使い方に合ったキーボードを探しました。これは困難を極めましたが、しばらくの放浪の末、「ロジクールERGO K860ワイヤレススプリットキーボード」に行き着きました（以下、「K860」と呼びます）。
このK860はパームレストがキーボードに付属していて、パームレスト側の高さを上げることができるのです！K860を使って手首の疲れが解消されれば、仮説が正しかったと言えそうです。
Fig-2 パームレストの使用イメージ 画像出典：ロジクールERGO K860ワイヤレススプリットキーボード
K860の使用感 実際に使用してみると、手首の疲れは解消されました！また、エルゴノミクスキーボードに分類されるキーボードだけあって、肩凝りも特に感じません。ここ最近は、肩凝りの予防のため、物理的に左右が分離されるタイプの左右分離型キーボードにこだわり、使用してきました。K860はキーボードこそ一体型ですが、キーボードレイアウトの中央でキーが分離され、かつキーボード全体が立体的な形状を持っていることで、身体への負担をかなり軽減してくれているのだと思います。
また、当方macOSで使用していますが、特にカスタマイズすることなく、違和感なく使い始めることができました。ワイヤレスで接続できることもGoodです。また、使用開始から1ヶ月経ちますが、電池はまだ交換しておらず、頻繁に電池を入れ替える必要がない点も嬉しい点です。仕事用とプライベート用でMac 2台を使い分けているのですが、ボタン一発で接続先を切り替えてくれるのでとても便利です！
使い始めてしばらくはキータッチが重いことが気になりましたが、しばらく使っていると馴染んできたのか気にならなくなりました。残る難点は、テンキーが付いているため、少し筐体が大きいことでしょうか？テンキーレスモデルがあると嬉しかったのですが、なさそうでした。テンキーもあればあったで便利は便利です！</description></item><item><title>薄型の左右分離型キーボード「Hatsukey70」を組み立てました⌨️</title><link>https://okuzawats.com/blog/hatsukey70/</link><pubDate>Wed, 21 Feb 2024 05:33:00 +0900</pubDate><guid>https://okuzawats.com/blog/hatsukey70/</guid><description>半年ほど前にMistel Barocco MD770RGBを購入して以来、左右分離型キーボードを半年ほど使い続けてきましたが、この度は同じく左右分離型キーボードのHatsukey70を購入して組み立ててみました。Mistel Baroccoは比較的厚みがあるキーボードですが、Hatsukey70は薄型のキーボードです。Mistel Baroccoを使用している時はその厚みからリストレストが必要ですが、自分の場合はリストレストを使っても手首にストレスがあったこと、リストレストが卓上で邪魔になることが多々あったことから、薄型の左右分離型キーボードを試してみたい、ついでにキーボードの組み立てにもチャレンジしてみたい、という思いから、Hatsukey70の導入に至りました。
左右分離型・薄型キーボードといえばMistel BaroccoにもMD650Lという製品があります（BAROCCO MD650L）が、こちらは残念ながら販売が終了しております。今回、たまたま自分の手元にMD650Lが存在するのですが、Hatsukey70と比較するとキー配置が使いにくかったり、本体に重量感があったり、USB Mini-Bだったりと全体的な古さは否めません。これから左右分離型・薄型のキーボードを購入する場合は、MD650Lは勧めにくいです（そもそも販売終了しているので）。
Fig-1 Mistel Barocco MD650L Hatsukey70は遊舎工房に委託販売されている組み立て式のキーボードです（Hatsukey70）。部品を半田づけしていく必要があるので誰にでもおすすめできるものではありません。最終的な姿がどうなっているかというと、以下の写真のようになっています（ギャラリーも参照）。キートップについては選択肢があり、自分で選ぶ必要があります。特徴としては、左右の親指の位置に置かれたキーでしょうか。
Fig-2 Hatsukey70 組み立てについては、作者様のサイト（Hatsukey）を見れば、ある程度電子工作的な作業に慣れた人であれば困ることはないと思います。自分が組み立て（というかキーマップの書き込み）をしている途中に一点だけわからないことがあったのですが、問い合わせフォームから問い合わせたらすぐに作者様からご回答をいただき、ドキュメントにも反映されております。
オプションパーツもいくつか用意されており（オプションパーツ）、キーボードの裏側に付けるゴム板や、トッププレートがあります。自分はゴム板をつけてみました。トッププレートも購入しましたが、キースイッチを取らないと装着できないので、未装着です。その他にもパーツはいろいろとカスタマイズできるのですが、自分が試した結果を書くと、
Pro MicroはUSB Micro Bのものを使用しているが、USB Type-C版のものも存在する。自分はType-C版の方が良いので、今から買うならType-C版にする。わざわざやり直すほどではない。 キーキャップはChocFox Legends Keycap Setを購入したが、キーマップと合わないところはKailhロープロ無刻印キーキャップにキートップシールを貼り付けて使っている（遊舎工房で販売されているもの）。Kailhロープロ無刻印キーキャップには1.5Uや2.0Uのキーキャップ（横幅が通常のキーキャップの1.5倍、2.0倍のもの）が存在するので、スペースキーやエンターキーに使用している。 TRRSケーブルは0.8mのメタルケーブルがかっこいいが、長すぎる。0.15mだと短すぎる。0.3mのものに落ち着いた。 というところでしょうか。
作り始めるとこだわりってしまって時間がかかってしまいましたが（何度も遊舎工房でパーツを買い足しました）、満足いく出来になりました。とはいえ、トッププレートやUSB Type-C対応をしたい気持ちがありますので、完成度としては60%ほどでしょうか。まだまだ先はありそうです。
キーボードの使い心地はとても良く、既に実用に移して2週間ほど経ちました。当初の目論見通り、リストレストが不要になり、卓上がスッキリして気持ちいいです。ひさしぶりに半田ごてを握りましたが、なかなか綺麗に半田づけができたと思います。楽しかったです。</description></item><item><title>LuaでAtCoderの過去問精選10問を味わう</title><link>https://okuzawats.com/blog/atcoder-with-lua/</link><pubDate>Sat, 17 Feb 2024 06:20:00 +0900</pubDate><guid>https://okuzawats.com/blog/atcoder-with-lua/</guid><description>プログラミング言語Luaを使って、AtCoderの過去問精選10問を味わってみました。こういった問題を解く時、Luaは美しく書けるな〜という感想です。
AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～ #AtCoder - Qiita
第1問 ABC 086 A - Product 問題の内容は、AtCoderの出題ページ（A - Product）を参照してください。以下9問についても同様に出題ページへのリンクのみ提示します。
ABCのA問題という感じの難易度の問題ですが、Luaの文法を学ぶには丁度良いです。最終的な自分の回答は以下のコードです。
a, b = io.read(&amp;#34;n&amp;#34;, &amp;#34;n&amp;#34;) print(a * b % 2 &amp;lt; 1 and &amp;#34;Even&amp;#34; or &amp;#34;Odd&amp;#34;) まず、1行目のコードでは、標準入力から数値型の値を2個読み取り、変数 a と b に分割代入しています。io.read に文字列 n を渡すわけですが、可変長の引数を取ることが可能で、標準入力から複数の値を読み取る時に重宝します。自分の場合、プロダクト開発では分割代入を使うことはあまりありませんが、こういった問題を解く時は簡潔に記述することができて嬉しいです。
a, b = io.read(&amp;#34;n&amp;#34;, &amp;#34;n&amp;#34;) 2行目のコードでは、and と or を用いた、Luaでの頻出イディオムを使っています。and の左辺値に真偽値を取り、真偽値が真である場合は and の右辺値が評価されます。真偽値が偽である場合は and の右辺値は評価されず、or の右辺値が評価されます。一部の言語における三項演算子のような使い方をするイディオムとなっています。
print(a * b % 2 &amp;lt; 1 and &amp;#34;Even&amp;#34; or &amp;#34;Odd&amp;#34;) 第2問 ABC 081 A - Placing Marbles A - Placing Marbles</description></item><item><title>Luaでエラトステネスの篩を実装してみた</title><link>https://okuzawats.com/blog/sieve-of-eratosthenes/</link><pubDate>Sun, 04 Feb 2024 05:23:00 +0900</pubDate><guid>https://okuzawats.com/blog/sieve-of-eratosthenes/</guid><description>最近興味を持っているプログラミング言語「Lua」1を使って、エラトステネスの篩（ふるい）を実装してみました。「エラトステネス」というのは人の名前で、紀元前に生きていた方です。地球の大きさを始めて測定した人物だそうです。エラトステネスの篩とは、そのエラトステネスさんが考えた、ある整数以下の素数を求めるためのアルゴリズムです。
エラトステネスの篩 (エラトステネスのふるい、英: Sieve of Eratosthenes) は、指定された整数以下の全ての素数を発見するための単純なアルゴリズムである。古代ギリシアの科学者、エラトステネスが考案したとされるため、この名がついている。（エラトステネスの篩 - Wikipediaより引用）
ちなみに、現在では「アトキンの篩」と呼ばれる、より高速なアルゴリズムも考えられているそうです。
実装 Luaははじめて書くので、まずは関数のシグネチャを定義するところから始めます。整数値 n を引数として受け取り、整数値の配列を返します。Luaのコメントの書き方ってこうなんだ〜と思いながら書きました。なお、ローカル変数には local 修飾子を付けないとグローバル変数として扱われてしまいます。
--- n以下の整数のうち、素数のみを格納した配列を返す。 -- @param n 対象となる整数。正の値である必要がある。 -- @return n以下の整数のうち、素数のみを格納した配列。 function sieve(n) local prime = {} -- 素数と判定された整数値を格納する配列 return prime end assert を用いて引数の検証を行います。この関数が意味を持つのは引数が自然数の時のみなので、それを検証します。Luaの assert の文法は簡潔でいいですね。
assert(n &amp;gt; 0, &amp;#34;n must be positive.&amp;#34;) 2以上 n 以下の整数値に対して、それらが自然数か否かを true / false で配列に持ちます。この配列が、篩のメタファーとして働きます。Luaの配列は、テーブルの特殊型です。テーブルのキーを対象となる整数値に、そのバリューを真偽値にしています。配列をいい感じにデフォルト値で初期化する方法があると嬉しかったのですが、自分が調べた限りLuaにはそういった機能はなさそうでした。そのため、ループを回して配列を初期化しています。
local sieve = {} -- 判定対象となる整数値を格納する配列（「篩（ふるい）」と呼ぶ） -- 篩をtrueで初期化する。1はスキップして良い。 for i = 2, n do sieve[i] = true end 2から n の平方根までループを回して、それぞれの整数値が素数か否かに応じて整数値を配列から篩落としていきます。つまり、各整数値の倍数は合成数（素数でない数）であるため、配列に格納されている真偽値を false に設定します。</description></item><item><title>「ソフトウェアアーキテクチャの基礎」をアーキテクトのキャリアガイドとして読む</title><link>https://okuzawats.com/blog/fundamentals-of-software-architecture/</link><pubDate>Mon, 08 Jan 2024 06:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/fundamentals-of-software-architecture/</guid><description>「ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ」 (Mark, Neal (2022)) は、タイトルのとおり、ソフトウェアアーキテクチャの基礎を解説したものです。アーキテクチャは一概に「こうすれば良い」と言えるものではありませんが、どのようにアプローチすれば良いアーキテクチャを導き出せるのか？ということを解説した書籍です。特定のアーキテクチャについて解説するものではありません。
本書では、良いアーキテクチャを導く役割を持つアーキテクトというロールについても解説されています。アーキテクチャについて一般化された定義がないため、アーキテクトについても一般化された定義はありません。その上で、本書では「良いアーキテクトとは何であって何でないのか？」ということが示されています。アーキテクトロールは、最近ではソフトウェアエンジニアのキャリアパスにおける「スタッフエンジニア」のアーキタイプのひとつに数えられることもあります。
アーキテクトは技術の深さよりも、技術の広さが求められる アーキテクトには、技術的な専門性の深さよりも幅が求められます。これは、さまざまなソリューションを理解して、決定を行う必要があるためです。
アーキテクトロールに就いた後は、専門性を犠牲にしても、技術的な幅を広げることに時間を使うべきである、ということが本書では指摘されています。それまで専門性を磨くことに時間を費やしていたエンジニアは、技術的な幅を広げること時間を費やすことに時間を費やすようにマインドを変えていかなければなりません。
一方で、技術的な深さを維持するために、現場でコードを書き続ける必要性も指摘されています。これは簡単なことではありませんが、いくつかのポイントがあると解説されています（本記事では触れませんので、本書を参照してください）。
アーキテクトは技術的な選択をするのではなく、技術的な選択をガイドする アーキテクトは、チームの技術的な選択をガイドする存在でなければいけません。これは、アーキテクトがすべての技術的な選択についての決定を下してはならない、ということも意味します。
例えば、同じ機能を提供するライブラリAとライブラリBが存在し、どちらかを導入する選択をしようとしている状況を考えます。ここでアーキテクトがすべきことは、ライブラリAとライブラリBのどちらかを選定するのではなく、選定にあたっての指針を作成することです。たとえアーキテクト本人はライブラリAが好ましいと思っていても、アーキテクトの作成した指針に従っているのであれば、チームがライブラリBを選定してもそれは歓迎すべきことです。
アーキテクトは政治的な舵取りをする 本書によれば、アーキテクトが下す決定のほとんどについて異議が唱えられます。これは良い悪いの話ではなく、現実がそうなっているということです。
だからこそ、アーキテクトは組織の政治を理解し、ファシリテートと交渉のスキルを発揮し、意見の相違を乗り越えて、すべてのステークホルダーが納得できるソリューションを導き出さなければなりません。優れたアーキテクトの50%はソフトスキルである、と本書では指摘されています。
References Mark Richards, Neal Ford, 島田浩二(訳), (2022), ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ, オライリー・ジャパン</description></item><item><title>2023年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2023/</link><pubDate>Mon, 25 Dec 2023 22:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2023/</guid><description>今年も残すところ数日となりました。恒例となりつつある、毎年のふりかえりの記事です。今年はダイジェストでお送りいたします。
2022年のふりかえり 2021年のふりかえり 2020年のふりかえり 仕事 モバイルアプリケーションアーキテクトとして楽しくモバイルアプリのアーキテクチャ改善と技術負債解消を推進していたのですが、途中からはどちらかというと開発生産性に関する課題について考えることが増えてきました。これはこれで楽しいです。
お仕事の話なのでここでは多くは語りませんが、後述する登壇の内容や今後の登壇をチェックしていただければと思います。
Software Design誌での執筆 Software Design 2023年6月号にAndroidアプリにおけるクリーンアーキテクチャの記事を執筆させていただきました。実はSoftware Design誌にはいつか記事を書いてみたいという夢を持っていたのですが、シレッと叶ってしまいました。執筆の依頼がある半年ほど前からAndroidアプリにおけるクリーンアーキテクチャについて考え続けていたので、集大成となる記事となりました。
Software Design 2023年6月号｜技術評論社 登壇 今年はオンラインとオフラインをあわせて5回の登壇をしました。過去の登壇の内容を見て登壇のご依頼をいただくことがあったり、地道に活動してきた甲斐があったなあと思いました。発表スライドのうち1つは何故かホッテントリ（今もホッテントリって言うのか&amp;hellip;？）に入ったりもしました。あまりマサカリは投げないでください。
例外を投げるな、値を返せ 何故、UseCaseは1メソッドなのか Androidアプリ開発におけるSonarCloudの活用 10年モノのAndroidアプリのコード品質を改善していく、3つの取り組み 「勉強になった」で終わらせない、ストロングスタイルの勉強会 同人誌の執筆 前述したSoftware Design誌に執筆した記事の元となった同人誌を含めて、2冊の技術同人誌を執筆しました。去年から書いていたヒッチハイク・ガイドシリーズは全3巻すべて執筆完了したので、無事に完結しました。さほど売れているわけではないですが、書ききれてよかったです。
Android クリーンアーキテクチャ ヒッチハイク・ガイド Android 依存性注入 ヒッチハイク・ガイド 課題図書 「仕事」のところで書いたように、考える領域が広がってきたので、いろいろなことを学び直していました。画像1は2023年9月ごろ、主に品質保証やソフトウェアのメトリクスについて学んでいた頃の課題図書（自分で自分に課したもの）です。画像2は2023年12月（つまり今現在）、アジャイル開発などについて学ぶための課題図書です。
画像1 画像2 画像を拡大したい方がいましたら、画像を別タブで開いてみてください。
クラウド さくらのクラウドのウェブアクセラレータとオブジェクトストレージで静的サイトを配信する（HugoとGitHub Actionsを添えて）で書いたように、本ブログをさくらのクラウドを活用してホスティングするために、さくらのクラウドについて学習していました。AWSを使おうかとも考えていましたが、使いやすさ・とっつきやすさから、さくらのクラウドを選びました。この時にAWSについても学習することができました。
終わりに 良いお年を！</description></item><item><title>[Android] SQLiteのインメモリデータベースで単体テストを書く</title><link>https://okuzawats.com/blog/testing-sqlite/</link><pubDate>Fri, 22 Dec 2023 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/testing-sqlite/</guid><description>この記事はAndroid Advent Calendar 2023の22日目の記事です。21日目は @usuiat による「意外と知らないModifier.clickable #Android」でした。
Androidアプリ開発におけるローカルデータベースは、Android JetpackのRoomを使うケースが一般的になってきたかと思います。Roomを用いる場合は、inMemoryDatabaseBuilder を呼び出してインメモリデータベースを作り、単体テストを書くことができました。詳細は、GitHub ActionsでRoom / Realmの自動テストに書いています。
Roomが一般的になってきたとはいえ、まだまだRoomを使わずにSQLiteを使ってローカルデータベースの処理を書く機会はあるかと思います。自分はありました。本記事では、SQLiteを使っている場合の単体テストについて書きます。　インメモリデータベースの生成 結論から言うと、SupportSQLiteOpenHelper.Configuration の name に null を渡すとインメモリデータベースになります。こうして作ったインメモリデータベースを用いて、Robolectric環境下で単体テストを書くことができます。
「name に null を渡すとインメモリデータベースになる」ということを調べて知った時は衝撃を受けましたが、事実です。例えば以下のドキュメントにも記載があります。
name	String: of the database file, or null for an in-memory database SQLiteOpenHelper | Android Developers
具体的なコードを以下に示します。android.content.Context が必要なので、引数で受け取ります。このContextについては後述します。
import android.content.Context import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory fun inMemoryDb(context: Context): SupportSQLiteDatabase { val configuration: SupportSQLiteOpenHelper.Configuration = SupportSQLiteOpenHelper.Configuration .builder(context) .name(null) // nameにnullを指定するとインメモリデータベースになる .callback(callback) .build() val inMemoryDb: SupportSQLiteDatabase = FrameworkSQLiteOpenHelperFactory() .</description></item><item><title>[Android] 単体テスト用の依存関係をHiltで解決し、かつ例外のテストを行いたい場合のパターン🗡️</title><link>https://okuzawats.com/blog/test-dependency-by-hilt-and-testing-exception/</link><pubDate>Tue, 21 Nov 2023 05:48:00 +0900</pubDate><guid>https://okuzawats.com/blog/test-dependency-by-hilt-and-testing-exception/</guid><description>単体テスト用の依存関係をHiltで解決するの続きです。Hiltで注入した依存オブジェクトが特定の状況でthrowする例外をcatchするケースのテストを書きたいので、MockKを使う方法を考えました。
MockKの使い方については、以下の記事もあわせて参照ください。
Mockk によるモック入門 はじめに はじめに注意事項ですが、単体テスト用の依存関係をHiltで解決する理由は、単体テストにテストダブルを多用したくないためでした。本記事ではMockKを用いたテストダブルを活用しますが、例外のテストに用途を限定します。
また、テストダブルの中でもスパイを用いて、極力、依存オブジェクトを実オブジェクトに近いものにします。
依存性注入 まずは単体テスト用の依存関係をHiltで解決するでも書いたように、テスト用の依存関係を記述するHiltのモジュールを作成します。この辺りの説明については、上記の記事を参照してください。
@Module @TestInstallIn( components = [SingletonComponent::class], replaces = [AwesomeDaoModule::class], ) class SpyAwesomeDaoModule { // TODO } 次に @Provides の付いたprovide〜関数を作成します。ここではMockKの spyk を利用して、実オブジェクトのスパイに置き換えます。スパイなので、テストで注入されるオブジェクトは実オブジェクトと同様に振る舞い、またMockKの機能を用いた検証を行うことができるようになります。
@Module @TestInstallIn( components = [SingletonComponent::class], replaces = [AwesomeDaoModule::class], ) class SpyAwesomeDaoModule { @Provides @Singleton fun provideAwesomeDao(database: AwesomeDatabase): AwesomeDao { return spyk(database.awesomeDao()) // スパイに置き換える。 } } テスト対象オブジェクトのセットアップ テストで必要となる依存関係をHiltで解決します。以下の例では、テストで必要となる依存関係としてAwesomeDaoのオブジェクトを注入しています。このオブジェクトは、上述のモジュールで作成したスパイになります。
@HiltAndroidTest @Config( application = HiltTestApplication::class, manifest = Config.NONE, ) @RunWith(AndroidJUnit4::class) class DefaultAwesomeRepositoryTest { @get:Rule var hiltRule = HiltAndroidRule(this) private lateinit var sut: AwesomeRepository @Inject lateinit var dao: AwesomeDao @Before fun setUp() { hiltRule.</description></item><item><title>さくらのクラウドのウェブアクセラレータとオブジェクトストレージで静的サイトを配信する（HugoとGitHub Actionsを添えて）</title><link>https://okuzawats.com/blog/hosting-blog-on-sakura-cloud/</link><pubDate>Wed, 15 Nov 2023 05:35:00 +0900</pubDate><guid>https://okuzawats.com/blog/hosting-blog-on-sakura-cloud/</guid><description>本ブログを「さくらのクラウド」のCDN、ウェブアクセラレータとストレージサービスのオブジェクトストレージを使って配信するようにしました。
元々はNetlifyを使っていて機能的には何の不満もなかったんですが、Netlifyが簡単すぎて物足りなくなってきたので、新たな環境にお引越ししました。お金はかかりますが。ついでにブログ（Hugo）の多言語化も対応しました（英語のみ。英語の記事はこれから頑張って書きます！）。また、オブジェクトストレージにファイルをアップロードするためにGitHub Actionsを使っています。
備忘を兼ねて、設定手順をメモしておきます。
オブジェクトストレージ まずは元気にオブジェクトストレージのバケットを作成します。そんなに難しいことはないと思います。作成したら、GitHub Actionsを使ってファイルをアップロードするためのシークレットと、後述するウェブアクセラレータからオブジェクトストレージに繋ぐためのシークレットを追加しておきます。
GitHub Actionsで使う方のシークレットは、GitHubのリポジトリシークレットに入れておきます。GitHub Actionsのワークフローは、以下の記事を参考に書きました。
GitHub Actionsからさくらのクラウド オブジェクトストレージへアクセスする - Hateburo: kazeburo hatenablog 実際に使っているymlを一部記載するとこんな感じです。./path/to/hugo/public/ と //your-bucket-here/ 、およびS3エンドポイントは各自の環境にあわせて修正してください。また、Hugoのセットアップには、peaceiris/actions-hugoを使用しています（いつもありがとうございます）。
jobs: upload: runs-on: ubuntu-latest steps: # 省略 - name: setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: &amp;#39;0.119.0&amp;#39; - name: build Hugo run: | cd ./path/to/hugo hugo --minify - name: sync to object storage env: AWS_ACCESS_KEY_ID: ${{ secrets.SAKURA_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.SAKURA_SECRET_ACCESS_KEY }} AWS_REGION: eu-west-1 run: | aws --endpoint-url=https://s3.isk01.sakurastorage.jp s3 --only-show-errors --delete sync .</description></item><item><title>[Kotlin] 関数定義が1つだけのinterfaceは `fun interface` で定義できる</title><link>https://okuzawats.com/blog/functional-interface/</link><pubDate>Sun, 24 Sep 2023 05:42:05 +0900</pubDate><guid>https://okuzawats.com/blog/functional-interface/</guid><description>表題のとおりですが、Kotlinで関数定義が1つだけのinterfaceを定義する場合は、fun interface として定義すると関数型のインターフェースとして宣言できます。
Functional (SAM) interfaces | Kotlin Documentation
どういうことでしょうか。まずは以下のようなinterfaceについて考えます。関数定義が1つだけのinterfaceです。
interface Logger { fun log(s: String) } この場合は、interfaceの宣言を fun interface にすることができます。
fun interface Logger { fun log(s: String) } fun interface にすることができるのは、関数定義が1つだけの時に限られます。つまり、以下のようなinterfaceの定義をすることはできません。
// コンパイルエラー fun interface Logger { fun log(s: String) fun errorLog(e: Throwable) } さて、fun interface で定義したLoggerを実装してみます。オブジェクト式を用いた無名クラスを以下のように実装することができます。
val logger: Logger = object : Logger { override fun log(s: String) { println(s) } } fun interface の場合は以下のように書き直すことができます。オブジェクト式を用いる必要がなくなり、かなりスッキリと書くことができるようになります。
val logger: Logger = Logger { s -&amp;gt; println(s) } ここでは型推論が効きますし、ラムダ式の引数名も省略できますので、上記のコードはさらに短く書くことができます。また、この場合は関数参照も適用できます。</description></item><item><title>GitHub ActionsでSonarCloudにカバレッジをアップロードする😺</title><link>https://okuzawats.com/blog/upload-coverage-report-to-sonarcloud/</link><pubDate>Mon, 18 Sep 2023 22:48:21 +0900</pubDate><guid>https://okuzawats.com/blog/upload-coverage-report-to-sonarcloud/</guid><description>表記のことを行う方法をメモしておきます。
サンプルとしてAndroidアプリのカバレッジレポートをJaCoCoで出力する場合を取り上げています。JaCoCoについてはbuild.gradle.ktsでJaCoCoを動かすなどを参考にして設定済みであることを前提とします。
GitHub Actionsのワークフロー 結論から先に書くと、こんな感じのステップを作ります。このステップを動かすために、いろいろな準備が必要です。
jobs: test: # 省略 steps: # 省略 - name: sonarcloud uses: SonarSource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: &amp;gt; -Dsonar.organization=your-organization-here -Dsonar.projectKey=your-project-key-here -Dsonar.coverage.jacoco.xmlReportPaths=./app/build/reports/jacoco/debugCoverage/debugCoverage.xml 準備 CI baseの解析を有効にする SonarCloudは、GitHubのリポジトリと連携した後、デフォルトブランチとPull Requestを自動で解析する設定になっています。SonarCloudのカバレッジ機能を有効にするためには、この設定を無効化して、Pull Requestベースでの解析を行うように変更する必要があります。
SonarCloudのプロジェクトのダッシュボードから、Administration &amp;gt; Analysis Methodを開き、Automatic Analysisを無効化します。もし&amp;quot;Administration&amp;quot;が表示されない場合は権限的な問題かもしれません。
SONAR_TOKEN GitHubのリポジトリシークレットに保存する、SonarCloudのトークンです。
このトークンは、SonarCloudのダッシュボードから、My Account &amp;gt; Securityを開き、&amp;ldquo;Generate Tokens&amp;quot;で作成できます。この辺りは、組織のポリシーがあればそれに従います。今回は自分個人のアカウントで試しているので、自分のアカウントでトークンを作成しました。
オーガニゼーションとプロジェクトキー yamlの以下の部分です。これら2つは、SonarSource/sonarcloud-github-actionで with を用いた構文を使う場合は必須のパラメータです。
-Dsonar.organization=your-organization-here -Dsonar.projectKey=your-project-key-here SonarCloudのプロジェクトのダッシュボードから、Informationを開き、&amp;ldquo;About This Project&amp;quot;の下に表示されている&amp;quot;Project Key&amp;quot;と&amp;quot;Organization Key&amp;quot;をそれぞれ入力します。
カバレッジレポートのパス yamlの以下の部分です。カバレッジレポートのパスを設定します。言語によってパラメータが異なるので、Test Coverage Parametersを参考に設定します。
-Dsonar.coverage.jacoco.xmlReportPaths=./app/build/reports/jacoco/debugCoverage/debugCoverage.xml</description></item><item><title>DroidKaigi 2023に行ってきた🤖</title><link>https://okuzawats.com/blog/droidkaigi-2023/</link><pubDate>Fri, 15 Sep 2023 22:20:25 +0900</pubDate><guid>https://okuzawats.com/blog/droidkaigi-2023/</guid><description>昨日と今日の2日間、DroidKaigi 2023に行ってきました（明日の3日目も開催されますが、自分は不参加です）。数年振りのオフライン参加で、いろいろな人と会って話せたので楽しかったです。忘れないうちにセッションの感想を残しておきます。
Android Open-source repositories 101: Everything you always wanted to know OSSの管理方法について扱ったセッションでした。自動化が大事だという話をされてましたが、自動化のスキルは実務に役立つことも多そうです。OSS活動、なかなかできてないですが、やりたい気持ちだけはもう何年もあります。
Android Open-source repositories 101: Everything you always wanted to know | DroidKaigi 2023
Supercharging Android Testing: Scalable Environments for Large Teams on Diverse Devices &amp;amp; Features AndroidはOSバージョン、スクリーンサイズ、メーカーをたくさんサポートしなくてはならない、というようなことを言っていた記憶があります。事業成長のためにはテストがスケールしないといけないと言っていた点については耳が痛いのと同時に頑張っていこうと思えました。長期のコミットメントとイテレーティブなマインドセットが必要である、とも言っていたので心の支えにします。
あとはテスト結果のトレンドをモニタリングできるダッシュボードを整備して、アラートを出すようにすると良い、とのこと。確かにダッシュボードがあれば良さそうですが、準備が大変そうだとも思いました。
Supercharging Android Testing: Scalable Environments for Large Teams on Diverse Devices &amp;amp; Features | DroidKaigi 2023
(Unofficial) Guide to App Architecture Guide Vol. 2 Hiltについての話が多かったです。HiltはComponent Treeから外れたことをしようとすると難しいという話をしていて、例えば @AccountScope みたいなやつを定義できればマルチアカウントが楽になるけどできないという話をしていました。Daggerの拡張であるsquare/anvilや、さらにその拡張であるdeliveryhero/whetstoneの話もありました。
マルチモジュールまわりの話は耳が痛かったです（すみません）。</description></item><item><title>ADR-Toolsを使ってADR（Architecture Decision Record）を作る</title><link>https://okuzawats.com/blog/adr/</link><pubDate>Fri, 11 Aug 2023 15:53:06 +0900</pubDate><guid>https://okuzawats.com/blog/adr/</guid><description>npryce/adr-toolsは、ADR（Architecture Decision Record）を管理するためのCLIです。ADRの作成や置き換えなど、いくつかの機能を提供しています。
macOSであればHomebrewでインストールできます。
% brew install adr-tools 以下のコマンドでADRのディレクトリが作成されます。デフォルトでは、/doc/adr/ となります。
% adr init ADRとADR-Tools ADRは、Documenting Architecture Decisionsが初出であるとのこと (Mark, Meal (2022), p.289)。
ADR-Toolsの使い方については、hasCode.com » Blog Archive » Managing Architecture Decision Records with ADR-Toolsが詳しいです。
日本語で読める書籍では、「ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ」 (Mark Richards, Neal Ford (2022))、「エンジニアリングマネージャーのしごと チームが必要とするマネージャーになる方法」 (James Stanier (2022)) に記述が見られます。
ADR-Tools 以下のようなコマンドで、ADRの雛形を生成します。&amp;ldquo;absolutely important architecture decision&amp;rdquo; の部分は自由に入力します。
% adr new absolutely important architecture decision 0003-absolutely-important-architecture-decision.md というような名前でMarkdownファイルが作成されます。このファイル名の 0003 の部分は連番で作成されます。ファイルの中身は以下のようなものになります。「ADRの基本構造は、タイトル、ステータス、コンテキスト、決定、影響という5つの主要セクションから構成される (Mark, Meal (2022), p.289)」 という説明のとおりです。
# 3. absolutely important architecture decision Date: 2023-08-11 ## Status Accepted ## Context The issue motivating this decision, and any context that influences or constrains the decision.</description></item><item><title>[Android] Uniflowを用いたMVI的なアーキテクチャを試してみる🦄</title><link>https://okuzawats.com/blog/uniflow/</link><pubDate>Sat, 05 Aug 2023 22:54:20 +0900</pubDate><guid>https://okuzawats.com/blog/uniflow/</guid><description>MVI的な単一方向のデータフローをサポートするライブラリUniflowを（しばらく前に）試してみました。その概要はWhat is Uniflow?に詳しいです。
Uniflow 🦄 - Simple Unidirectional Data Flow for Android &amp;amp; Kotlin, using Kotlin coroutines and open to functional programming https://github.com/uniflow-kt/uniflow-kt
ここ1年ほどはコミットが進んでないようです。最新バージョンは1.1.2で、1.1.1とかなり違うような&amp;hellip;。
dependencies { implementation &amp;#39;org.uniflow-kt:uniflow-android:1.1.2&amp;#39; } Uniflowを味見してみる io.uniflow.android.AndroidDataFlow を継承したクラスを作ります。便宜上ViewModelという名前を付けていましたが、公式のサンプルでは「〜DataFlow」という命名をしているようです。なお、AndroidDataFlowはAACの androidx.lifecycle.ViewModel を継承しているので、実装上は同じように扱うことができます。例えば、Hiltを用いたDIには @HiltViewModel を用いることができるということです。
import io.uniflow.android.AndroidDataFlow import io.uniflow.core.flow.data.UIEvent // 省略 class MainViewModel : AndroidDataFlow( defaultState = MainViewModelState.Initial, ) { // TODO } AndroidDataFlowを継承したクラス内では、action 内で setState を用いた状態の更新を、sendEvent を用いたOne Shot Eventの発火を行うことができます。Viewからアクションがトリガーされ、Stateの更新・Eventの発火処理が行われます。
fun onSomeAction() { action { setState(MainViewModelState.Loading) getSomeFlowUseCase() .map(/* map it here */) .</description></item><item><title>Mistel Barocco MD770RGBを買いました⌨️</title><link>https://okuzawats.com/blog/barocco/</link><pubDate>Thu, 27 Jul 2023 05:24:34 +0900</pubDate><guid>https://okuzawats.com/blog/barocco/</guid><description>長年、MacBook Pro本体のキーボードで仕事をしてきましたが、左手にダメージがあったり、肩がこりがひどくなってきたり、といった健康上の課題がありました。こういった課題に左右分離型のキーボードがいいぞという話があり、また懲りずにチャレンジするかという気になってきました。外付けキーボードはHHKBや左右分離型のキーボードなど覚えているだけで5回ほどのチャレンジを重ね、その度に結局は煩わしくなりMacBook Pro本体の戻るということを繰り返してきました。今回はいよいよ健康上の課題が限界に近づいてきたので、本気を出して左右分離型のキーボードにチャレンジしてみたいと思います。
購入したのは、「Mistel BAROCCO MD770RGB JP（日本語配列）」です。キーボードが光ってかっこいいです。
Fig-1 Mistel Barocco MD770RGB 画像出典：Mistel BAROCCO MD770RGB JP（日本語配列） キーボード - 株式会社アーキサイト
セットアップ MacBook Pro (M2, 2022)を使用しています。使い始めるには難しい設定は不要ですが、いくつか問題点がありました。
JISキーボードと認識されない問題 キーボードがJISキーボードと認識されず、US配列と認識されてしまいました。キーボードの刻印と実際に打たれる文字に差異があり、実用が難しい状態でした。
MacでJISキーボードがUS配列と認識されてしまう問題。＠キーが打てない。 - はる速報 多くの記事でKarabiner-Elementsを導入していたために同事象が発生しているということが報告されていたのですが、自分の場合は特にKarabiner-Elementsは使用していない状況でも発生していました。とはいえ、キーボードをセットアップしていく上でKarabiner-Elementsを使いたかったので、Karabiner-Elementsをインストールした上、多くの記事で同事象の解決方法として示されていた「Virtual KeyboardにJIS (Japanese)を設定する」を行ったところ、解決しました。
Fig-2 Karabiner-ElementsによるVirtual Keybordの設定 キーボードの配置問題（物理） MacBook Proを開いた状態で左右分離型キーボードを配置すると、理想的な位置にキーボードを配置できないという問題があります。筆者はMacBook Proをクラムシェルモードでは使いたくないと考えており1、外付けのキーボードをどう配置するか？という問題は、左右分離型のキーボードを活用する上で死活を分ける課題でした。
三昼夜ほどこの問題に悩んだ末、左右分離型キーボードの左側だけを使用するという解決策に至りました。
Mistel Barocco MD770RGBは、分離された左側のキーボード（左ユニット）だけでも動作します（「左ユニット単独接続」と呼ばれる）。ただし、Mistel Barocco MD770RGBは右側のキーボード（右ユニット）が親機（マスター）となっているため、左ユニット単独接続した場合は、マクロプログラミングやmacOS風最適化モードなどの便利な機能が使用できません。
それならば、左ユニットではなく右ユニットを単独接続して左手でMacBook Proのトラックパッドとキーボードを操作すれば良いのでは？と思いますが、筆者は右利きのため、左手ではトラックパッドの操作がストレスなくできず、断念しました。
キーマップの変更 上述のようにキーボードを配置したことで、新たな問題が生じました。MacのJIS配列キーボードではスペースキーの左に「英数」キーが配置されています。Baroccoの左ユニット単独接続では、左ユニットのスペースキーの左にあるべき「英数」が存在しません（多分）。そうなると、MacBook Pro本体のキーボードに付属している「英数」を押さないといけませんが、右手のホームポジションから「英数」までは距離が遠く、押すのに一手間かかってしまいます。
自分はMacのcommand（⌘）は左手で押すので、右側のcommand（⌘）はあまり必要としません。このボタンに英数・かなの切り替えを割り当てれば、とりあえずの問題は解決しそうです。
また、あわせて左ユニットのcommand（⌘）、option（⌥）、control（^）あたりのキーマップも変更しておきます。
これらのキーマップの変更は、前述のKarabiner-Elementsで行いました。この変更によって、JIS配列のMacのキーボードに近い感覚で操作を行えるようになりました。
パームレスト Baroccoはキーの高さがあるので、手首のストレスを緩和するために、パームレストが欲しくなると思います。2023年現在、左右分離型キーボードで使えるようなタイプのパームレストがたくさん売っています。
自分が最初に左右分離型キーボードに手を出した頃はあまりそういったものは見当たらなかったので（たしか）、FILCOの普通のパームレストをノコギリで2つに切り分けたものをパームレストとして使っています（ヤスリがけもしてあります）。パームレスト1枚では厚みが足らない気もするので2枚重ねにしたり、試行錯誤してます。
まとめ ちょっと手間がかかりましたが、なんとか自分好みの環境を作ることができました。肩こりが解消すると嬉しいです。
MacBook Pro本体のWebカメラを使いたい、MacBook Pro本体のトラックパッドを使いたい、等の理由による。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>[Android] 単体テスト用の依存関係をHiltで解決する🗡️</title><link>https://okuzawats.com/blog/test-dependency-by-hilt/</link><pubDate>Thu, 29 Jun 2023 17:52:00 +0900</pubDate><guid>https://okuzawats.com/blog/test-dependency-by-hilt/</guid><description>プロダクションとは異なる単体テストの依存関係をHiltで解決したい、ということってありますよね。僕はありました。
本記事では、単体テスト用の依存関係をHiltで解決する方法を示していきます。
単体テスト用の依存関係のセットアップ Hiltのセットアップはできているものとして、さらに単体テスト用の依存関係を追加します。テスト用のHiltの依存関係の他、JUnit 4で使用するテストランナーとRobolectricを使います。
// use Hilt in tests testImplementation &amp;#34;com.google.dagger:hilt-android-testing:2.46.1&amp;#34; kaptTest &amp;#34;com.google.dagger:hilt-android-compiler:2.46.1&amp;#34; // TestRunner testImplementation &amp;#34;androidx.test.ext:junit-ktx:1.1.5&amp;#34; // Robolectric testImplementation &amp;#34;org.robolectric:robolectric:4.10.3&amp;#34; テストクラスのセットアップ テストクラスのセットアップにいくつかポイントがありますが、結論としては以下のように行いました。
import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication import org.junit.Test import org.robolectric.annotation.Config import javax.inject.Inject @HiltAndroidTest @Config(application = HiltTestApplication::class) @RunWith(AndroidJUnit4::class) class ExampleUnitTest { // 後述 } ポイントは、以下です。
@HiltAndroidTest を付与すること プロダクションで使う @AndroidEntryPoint のようなアノテーションと同様に、Hiltが依存関係を解決するために必要です。 @Config にHiltTestApplicationを指定すること @Config 自体はRobolectricの仕組みです。 @Config にHiltが定義しているテスト用のApplicationクラスを指定しています。 @RunWith にAndroidJUnit4を指定すること @RunWith でテストランナーを指定します。Robolectricとandroidx.testで書いたように、ここで指定するのはRobolectricTestRunnerでも問題ありません。 テストルールの設定 テストルールとしてHiltAndroidRuleを指定します。setupでHiltAndroidRule#injectを呼び出すことでInjectされます。
import dagger.hilt.android.testing.HiltAndroidRule import org.junit.Before import org.</description></item><item><title>GitHub ActionsでktlintとAndroid Lintを並列実行して、DangerでPRにまとめてコメントする🐝</title><link>https://okuzawats.com/blog/lint-android-with-github-actions/</link><pubDate>Sat, 17 Jun 2023 23:13:00 +0900</pubDate><guid>https://okuzawats.com/blog/lint-android-with-github-actions/</guid><description>Androidアプリ開発での静的解析として広く使われているktlintとAndroid LintをGitHub Actions上で実行して、Dangerを使ってPRにコメントして欲しい、ということは良くあると思います。ktlintとAndroid Lintを直列に実行するのは簡単ですが、並列に実行できた方がCI待ちの時間が減って嬉しいですよね。そこまで難しくないのでやっていきます。
pinterest/ktlint: An anti-bikeshedding Kotlin linter with built-in formatter Improve your code with lint checks | Android Studio | Android Developers Danger - Stop Saying &amp;ldquo;You Forgot To…&amp;rdquo; in Code Review jobs.&amp;lt;job_id&amp;gt;.needs 構文 GitHub Actionsでは、ひとつのワークフロー（YAMLファイル単位で作成される）に複数のジョブを定義できます。ひとつのワークフローにktlint、Android Lint、Dangerのジョブをそれぞれ定義すれば良さそうですが、Dangerの実行はktlintとAndroid Lintの両方の実行完了を待たないといけません。
ここで使えるのが、 jobs.&amp;lt;job_id&amp;gt;.needs 構文です。
GitHub Actions のワークフロー構文 - GitHub Docs この構文を使って、
jobs: ktlint: # do ktlint androidLint: # do android lint danger: needs: - ktlint - androidLint # do danger というように、ktlintのジョブ、Android Lintのジョブ、Dangerのジョブをそれぞれ定義しておき、Dangerのジョブの依存ジョブとしてktlintおよびAndroid Lintのジョブを指定すれば良いです。</description></item><item><title>何故、Squareクラスはリスコフの置換原則（LSP）に違反するのか</title><link>https://okuzawats.com/blog/square-violate-lsp/</link><pubDate>Sun, 30 Apr 2023 15:25:53 +0900</pubDate><guid>https://okuzawats.com/blog/square-violate-lsp/</guid><description>リスコフの置換原則（The Liskov Substitution Principle: LSP） に違反する例として、Rectangleクラスを継承したSquareクラスの例を複数の書籍で目にしました（Robert (2004)、Michael (2009)、Robert (2018)）。何故、Squareクラスはリスコフの置換原則に違反するのでしょうか。
リスコフの置換原則とは、以下のように要約されます。
派生型はその基本型と置換可能でなければならない。（Robert, (2004), p.144）
Rectangleクラスは長方形を表すクラスで、幅（width）と高さ（height）を持ち、幅と高さから面積（area）を計算することができます。
public class Rectangle { public Rectangle(int width, int height) { /* 略 */ } private int width; private int height; public void setWidth(int width) { /* 略 */ } public void setHeight(int height) { /* 略 */ } public int getArea() { /* 略 */ } } Squareクラスは正方形を表すクラスで、リスコフの置換原則に違反する例では、Rectangleを継承します。正方形は長方形の一種、というわけです。正方形の幅と高さは定義により常に等しいです。
public Square(int size) { /* 略 */ } Squareを親クラスのRectangle型としてインスタンス化してみます。</description></item><item><title>Androidアプリ開発におけるセマンティック・バージョニング</title><link>https://okuzawats.com/blog/semantic-versioning-in-android/</link><pubDate>Sat, 22 Apr 2023 22:25:47 +0900</pubDate><guid>https://okuzawats.com/blog/semantic-versioning-in-android/</guid><description>Androidアプリのバージョン番号を X.Y.Z 形式、いわゆるセマンティック・バージョニングにすることは必須ではありません。Androidではバージョン番号の指定を versionName で行いますが、 versionName は文字列でありさえすれば問題ありません。なのでバージョン番号の命名は好きにしたらいいんですが、セマンティック・バージョニングを採用するメリットも確かにあります。
そもそもセマンティック・バージョニングとは バージョン番号を メジャー.マイナー.パッチ とするバージョニングのルールです。互換性のないアップデートでメジャーを、互換性があり機能が追加されるアップデートでマイナーを、後方互換性を伴うバグ修正でパッチを、それぞれインクリメントしていきます（セマンティック バージョニング 2.0.0 | Semantic Versioning）。
Androidアプリのユーザーが上記リンクに示されるようなモチベーションを感じることは稀だと思いますので、Androidアプリ開発においてセマンティック・バージョニングを導入する必然性は薄いと思われます。メリットがあるとすれば、ユーザーではなく開発者の側でしょう。
すなわち、「次のアップデートはメジャーアップデートだから、メジャー番号を上げたバージョンをリリースしよう」とか、「プロダクションにバグがあるからhotfixを出そう、パッチ番号を上げたバージョンをリリースしよう」というような場面では、セマンティック・バージョニングを用いることで開発者内のコミュニケーションを円滑にできる効果があると思います。
versionName と versionCode Androidアプリには、ふたつのバージョンが存在します。前述の versionName と、 versionCode です。
versionName が文字列であったのに対し、versionCode は正の整数で、内部的なバージョン番号として使用されます。Google Playでは versionCode を用いてアプリのバージョン管理を行なっており、端末にインストールされているアプリの versionCode よりも小さな versionCode を持つアプリを端末にアップデート・インストールすることはできません。
versionCode については、最初のリリースで 1 を設定し、リリースごとに単純に値を増やしていくというのが最もあり得る運用であると思います。 versionCode まで頑張ってセマンティックにはしないということですね。
一般的に、アプリの最初のバージョンをリリースするときは versionCode を 1 に設定し、リリースを重ねるたびに、メジャー リリースかマイナー リリースかにかかわらず、単純に値を増やします。つまり、versionCode 値は、ユーザーに表示されるアプリのリリース バージョンを必ずしもなぞっているわけではありません。アプリと公開サービスでは、このバージョン値をユーザーに表示するべきではありません。（アプリのバージョニング | Android Studio | Android Developers）
その他、バージョン番号 X.Y.Z に対して versionCode を 10000 * X + 100 * Y + Z というように決め、 versionName と versionCode を連動させるように決めているプロジェクトもあるかと思います。 versionCode まで頑張ってセマンティックにするパターンです。</description></item><item><title>Truthのカスタムサブジェクトを定義する</title><link>https://okuzawats.com/blog/truth-custom-subject/</link><pubDate>Sat, 25 Mar 2023 23:24:08 +0900</pubDate><guid>https://okuzawats.com/blog/truth-custom-subject/</guid><description>Truthのカスタムサブジェクトを新たに定義して、独自のアサーションを追加してみます。公式の解説を参考に進めました。Javaで書かれたサンプルコードをKotlinに読み替えるのに若干の苦労をしましたが、なんとかなりました。
今回は、サンプルとしてKotlinのUnit型に対するアサーションを追加します。つまり、以下のようなアサーションができるようにします。
@Test fun test_isNotUnit() { val actual: Unit? = null assertThat(actual).isNotUnit() } @Test fun test_isUnit() { val actual: Unit? = Unit assertThat(actual).isUnit() } 余談ですが、KotlinのUnitのインスタンスをJavaで使うには、 Unit.INSTANCE と書くことを知りました。またひとつ賢くなりました。
カスタムサブジェクトの定義 com.google.common.truth.Subject （以下Subjectと呼ぶ）を継承して、カスタムサブジェクトを作ります。Subjectのコンストラクタは、引数としてFailureMetadataと検査対象となるObjectをとります。カスタムサブジェクトのコンストラクタ引数もこれに準じます。コンストラクタはprivateにしておきます（理由は後述します）。
class UnitSubject private constructor( metadata: FailureMetadata, private val actual: Unit?, ) : Subject(metadata, actual) { // TODO } 次に、 assertThat をstaticな関数として定義します。 assertThat は検査対象となる値（actual）を引数にとります。この中で呼んでいる assertAbout はSubjectのFactoryを引数にとり、SubjectBuilderを返します。さらにSubjectBuilderに対して that を呼び出し、actualを渡すことでSubjectが作られます。ここでは独自に定義したUnitSubjectを返しています（ assertThat を経由してUnitSubjectのインスタンスを作りたいため、コンストラクタをprivateにしています）。
class UnitSubject private constructor( metadata: FailureMetadata, private val actual: Unit?, ) : Subject(metadata, actual) { // TODO companion object { /** * start assertion of an object with type Unit?</description></item><item><title>短絡評価を乱用しないでください🙅‍♂️</title><link>https://okuzawats.com/blog/do-not-abuse-short-circuit/</link><pubDate>Thu, 16 Mar 2023 22:48:54 +0900</pubDate><guid>https://okuzawats.com/blog/do-not-abuse-short-circuit/</guid><description>多くのプログラミング言語では、論理演算は短絡評価されます。Kotlinの文法であれば、 a &amp;amp;&amp;amp; b で a がfalseであれば b は評価されず、 a || b で a がtrueであれば b は評価されないということです（無駄なので）。
これを利用して、ハック的なコードを書くことが可能です。
わかりやすい例を提示します。以下のコードでは、 someBool() がtrueを返した時は some() のブロック内の処理は短絡評価されるため、 doSomething() は評価されません。一方、 someBool() がfalseを返した時は doSomething() が評価されます。
fun some() { someBool() || doSomething() } fun someBool(): Boolean = Random.nextBoolean() fun doSomething(): Boolean { println(&amp;#34;do something here&amp;#34;) return true } この &amp;amp;&amp;amp; || の短絡評価を利用すると、 someBool() がtrue / falseの時にだけ特定の処理を行う、という処理を書くことができるわけですが、あまり行儀が良くないので1、基本的にはやめましょう。
今回の例はまだわかりやすいですが、 if (someCondition() || anotherCondition()) {} のように、 if の条件式内で何らかの副作用が発生するような短絡評価の乱用は、厳に慎むべきでしょう。
Kotlinには、 and 演算子と or 演算子が存在します。これらの演算子はそれぞれ &amp;amp;&amp;amp; 演算子と || 演算子と似ていますが、 and 演算子と or 演算子は短絡評価されず、完全評価されます。すなわち、演算子の左側の値がtrueだろうがfalseだろうが、右側の値も評価される、ということです。</description></item><item><title>ソフトウェアエンジニアのキャリアパス</title><link>https://okuzawats.com/blog/software-engineer-career-path/</link><pubDate>Sat, 11 Mar 2023 22:18:32 +0900</pubDate><guid>https://okuzawats.com/blog/software-engineer-career-path/</guid><description>ソフトウェアエンジニアには一般にどのようなキャリアパスがあるのか、ということを考えます。組織によっても異なるでしょうが、一般的には以下のようにまとめられそうです（Will (2021), James (2022) より筆者作成） 。&amp;ldquo;L&amp;quot;はレベル、&amp;ldquo;IC&amp;quot;はIndividual Contributorです。
注意点です。
ICトラックとマネジメントトラックを行き来する人もいると思いますが、両者は別物と考えた方が良さそうです。 同じ名前で呼ばれていても、組織の規模によってレベル感は異なります。極端な話、CEOとCTOのふたりだけのスタートアップのCTOと、GAFAM的な企業のCTOでは、一般的に後者の方がレベル感が高いとみなされるでしょう。 ジュニアエンジニア〜エンジニア ソフトウェアエンジニアとしての仕事は、ジュニアエンジニアから始まります。組織によって定義は異なるでしょうが、仕事を進めるために手助けが必要な段階です。手助けが不要になり、ひとりで仕事が進められるようになれば、「ジュニア」が外れて「エンジニア」と呼ばれることになるでしょう。
このレベルには、マネジメントトラックは存在しません。
シニアエンジニア エンジニアからレベルが上がって、ICトラックに進んだ場合はシニアエンジニアと呼ばれるようになります。しっかりとした知識を持ち、周囲から頼りにされるようになるレベルです。ジュニアエンジニアやエンジニアにアドバイスができたり、プロジェクトの主力メンバーだったりするでしょう。
スタッフエンジニア シニアエンジニアからさらにレベルが上がると、スタッフエンジニアと呼ばれるようになります。スタッフエンジニア以上のソフトウェアエンジニアには、以下の4つの類型があります（Will (2021) ）。より困難で、答えのない問題に取り組んでいくことになるでしょう。
テックリード（Tech Lead）：チームに対するリーダーシップを発揮する役割。 アーキテクト（Architect）：特定の技術分野の技術的リーダーシップを発揮する役割。 ソルバー（Solver）：難しい技術的課題を解決する役割。 ライトハンド（Right Hand）：エグゼクティブの右腕となる役割。 プリンシパルエンジニア ICとして極まった人です。
エンジニアリングマネージャー エンジニアからレベルが上がって、マネジメントトラックに進んだ場合はエンジニアリングマネージャーと呼ばれるようになります。レベル感としてはシニアエンジニアと同じL3です。
エンジニアリングディレクター エンジニアリングマネージャーからレベルが上がるとエンジニアリングディレクターと呼ばれるようになります。レベル感としてはスタッフエンジニア相当のL4です。
エンジニアリング担当VP（Vice President） エンジニアリングディレクターからさらにレベルが上がるとエンジニアリング担当VPと呼ばれるようになります。VPoEなどでしょうか。レベル感としてはスタッフエンジニアやプリンシパルエンジニアに相当するL5〜L6です。
CTO マネジメントトラックを極めるとCTOと呼ばれるようになるようです。レベルはL7になるので、ソフトウェアエンジニアの最上位職種と言えるかもしれません。
References Will Larson, (2021), Staff Engineer Leadership beyond the management track James Stanier, (2022), エンジニアリングマネージャーのしごと チームが必要とするマネージャーになる方法, オライリー・ジャパン Camille Fournier, (2018), エンジニアのためのマネジメントキャリアパス テックリードからCTOまでマネジメントスキル向上ガイド, オライリー・ジャパン</description></item><item><title>SwiftでFizzBuzz</title><link>https://okuzawats.com/blog/swift-fizzbuzz/</link><pubDate>Sun, 26 Feb 2023 22:27:00 +0900</pubDate><guid>https://okuzawats.com/blog/swift-fizzbuzz/</guid><description>Swiftに入門していきたいので、FizzBuzzを書いて肩慣らししていきます。FizzBuzzのルールについてはWikipediaを参照してください。
FizzBuzz まずは普通に switch で書こうとしたわけですが、Swiftの switch は値を返す式ではなく、値を返さない文です。そのため、Fizzを返すパターン、Buzzを返すパターン、FizzBuzzを返すパターン、それ以外のパターンのすべてで return を書く必要があることに気付きます。悪くないですが、 return をもう少し減らしたいです。
ということで、var で文字列を宣言し、3で割り切れる場合は Fizz を、5で割り切れる場合は Buzz を文字列に追加していくアプローチを取ります。3で割り切れ、かつ5でも割り切れる場合は、Fizz と Buzz の両方が追加されて FizzBuzz となる仕組みです。最初に書いたものがこれです。
func fizzbuzz(n:Int) -&amp;gt; String { var s = &amp;#34;&amp;#34; if n % 3 == 0 { s += &amp;#34;Fizz&amp;#34; } if n % 5 == 0 { s += &amp;#34;Buzz&amp;#34; } return s.isEmpty ? String(n) : s } (1...100) .map { fizzbuzz(n:$0) } .forEach { print($0) } 悪くないです。</description></item><item><title>[MacOS] HomebrewからGitをインストールする</title><link>https://okuzawats.com/blog/install-git-on-mac-from-homebrew/</link><pubDate>Tue, 21 Feb 2023 22:28:08 +0900</pubDate><guid>https://okuzawats.com/blog/install-git-on-mac-from-homebrew/</guid><description>まったく目新しい情報ではないですが、MacOS（Venture 13.0、Apple M2、MacBook Pro 2022）でHomebrewを用いてGitをインストールする方法をメモしておきます。せっかく新しいMacを買ったので。
MacOS Venture 13.0 Apple M2 MacBook Pro 2022 Homebrewのインストール Homebrewはプリインストールされていないので、インストールします。
% brew -v zsh: command not found: brew Homebrewのインストールスクリプトを実行します。今回は以下のコマンドでした。
% /bin/bash -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&amp;#34; // 略 ==&amp;gt; Next steps: - Run these two commands in your terminal to add Homebrew to your PATH: (echo; echo &amp;#39;eval &amp;#34;$(/opt/homebrew/bin/brew shellenv)&amp;#34;&amp;#39;) &amp;gt;&amp;gt; /Users/okuzawats/.zprofile eval &amp;#34;$(/opt/homebrew/bin/brew shellenv)&amp;#34; - Run brew help to get started - Further documentation: https://docs.brew.sh % (echo; echo &amp;#39;eval &amp;#34;$(/opt/homebrew/bin/brew shellenv)&amp;#34;&amp;#39;) &amp;gt;&amp;gt; /Users/okuzawats/.</description></item><item><title>「単体テストの考え方 / 使い方」を読みました📚</title><link>https://okuzawats.com/blog/unit-testing-principles-practices-and-patterns/</link><pubDate>Tue, 31 Jan 2023 22:24:00 +0900</pubDate><guid>https://okuzawats.com/blog/unit-testing-principles-practices-and-patterns/</guid><description>単体テストの考え方/使い方 (Vladimir, (2022)) を読みました。2022年末から話題になっていて、Amazonでは品切れの状態が続いていた本です。物理書店に行くと割と置いてあるみたいです。自分も年末に物理書店で購入し、興味深く読みました。
さて、この本は単体テストの質を高め、ソフトウェアに価値をもたらすための本です。
ソフトウェアに価値をもたらす単体テスト 単体テストには、ソフトウェアに価値をもたらす単体テストとそうでない単体テストがある、というのが本書の主張です。そして、ソフトウェアの成長を支え、価値をもたらす単体テストを書くためにはどうすればよいのか、ということが論じられています。
わかりやすい例でいうと、プロダクトコードをリファクタリングした時に（壊れるべきでないのに）壊れてしまうテストは、価値が低いです。本書では、こういったテストをリファクタリングに対する耐性がないテストであるとし、改善が必要であるということを論じています。
単体テストとアーキテクチャ また本書では、ソフトウェアのアーキテクチャにも論が及びます。単体テストを扱った書籍で何故アーキテクチャの話をするのでしょうか？それは、単体テストの質を向上するためには、プロダクトコードのアーキテクチャを改善しなければならないためです。
こちらもわかりやすい例をあげると、「Humble Object」の話に触れられています。これはテストを書きにくい箇所を質素（Humble）にし、テストを書きやすい部分を抜き出してテストを書きにくい箇所を包み込むようにしていく、という考え方です（いろいろな本に書かれています）。
また、特に強い印象を受けたのは、ヘキサゴナルアーキテクチャの一種として紹介された、関数型アーキテクチャという考え方です。これはアーキテクチャの中心を関数型で構成し（Functional Core）、その外側にMutable Shellを置くというものです。常に関数型アーキテクチャを採用することが正解というわけではありませんが、考え方としてはとても興味深いと思いました。
モック また、モック主義者で触れたように、モックの使い方もひとつの論点となっています。記事にも書きましたが、このあたりの考え方についてはアップデートして行きたいと思っています。
Reference Vladimir Khorikov, 須田智之（訳）, (2022), 単体テストの考え方/使い方, マイナビ出版</description></item><item><title>モック主義者</title><link>https://okuzawats.com/blog/mockist/</link><pubDate>Mon, 23 Jan 2023 22:25:00 +0900</pubDate><guid>https://okuzawats.com/blog/mockist/</guid><description>「単体テストの考え方/使い方」 (Vladimir, (2022)) を読んでいて驚いたことのひとつが、「モック主義者」という概念でした。自分もモック主義者の持つ信条を持っていたので、知らない間に何らかの派閥に入ってしまっていたことに気付いたためです。
モック主義者とは、単体テストに関する2つの派閥、古典学派とロンドン学派のうち、ロンドン学派に属するプログラマーを指します。これらの学派はユニットテストにおいて「何を隔離するのか？」という点について考えを異にするグループです。
ロンドン学派は、テスト対象システムから協力者オブジェクトを隔離し、すべての依存をテストダブルに置き換えます。一方で古典学派は、テストケースが互いに影響しないよう、テストケースを隔離します。テストダブルも使用しますが、使い方はロンドン学派と比べて限定的です。こちらは「デトロイト学派」とも呼ばれることがあります (Tom, (2023)) 。
「Good Code, Bad Code 持続可能な開発のためのソフトウェアエンジニア的思考」 (Tom, (2023)) では、古典学派とロンドン学派の特徴を以下のように示しています。
古典学派 テストにおいて、プロダクションの依存関係を用いることを優先すべき その次に優先するのはフェイク モックとスタブの使用は最小限にし、プロダクションの依存関係とフェイクを使用できない場合の最終手段 ロンドン学派 テストにおいて、プロダクションの依存関係を用いることを避け、モックを使うべき 自分は、単体テストはテスト対象となるクラスをその依存先から隔離すべきであると考えており、基本的にすべての依存をテストダブルに置き換えることを目指していました。いつ・どこでこの考え方を持ったのかは思い出せませんが、知らない間にロンドン学派の考え方をしていたようです。
「単体テストの考え方/使い方」を読んで、それとは異なる考え方があるということを学ぶことができ、視野を広げることができたのは僥倖でした。今後、単体テストに関する考え方をアップデートしていきたいと思います。
References Vladimir Khorikov, (2022), 単体テストの考え方/使い方 プロジェクトの持続可能な成長を実現するための戦略, マイナビ出版 Tom Long, (2023), Good Code, Bad Code 持続可能な開発のためのソフトウェアエンジニア的思考, 秀和システム</description></item><item><title>[Android] build.gradle.ktsでJaCoCoを動かす</title><link>https://okuzawats.com/blog/configure-jacoco/</link><pubDate>Sun, 22 Jan 2023 05:58:00 +0900</pubDate><guid>https://okuzawats.com/blog/configure-jacoco/</guid><description>※ 本記事で紹介しているarturdm/jacoco-android-gradle-pluginを用いる方法は、Gradle 8では動かないようです。Fixed build crash in gradle 8.0に修正のPRが作成されていますが、本日現在、まだマージはされておりません。代わりに、thsaravana/jacoco-android-playgroundを参考にしてGradleのタスクを作成する方法があります。
AndroidのGradleの設定ファイルを build.gradle から build.gradle.kts に書き換えた時、JaCoCoをセットアップする方法がわからなかったので頑張って動かしてみました。GradleとJaCoCoについてはよくわかっていないことが多いです。プロジェクトを以下のリポジトリにpushしてあります。
okuzawats/android-jacoco-test-report: measure test coverage of android app with JaCoCo JaCoCoのセットアップのために、Android用のプラグインを作ってくれている方がいたので、利用させていただきました。とても助かりました。ありがとうございます。
arturdm/jacoco-android-gradle-plugin: Gradle plugin that creates JaCoCo test reports for Android unit tests プロジェクトのsettings.gradle.kts Maven Repositoryを追加します。プロジェクトによっては、プロジェクトの build.gradle.kts に追加する場合もあると思います。
dependencyResolutionManagement { // 略 repositories { // 略 maven(url = &amp;#34;https://plugins.gradle.org/m2/&amp;#34;) } } プロジェクトのbuild.gradle.kts プラグインをdependenciesに追加します。
buildscript { dependencies { // 追加 classpath(&amp;#34;com.dicedmelon.gradle:jacoco-android:0.1.5&amp;#34;) } } plugins { // 略 } モジュールのbuild.gradle.kts プラグインを適用し、JaCoCoのバージョン、出力するカバレッジレポートの種別、カバレッジレポートの有効化を行います。</description></item><item><title>2022年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2022/</link><pubDate>Sat, 24 Dec 2022 22:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2022/</guid><description>さて、はやいもので2022年も終わろうとしております。毎年恒例のふりかえりを行いたいと思います。仕事についてはあまり書くこともないので、主にプライベートについてです。
昨年、一昨年のふりかえりはこちらです。
2021年のふりかえり 2020年のふりかえり 2022年1月 Ruby on Rails、Heroku、RSpec、GitHub Actionsあたりをまとめて触っていました。Railsは折に触れて触っていますが、特に何も作ることがないです。 AWS Code PipelineでのCIなども触っていました。 Hugoで作っている本ブログのリニューアルなどもしてました。 読んだ本（のうちメモの残っているもの）は以下の三冊です。 クリーンコーダー Advanced Android App Architecture Kotlin Design Patterns and Best Practices 書いたブログ記事は7本です。この頃は頑張ってブログを書いていました。 -[Android] UseCaseの実装 -[Android] OkHttpのMockWebServerを用いた、OkHttp + Retrofitのユニットテスト -[Android] SnackbarをBuilderパターンっぽく表示したい -[Kotlin] sealed classに親しむ -[Kotlin] 「何もしない」関数をいい感じに書きたい -何故、依存性注入（DI）するのか -[Architecture] Advanced Android App Architectureを読みました 2022年2月 RubyのプロジェクトをCodeCovでカバレッジ計測できるようにしてました。 引き続き、AWSをちょこちょこ触ってました。 趣味のAndroidアプリ（未完🍊）を作ってたりしました。 外資のコーディング試験のための大慌てでコーディング試験の対策をしてたりしました。 書いたブログ記事は4本です。 [Kotlin] underscore prefixに関するコーディング規約 [Kotlin] nullオブジェクトパターン [Kotlin] はじめてのカリー化 [Kotlin] 負数に対する除算の商と剰余 2022年3月 Ruby on Railsを触ったり、「RubyでつくるRuby」の写経をしていたり、引き続きRubyをやっていました。仕事で書かないのにRuby好きだな自分。 フラー株式会社とちゅらデータ株式会社の合同勉強会で、Kotlinのifを愛でるというタイトルで登壇してました。 引き続き外資のコーディング試験のため大慌てで（略）。 Kotlin Multiplatform Mobileをちょっとお試ししていたような気もします。 読んだ本は以下です。 Googleのソフトウェアエンジニアリング 書いたブログ記事は3本です。 [Kotlin] ユークリッドの互助法を用いて最小公約数・最小公倍数の計算を実装する コードレビューにおける「パッと見でわからないので」 設計原則 2022年4月 この頃、現職にモバイルアプリケーションアーキテクトとして入社することを決めていたので、ソフトウェアのアーキテクチャ・設計に関する本をよく読んでました。良かったのはこのあたりです。 実践テスト駆動開発 オブジェクト指向設計入門ガイド ソフトウェアのアーキテクチャの基礎 進化的アーキテクチャ 「コンピュータシステムの理論と実装」を再び始めました。 書いたブログ記事は1本です。 巨大な泥団子 2022年5月 引き続き、「コンピュータシステムの理論と実装」をやってました。 簡単な計算式のパーサとそれを用いた計算機を作ったりしてました。「コンピュータシステムの理論と実装」でやっていた内容を使ってAndroidアプリを作ってみよう、みたいな感じのモチベーションだったと思います。 あと、DockerやElixirに触れてました。 GitHub as a Text Strage活動をしていて、過去の登壇スライドをMarkdown化してGitHubのリポジトリにまとめたりしてました。 読んだ本はこのあたり。Elixirを書いていて、関数型に目覚めていたんだと思います。 良いコード／悪いコードで学ぶ設計入門 Scala スケーラブルプログラミング 書いたブログ記事は2本です。 [Kotlin] ifを愛でる [Kotlin] 末尾カンマ 2022年6月 U-NEXTさん主催の勉強会で、会社のGitHub Actionを完全停止させるところだった話で登壇しました。気を付けましょう。 個人的に気になっていたUniflowというライブラリを味見してみて、なるほどMVIとなっていました。 マイクロサービスに興味を持っていたようです。読んだ本。 モノリスからマイクロサービスへ 書いたブログ記事は1本です。 自己カプセル化 2022年7月 mermaid.</description></item><item><title>[Android] EventBusの思い出🚌</title><link>https://okuzawats.com/blog/eventbus/</link><pubDate>Fri, 23 Dec 2022 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/eventbus/</guid><description>この記事はフラー株式会社 Advent Calendar 2022の記事です。22日目は @Daiji256 による「onClick VS onClicked」でした。
さて、6日目の記事「Androidエンジニアになってから4年経った振り返り」を読みました。自分は、上記の記事を書いた @m-coder より少し前にAndroidアプリ開発を始めたのですが、記事を読むと、この4年間やその前にあったいろいろな出来事が思い出されてきます。自分としたことがちょっとセンチメンタルな気分になってしまいました&amp;hellip;。人生いろいろありますね。
ともかく、上記記事ではRxJavaについて触れられていました。これを読んでいて思い出したのが、RxJavaが広く使われるようになった、そのもう少し前。燎原の火のごとく燃え広がり、RxJavaの流行と共にAndroidアプリ開発の歴史に消えていったものがありました。本記事はソレについての思い出を書き記し、Androidアプリ開発史における歴史の一里塚とすることを意図したものです。
自分の理解不足や記憶違いがあればご指摘ください。予防線を張ったところで、始めていきます。
EventBus RxJavaが流行する前、EventBusなるものが流行していました。
EventBusとは、特定のライブラリというよりは、イベント通知の設計を指します。その実装を提供する代表的なライブラリとしては、Square製のOttoや、greenrobot製のEventBusが存在します。5年以上前の歴史については明るくないのですが、おそらくGuavaの流れを汲んでいたものと思います。
square/otto: An enhanced Guava-based event bus with emphasis on Android support. greenrobot/EventBus: Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality. 前者のOttoについては、今から6年前の2016年にDeprecatedとなり、本日までにプロジェクトがアーカイブされています。後者のEventBusについてはDeprecatedになったりアーカイブになったりこそしていませんが、それほど活発にメンテナンスがされている状況ではありません。こういった状況を踏まえると、EventBusは既にAndroidアプリ開発のメインストリームからは外れていると言えそうです。
それでは、EventBusは何故流行し、そして何故消えていったのでしょうか？
Callback Hell さて、EventBusとはイベント通知の設計である、と書きました。以下の図に、EventBusによる基本的なイベント通知のフローを示します。Publisher、すなわちイベントの発行者は、EventBusに向けてイベントを通知します。Subscriber、すなわちイベントの購読者は、EventBusからイベントを購読します。この図に示されるEventBusは、大域的に存在するインスタンスです。
Fig-1 EventBus ※ 画像出典：greenrobot/EventBus: Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc.</description></item><item><title>[Android] Clean Architecture の理論と実装</title><link>https://okuzawats.com/blog/clean-architecture/</link><pubDate>Sun, 06 Nov 2022 22:38:00 +0900</pubDate><guid>https://okuzawats.com/blog/clean-architecture/</guid><description>追記：以下の書籍に、本記事の内容に加筆・修正した内容が収録されています。是非、お手にとっていただけますと幸いです。
［入門］ドメイン駆動設計 基礎と実践・クリーンアーキテクチャ Androidアプリにおいてクリーンアーキテクチャを採用する場合の基本的な実装アイデアをこの記事にまとめます。あくまで自分の個人的なアイデアですので、他にもいろいろな異なる考え方が存在する可能性があります。その辺を割り引いて、ひとつのアイデアとして受け取っていただけますと幸いです。予防線を張ったところで始めていきます。
サンプルコードはGitHubの以下のリポジトリに置いてあります。ので、プロジェクト全体をローカル環境で参照したい場合はリポジトリをForkしてください。また、本記事執筆時点でのコードにはタグが切ってありますので、記事に対するソースコードを参照したい場合は、タグのコミットをチェックアウトしてください。
okuzawats/android-clean-architecture: Android Clean Architecture Sample App (WIP🤪) Release verion.1 · okuzawats/android-clean-architecture 本記事では、Androidアプリ開発に関する基本的な知識と、依存性注入（DI）、依存関係逆転の原則を理解していることを前提条件とします。DI及び依存関係逆転の原則については本ブログ内にも記事がありますので、必要に応じて参考にしていただければと思います。
何故、依存性注入（DI）するのか 依存関係逆転の原則 クリーンアーキテクチャの図 まずは、書籍クリーンアーキテクチャ (Robert (2018), p.200) の有名な図と、Androidのアプリアーキテクチャガイド (https://developer.android.com/topic/architecture) を参考に、目指すアプリのアーキテクチャの図を描きます。それが以下の図です。
Domain この図の中心には、Domainが存在します。本記事におけるDomainでは、ビジネスルールをUseCaseとして定義します。書籍クリーンアーキテクチャでは、UseCaseの中心にさらにEntityが存在しますが、本記事ではEntityは登場しません。
UseCaseの実装においての注意点としては、ひとつのUseCaseは単一の機能のみを持つ、ということがあります。すなわち、ひとつのUseCaseに対して、ひとつのメソッドのみが定義されます。この方針での実装はいろいろなやり方が考えられると思いますが、本記事では、以下の記事で紹介した、operator fun invoke を実装する方針で実装します。
[Android] UseCaseの実装 この方針で実装した場合、UseCaseのインスタンスに対して awesomeUseCase() というようにinvokeを呼び出し、UseCaseの処理を実行することができます。
Presentation 図のDomainの上に目を向けると、Presentationが存在します。PresentationはUIに対するInterface Adapterの役割を持ち、ViewModelとして実装しています。PresentationはAndroidフレームワークへの依存を持たないように実装すべきですが、実装都合で、Android Architecture ComponentsのViewModelを用います。
Android Architecture ComponentsのViewModelはAndroidの複雑なライフサイクルをいい感じに扱うために非常に便利ですが、すなわちフレームワーク非依存と言いにくくなってしまいます。まあ便利だから使うんですが&amp;hellip;。
以下、本記事で特に断りなくViewModelと書く時は、Android Architecture ComponentsのViewModelではなく、Presentationにおける（MVVM的な意味での）ViewModelを指します。
UI 図のPresentationのさらに上に目を向けると、UIが存在します。AndroidにおけるUIは、Activity、Fragment、Composeといったものです。UIは、Androidのフレームワークに依存します。
Data 今度は、図のDomainの下に目を向けます。ここには、Dataが存在します。Dataは主にRepositoryとして実装します。Repositoryは、RESTful API、ローカルデータベース、SharedPreferenceなどのデータソースに対するInterface Adapterの役割を持ち、データアクセスを抽象化します。
Data Source さらにDataの下に目を向けると、DataSourceが存在します。DataSourceには、RESTful API、ローカルデータベース、SharedPreference等、データに直接アクセスするコードが書かれます。
制御の方向と依存の方向 図中の青い色の矢印と赤い色の矢印に注目します。これは制御の方向と依存の方向を表しています。
例えば、UIとPresentationについて考えます。具体的な状況としては、MVVMにおけるViewとしてのActivityとViewModelです。
典型的なMVVMの実装では、Activityがユーザーアクションを受け、ViewModelにアクションを伝えます。ViewModelではアクションを受け取り、何らかの処理を行ったのち、ViewであるActivityに状態更新通知などを送ることになるでしょう。この更新通知は主としてObserverパターンを用いて実装されるため、ViewModelはそのサブスクライバであるViewへの依存を持たない、ということになります。すなわち、依存の方向は、UI (View) → Presentation (ViewModel) となります。ViewがViewModel側に定義されたメソッドを呼び出しますので、制御の流れも同じくUI (View) → Presentation (ViewModel)です。</description></item><item><title>Mockk によるモック入門</title><link>https://okuzawats.com/blog/mockk/</link><pubDate>Sat, 22 Oct 2022 22:50:00 +0900</pubDate><guid>https://okuzawats.com/blog/mockk/</guid><description>MockK は、オープンソースで開発されている、Kotlin 製のモックライブラリです。本記事では、MockK を用いてテストコードを書く方法を紹介します。MockK のすべての API に触れることはできませんので、筆者が代表的な API と考える API について触れていきます。より詳しい内容については、MocKK の Web サイトを参照してください。
MockK | mocking library for Kotlin モックライブラリとは モックライブラリとは、ユニットテストで用いるためのテストダブル（テストのための代役）を便利に扱うためのライブラリです。モックライブラリを用いることで、わざわざ自分でテストダブルを作るためのコードを書かなくとも、快適にテストコードを書くことが可能となります。
Kotlin から便利に利用できるモックライブラリには、本記事で紹介する MockK の他に、Java 向けのモックライブラリである Mockito の Kotlin 向けラッパーである Mockito-Kotlin が存在します。
mockito/mockito-kotlin: Using Mockito with Kotlin MockK と Mockito-Kotlin のどちらを選んでも基本的な機能には大きな差はありませんが、MockK は Mockito-Kotlin にない便利・強力な機能が存在します。「Android ユニットテスト ヒッチハイク・ガイド」の本での結論とは異なってしまいますが、本記事執筆時現在、筆者個人的には MockK を選ぶことを推奨したいと思います。
本書では、Android のプロジェクトのユニットテストに MockK を導入するケースを想定し、MockK の基本的な機能について紹介します。
Android のプロジェクトへの MockK の導入 Android のプロジェクトに MockK を導入するには、build.gradle または build.gradle.kts に以下のような記述を追加します（以下の例は build.gradle の場合です）。MockK のバージョンは、執筆時点の最新版を使用しています。
dependencies { testImplementation &amp;#34;com.</description></item><item><title>Truth によるアサーション入門</title><link>https://okuzawats.com/blog/truth/</link><pubDate>Sat, 08 Oct 2022 10:30:00 +0900</pubDate><guid>https://okuzawats.com/blog/truth/</guid><description>Truth は、Google が中心となって開発している、Java / Android 向けのアサーションライブラリです。本記事では、Truth を用いてアサーションを行う方法を紹介します。Truth のすべての API に触れることはできませんので、筆者が代表的な API と考える API について触れていきます。より詳しい内容については、Truth の Web サイトを参照してください。
Truth - Fluent assertions for Java and Android androidx.test による Truth の拡張については本記事では触れませんので、androidx.test のドキュメントを参照してください。
Package Index | Android Developers アサーションライブラリとは アサーションライブラリとは、テストコードにおけるアサーションの可読性を上げ、またアサーションを書きやすくしてくれるライブラリです。アサーションに失敗した時のメッセージもわかりやすくしてくれるため、どういう理由でテストが失敗したのかも把握しやすくなります。
Java 向けのアサーションライブラリも種々ありますが、その中で Truth の特徴は、シンプルな API を提供していること、Android のサポートがあることがあげられます。前者の「シンプルな API を提供していること」は、テストコードを書く場合に考えることを減らして、機能の実装に集中することができるというメリットがあります。後者の「Android のサポートがあること」については、Android のプロジェクトで Truth を導入することを後押ししてくれます。
本書では、Android のプロジェクトのユニットテストに Truth を導入するケースを想定し、Truth による基本的なアサーションについて紹介します。
Android のプロジェクトへの Truth の導入 Android のプロジェクトに Truth を導入するには、build.gradle または build.gradle.kts に以下のような記述を追加します（以下の例は build.gradle の場合です）。Truth のバージョンは、執筆時点の最新版を使用しています。
dependencies { testImplementation &amp;#34;com.</description></item><item><title>Chatworkにメッセージを送信するGitHub Actionsを公開しました🎉</title><link>https://okuzawats.com/blog/chatwork-messaging-action/</link><pubDate>Wed, 31 Aug 2022 13:32:00 +0900</pubDate><guid>https://okuzawats.com/blog/chatwork-messaging-action/</guid><description>GitHub ActionsからChatworkに何かを通知したいことがありませんか？僕はあります。例えば、CIが成功した時は成功したことをChatworkに通知して欲しいですし、CIが失敗した時は失敗したことをChatworkに通知して欲しいです。GitHub Actionsが元気に動いているのを眺めているのは楽しい趣味ですが（そして時に必要なことでもありますが）、大抵の場合は結果だけをチャット（ここではChatwork）に通知してくれれば足ります。
結論としては、GitHub ActionsからChatworkにメッセージを送信するためのActionをGitHubのマーケットプレースに公開しました🎉こちらのActionを使っていただければ、GitHub ActionsからChatworkへ、簡単にメッセージを送信できるようになるかと思います。
Chatwork Messaging Action · Actions · GitHub Marketplace ちなみに、GitHubのマーケットプレースを探すと、既に以下のアクションが存在しました。どのActionもPull Requestに関する通知を送ってくれるActionのようです。自分はCIの結果をChatworkに通知する、というようなユースケースを満たすActionが欲しいと考えていたので、これらのActionはちょっと目的が違うかなと思いました。
chatwork-actions · Actions · GitHub Marketplace Pull Request Chatwork Notifier · Actions · GitHub Marketplace Open Pull Requests Chatwork Notifier · Actions · GitHub Marketplace 使い方 以下にサンプルとなるGitHub Actionsのワークフローを示します。 okuzawats/chatwork-messaging-action を使用している箇所に着目してください。
name: send message on: push: branches: [main] jobs: message: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: set current datetime to env env: TZ: &amp;#39;Asia/Tokyo&amp;#39; run: echo &amp;#34;CURRENT_DATETIME=$(date +&amp;#39;%Y-%m-%d %H:%M:%S&amp;#39;)&amp;#34; &amp;gt;&amp;gt; $GITHUB_ENV - name: set arguments id: arguments run: echo &amp;#39;::set-output name=message::&amp;#34;[info][title](beer)what time is it now?</description></item><item><title>キャリアラダーとキャリアパス</title><link>https://okuzawats.com/blog/career-ladder-vs-career-path/</link><pubDate>Fri, 05 Aug 2022 21:26:54 +0900</pubDate><guid>https://okuzawats.com/blog/career-ladder-vs-career-path/</guid><description>リーダーの作法 (Lopp, (2022)) の脚注に面白い考えが書かれてました。この書籍の中で「キャリアラダー」という言葉ではなく「キャリアパス」という言葉を使っている理由です。以下に引用します。
ここで「ラダー（はしご）」という言葉を使いたがる人もいますが、私は「パス（道）」という言葉が好きです。はしごは、上に向かって登らなければなりませんが、パスは旅です。 (Lopp (2022), リーダーの作法, p.133)
自分も筆者の意見に近いです。キャリアを「はしご」と捉える場合、多くの人は組織図でのヒエラルキーの上に行くことをイメージするものと思います。もちろん、組織の統制上、権力関係は必要でしょう。その一方で、プロフェッショナルのキャリアは、この組織図上のヒエラルキーとは切り離して考えるべき、とする立場です。
例えば、テックリードというロールを考えても、「エンジニアの階層におけるランクのひとつではなく、シニアのレベルに達したエンジニアが担うことのできる職責郡である」(Fournier (2018)) と考えています。あくまでロールであって権力ではないと捉えている、という意味です。テックリードの場合は、スキル、知識、リーダーシップでチームをリードするべきで、権力を使って何かを成し遂げるロールではないというのが自分の考えです。
また、エンジニアリングマネージャー、テックリード、インディビジュアルコントリビューターのどのロールを選んでも正解であるし1、キャリアの途中でロールをチェンジすることも正解であると考えているのですが、キャリアを「はしご」と捉えた場合、この考えが成立しなくなってしまうと思うのです。
キャリアを「パス」として捉えれば、どこへ歩いていくのも当人次第である、と愚考する次第です。
References Michael Lopp (著), 和智右桂 (訳), (2022), リーダーの作法, オライリージャパン Camille Fournier (著), 武舎広幸 (訳), 武舎るみ (訳), (2018), エンジニアのためのマネジメントキャリアパス, オライリージャパン 選べる場合は。&amp;#160;&amp;#x21a9;&amp;#xfe0e;</description></item><item><title>[Android] Robolectricとandroidx.test</title><link>https://okuzawats.com/blog/robolectric-vs-androidx-test/</link><pubDate>Wed, 03 Aug 2022 22:03:45 +0900</pubDate><guid>https://okuzawats.com/blog/robolectric-vs-androidx-test/</guid><description>Robolectricと androidx.test のどちらを使えばいいのか混乱してしまったので、情報を整理します。
わかりやすい例としてSharedPreferenceを取り上げます。SharedPreferenceへのアクセサを提供する、こんな感じのクラスを考えます。SharedPreferenceへの文字列の読み書きをしているだけのクラスです。
import android.content.SharedPreferences import androidx.core.content.edit private const val KEY_SOME_STRING = &amp;#34;KEY_SOME_STRING&amp;#34; class PreferenceDataSource( private val preference: SharedPreferences, ) { var someString: String get() = preference.getString(KEY_SOME_STRING, &amp;#34;&amp;#34;)!! set(value) { preference.edit { putString(KEY_SOME_STRING, value) } } } 一昔前は、Robolectric1のRuntimeEnvironmentを使ってテストを書いてましたね。
testImplementation(&amp;#34;org.robolectric:robolectric:4.8&amp;#34;) import androidx.preference.PreferenceManager import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment @RunWith(RobolectricTestRunner::class) class PreferenceDataSourceTest { @Test fun test() { val preferenceDataSource = PreferenceDataSource( PreferenceManager.getDefaultSharedPreferences( RuntimeEnvironment.getApplication().applicationContext ) ) preferenceDataSource.someString = &amp;#34;hello world!&amp;#34; assert(preferenceDataSource.</description></item><item><title>テックリードとは</title><link>https://okuzawats.com/blog/techlead/</link><pubDate>Tue, 02 Aug 2022 22:07:22 +0900</pubDate><guid>https://okuzawats.com/blog/techlead/</guid><description>新興のIT企業を中心に、テックリードという役割が広がっています1。かく言う私もテックリードをやっているわけですが、果たしてこのテックリードとは、一体どんな役割なのでしょうか。翻って考えてみたいと思います。
何冊かの本から、あらかじめ参考になりそうな記述をメモしておきました。
ソフトウェアの開発チームに対する責任を負う役割を持つ、技術面でのリーダー (Kua, (2015)) マネージャーが人員のリーダーであるのに対し、テックリードは技術的取り組みを主導する役割 (Winters他 (2021)) プログラミングの最前線からは退き、技術面での貢献とチーム全体のニーズをバランスさせ、プロジェクトを推進するための大局的な視点を持つ (Fournier (2018)) どうも曖昧然としてはいますが、技術面でのリーダーシップを発揮する役割であることは間違いなさそうです2。いわゆるIndividual Contributor（IC）でも技術面でのリーダーシップを発揮することはありそうですが、違いは「チーム全体の生産性」に対する責任を負うかどうか、という点にありそうです。
面白い記事がありました。初出はWEB+DB PRESS Vol.103とのこと。
第11回　テックリード | gihyo.jp 少し長くなりますが、引用します。
テックリードの仕事は輝かしく見えるかもしれない。ただ実態は、地味である。またそうであるべきだ。技術的にチャレンジだったり、やりがいのある仕事はテックリードのものではない。そういう「おいしい」仕事はお膳立てだけして、チームメートに譲るのだ。
それよりも、誰もやりたがらないものがテックリードの仕事である。ミーティングの進行役、先を見越したプロジェクトマネジメント、コードのクリーンアップなど。とにかくチームの生産性を上げることが使命である。また、表面上は成果として見えないようなものにも取り組むべきだ。たとえばチームの技術スコープが将来的に広がるような技術やデザインの採用を促進するなど。
自分がテックリードになって「自分の仕事は地味だな」と感じたら、うまくいっている証拠なのでがんばってほしい。
(Minowa (2018))
とにかく地味に、チームの生産性を上げることがテックリードの使命であるということ。また、チームメートが活躍するためのお膳立てをして美味しいところは譲ることもテックリードの仕事である、とも書いています。
「テックリード」という響きは何やら格好いいですが、その響きほど格好いい役割ではなさそうだということがわかりました。改めて、自分自身のテックリードとしての仕事を振り返ってみたいと思いました。
追記 Forkwellさんからインタビューを受けて、テックリードをしていた時の仕事の内容や、その難しさ、楽しさについて話しました。以下の記事に掲載されています。
テックリードはキャリアの分岐点。取材でわかった6系統の役割と市場価値のリアル | エンジニアの生き様をウォッチするメディア 自分のコメントが掲載されていることを差し引いても、何人ものテックリードにその仕事内容をヒアリングした、面白い記事であると思います。
References Patrick Kua, (2015), Talking with Tech Leads: From Novices to Practitioners retrieved from https://www.amazon.co.jp/dp/B014Q2C4M4/ (最終アクセス日：2022年8月2日) Titus Winters, Tom Manshreck, Hyrum Wright, (2021), Googleのソフトウェアエンジニアリング, オライリージャパン Camille Fournier, (2018), エンジニアのためのマネジメントキャリアパス テックリードからCTOまでマネジメントスキル向上ガイド, オライリージャパン Taro Minowa, (2018), テックリード, retrieved from https://gihyo.</description></item><item><title>自己カプセル化</title><link>https://okuzawats.com/blog/self-encapsulation/</link><pubDate>Sun, 05 Jun 2022 06:28:00 +0900</pubDate><guid>https://okuzawats.com/blog/self-encapsulation/</guid><description>自己カプセル化（Self-Encupsulation） は、クラスの持つフィールドに対してクラス内部からアクセスする場合もアクセサメソッドを経由して行うパターンです。
以下のコード（Javaっぽい疑似コードです）は、自己カプセル化のパターンを適用する前のコードです。コンストラクタおよび getUserName で、アクセサメソッドを経由せずに firstName 、 lastName にアクセスしています。
class UserName { private String firstName; private String lastName; public UserName(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getUserName() { return firstName + &amp;#34; &amp;#34; + lastName; } } firstName と lastName に対するアクセサメソッドを追加して、 firstName 、 lastName へのアクセスをアクセサメソッド経由に変更します。
class UserName { private String firstName; private String lastName; public UserName(String firstName, String lastName) { setFirstName(firstName); setLastName(lastName); } public String getUserName() { return getFirstName() + &amp;#34; &amp;#34; + getLastName(); } private void setFirstName(String firstName) { this.</description></item><item><title>[Kotlin] 末尾カンマ</title><link>https://okuzawats.com/blog/kotlin-trailing-commas/</link><pubDate>Tue, 31 May 2022 22:22:00 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-trailing-commas/</guid><description>Kotlinの末尾カンマは、Kotlin 1.4において導入されました。引数リストの最後の要素の後にカンマを付けられる文法です。以下の val c: Int, の , の部分を指しています。Kotlin 1.4から、この , の部分を追加することが可能になりました（なくても良い）。
data class AwesomeDataClass( val a: Int, val b: Int, val c: Int, ) この末尾カンマが導入されて一番嬉しいのは、ここに新たな引数を追加した場合に、追加した行にのみ差分が生じることです。以下のような差分です。
val c: Int, + val d: Int, ) 末尾カンマを使わない場合の差分は以下のようになります。
- val c: Int + val c: Int, + val d: Int ) 末尾カンマを使った場合は、追加された引数の行にだけ差分が生じています。追加された箇所にだけ着目して差分を見ることが可能です。
引数を横に並べる場合は末尾カンマがあってもあまり嬉しくはありませんが、引数を縦に並べる場合は末尾カンマがあると嬉しいです。自分は引数を縦に並べたいので、（Kotlinのバージョンが1.4以前の場合を除いて）可能な限り、末尾カンマを使うようにしています。また、コードレビューなどでも、IMO1、IMHO2として、末尾カンマの使用を広める活動を地道に行っています。
なお、Kotlin公式のCoding conventionsには、以下の記述があります。変更の差分が見やすくなるというメリットの他に、引数の順序を入れ替えることとコードの生成が容易となることが、末尾カンマのメリットとしてあげられています。
It makes version-control diffs cleaner – as all the focus is on the changed value. It makes it easy to add and reorder elements – there is no need to add or delete the comma if you manipulate elements.</description></item><item><title>巨大な泥団子</title><link>https://okuzawats.com/blog/big-ball-of-mud/</link><pubDate>Fri, 29 Apr 2022 16:29:00 +0900</pubDate><guid>https://okuzawats.com/blog/big-ball-of-mud/</guid><description>巨大な泥団子（Big Ball of Mud） は、Brian Foote、Joseph Yoderによって書かれた1997年の論文のタイトルです。「進化的アーキテクチャ 絶え間ない変化を支える」「ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ」など、多数の書籍でしばしば参照されます。
この論文の中では、論文と同名の「巨大な泥団子」というソフトウェアの状態について語られています。「巨大な泥団子」とは、構造を持たず、要素間が密に結合し、ソフトウェア全体がひとつの大きな塊となっている状態です。すなわち、「認識できるアーキテクチャが不在の状態」(Mark他 (2022))と言えます。ソフトウェアのエントロピーが最大化されている状態といえるかもしれません。
「巨大な泥団子」状態のソフトウェアは、構造がないため、一般に変更が困難です。変更が困難なため、ソフトウェアがスケールしません。「継続的デリバリーのソフトウェア工学」から引用します。
ある箇所を書き換えると、コードのほかの部分に影響が出るような書き換えにくいコードがあります。システムのほとんど全部の仕組みを理解できるほどの頭脳がないと書き替えられないようなコードもあります。これではスケーラブルなアプローチになりません。（David（2022）, P.247）
物理的な、泥団子について考えます。泥団子は、構造を持ちません。少なくともマクロな視点から認識できる構造はありません。また、要素同士が結びついており、ひと塊の物体となっています。
ソフトウェアが「巨大な泥団子」となっている時も、まさしくソフトウェアはこの泥団子のような状態になっていると言えます。「巨大な泥団子」という言葉は、このようなソフトウェアの状態を表す的確な比喩であると思います。
Reference Brian Foote, Joseph Yoder, (1997), Big Ball of Mud, retrieved from http://www.laputan.org/mud/mud.html Neal Ford, Rebecca Parsons, Patrick Kua, (2018), 進化的アーキテクチャ 絶え間ない変化を支える, オライリー・ジャパン Mark Richards, Neal Ford, (2022), ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ, オライリー・ジャパン David Farley, (2022), 継続的デリバリーのソフトウェア工学, 日経BP</description></item><item><title>設計原則</title><link>https://okuzawats.com/blog/design-principle/</link><pubDate>Thu, 31 Mar 2022 05:59:00 +0900</pubDate><guid>https://okuzawats.com/blog/design-principle/</guid><description>ソフトウェアの設計には、「設計原則（Design Principle）」が存在します。ソフトウェアの設計に関して先人たちが考えてきた原則です。設計原則には、例えば、単一責任の原則やオープン・クローズドの原則といったものがあります。
「Head Firstデザインパターン」(Eric他 (2005)) には、設計原則について以下の記述が見つかります。
実際にはどの原則も法則ではなく、すべての原則はそれらが便利になるときと場合に使用すべきものです。すべての設計には（抽象化対速度、空間対時間などの）トレードオフがあります。原則は指針を提供しますが、すべての要因を考慮に入れてからそれらを適用すべきなのです。（Eric他、Head Firstデザインパターン（2005）、p.267）
ここでは、（ある条件のもので）必ず守られなければならない法則という概念に対して、原則という概念はあくまで指針であり、全ての要因を考慮して適用する（あるいは適用しない）ことを決定することのできるものである、ということが述べられています。
つまり、単一責任の原則やオープン・クローズドの原則といった設計原則は、その設計原則がもたらすメリットとデメリットを考えて適用すべきもの、ということです。設計原則は、常に守られなければならない法則ではなく、あくまで原則にすぎないのです。もちろん、むやみやたらに原則から外れてしまうことを許すべきではありませんが、何故原則があるのかを理解した上で、あえて原則から外れることは許容されるものなのです。
Reference Eric Freeman、Elisabeth Freeman、Kathy Sierra、Bert Bates、Head Firstデザインパターン（2005）、オライリー・ジャパン</description></item><item><title>コードレビューにおける「パッと見でわからないので」</title><link>https://okuzawats.com/blog/code-review-at-a-glance/</link><pubDate>Tue, 22 Mar 2022 22:26:00 +0900</pubDate><guid>https://okuzawats.com/blog/code-review-at-a-glance/</guid><description>コードレビューをしていて、「パッと見でわからないので、〜して欲しいです」とコメントすることがあります。「〜」の部分は、「名前の変更をして欲しい」とか「処理の書き方を見直して欲しい」とかです。実際にコードレビューする時にはもう少し具体的な内容を書きますけど。
「パッと見でわからないのであればわかるまでコードを読め」と言われてしまいそうなので、「パッと見でわからないので」というレビューコメントの書き方は果たして良いのだろうか、ということをしばしば考えます。
現時点では、コードがパッと見でわからないのであれば何らかの改善が必要なので、（改善案を提案しつつ）「パッと見でわからないので」とレビューコメントをするのは正しい、と結論しています。
何故か。
コードは、書かれるよりも読まれる回数の方が多いことが広く知られています（出典不明）。パッと見でわからないコードを読む時、プログラマーは注意深く周辺を探り、時間をかけてコードを解読しなければなりません。一方、パッと見でわかるコードになっていれば、そのようなことで時間を無駄にすることはありません。
プログラマーは、そのコードを書いた瞬間に最もそのコードを理解しています。時間とともに、コードを書いた時の思考は失われて行きます。そのコードを最も容易にわかりやすく書き直せるのは、コードを書いた直後、現実的にはコードレビューを受けている時になるでしょう。
「パッと見でわからない」コードは、修正されない限り「パッと見でわからない」コードであり続けます。即ち、チームの時間（＝お金）を奪い続ける負債となってしまいます。レビュワーがコードをパッと見てわからないのであれば、そのコードを今改善することが大きな価値となるのではないか、と愚考する次第です。</description></item><item><title>[Kotlin] ユークリッドの互助法を用いて最小公約数・最小公倍数の計算を実装する</title><link>https://okuzawats.com/blog/euclidean-algorithm/</link><pubDate>Fri, 18 Mar 2022 22:20:00 +0900</pubDate><guid>https://okuzawats.com/blog/euclidean-algorithm/</guid><description>2 つの自然数 a, b (a ≧ b) について、a の b による剰余を r とすると、 a と b との最大公約数は b と r との最大公約数に等しいという性質が成り立つ。この性質を利用して、 b を r で割った剰余、 除数 r をその剰余で割った剰余、と剰余を求める計算を逐次繰り返すと、剰余が 0 になった時の除数が a と b との最大公約数となる。（「ユークリッドの互除法 - Wikipedia」より引用）
上記のユークリッドの互助法をKotlinのコードに当てはめると、最小公約数（Greatest Common Divisor）を求める処理は以下のように再帰を用いて実装できます。末尾再帰最適化を適用できますので、 tailrec キーワードを付けています。
// 最小公約数 tailrec fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b) 最小公倍数（Least Common Multiple）を求める処理については、2つの数の積を最小公約数で除算すればよいです。上記の gcd 関数を用いて以下のように実装できます。 (a * b) / gcd(a, b) としていないのは、 () を減らすための細かいテクニックです（コードゴルフ）。</description></item><item><title>[Kotlin] 負数に対する除算の商と剰余</title><link>https://okuzawats.com/blog/kotlin-arithmetic-operations-on-negative-value/</link><pubDate>Sun, 20 Feb 2022 22:05:00 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-arithmetic-operations-on-negative-value/</guid><description>AtCoder Beginner Contest 239のB問題を解いていてWAになり、解説を読んでいたら勉強になったのでメモ。負の値に対する除算の商と剰余について。
実は負数の除算はいくつか定義があり、プログラム言語によって定義が異なる という大きな問題があります。詳しい話は以下で説明しますが、例えば −24 を割られる数、 10 を割る数として整数除算した時の答えは言語によって −2 になったり −3 になったりします。 解説 - デンソークリエイトプログラミングコンテスト2022（AtCoder Beginner Contest 239）
Kotlinの（Int型やLong型に対する）除算のドキュメントを探すと、例えばInt型なら div 関数を見れば良さそうでしょうか（Kotlinの算術演算子は operator fun でオーバーロードされる）。
div - Kotlin Programming Language ここには、0に近い方に丸めると記載されてます。
Divides this value by the other value, truncating the result to an integer that is closer to zero.
例えば -1 に対して 2 で除算を行うと、（ -0.5 が 0 に近い方に丸められて） 0 となります。同様に -3 に対して 2 で除算を行うと、（ -1.5 が 0 に近い方に丸められて） -1 となります。</description></item><item><title>[Kotlin] はじめてのカリー化</title><link>https://okuzawats.com/blog/kotlin-currying/</link><pubDate>Thu, 10 Feb 2022 23:14:00 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-currying/</guid><description>カリー化とは、
複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること（あるいはその関数のこと）である。（Wikipediaより引用）
ということです。これがどういうことか、ということなんですが、まずはこんな感じの関数を考えます。
fun add(x: Int, y: Int): Int = x + y この関数は以下のように使えますね。
fun main() { val a = add(2, 4) println(a) // 6 } この関数をカリー化すると、以下のように書けるということだと思います。
fun main() { val a = add(2)(4) println(a) // 6 } 上記のKotlinのコードは、実際に動くコードです。ちょっと見ただけではなんで動くのか不思議なコードなんですが、わかってしまえば「なるほど」という感じです。
手始めに、以下のコードを考えます。Kotlinでは、関数は第一級オブジェクトなのでした。そのため、変数に関数を代入し、関数を呼び出すことができました。例えば以下のコードでは、関数 fun(int: Int): Int = int + 1 を代入した increment(int) を呼ぶと、 int の実引数に対して int + 1 を評価した結果が返ります。
fun main() { val increment: (Int) -&amp;gt; Int = fun(int: Int): Int = int + 1 println(increment(42)) // 43 } なお、上記のコードはラムダを用いて以下のように書くこともできます。</description></item><item><title>[Kotlin] nullオブジェクトパターン</title><link>https://okuzawats.com/blog/null-object-pattern/</link><pubDate>Mon, 07 Feb 2022 22:48:00 +0900</pubDate><guid>https://okuzawats.com/blog/null-object-pattern/</guid><description>Kotlinでnullオブジェクトパターンを実装する例です。こんな感じのinterfaceを考えます。
interface AwesomeRunnable { fun runSomething() } nullオブジェクトパターンを使わない場合 nullオブジェクトパターンを使わない場合は、こんな感じのifチェックを呼び出し側で毎回書かないといけません。対象の変数がnullなのかどうかということに興味がある場合は毎回nullチェックをするのもやぶさかではありません。
fun main() { val awesomeRunnable: AwesomeRunnable? = null if (awesomeRunnable != null) { awesomeRunnable.runSomething() } } nullオブジェクトパターンを使う場合 対象の変数がnullなのかどうかということに興味がない場合もあります。こういう場合はnullオブジェクトパターンの使用に一考の価値があります。
以下のコードは「何かを行う」関数を呼び出しています。
fun main() { val doSomethingRunnable: AwesomeRunnable = object : AwesomeRunnable { override fun runSomething() { println(&amp;#34;do something&amp;#34;) } } doSomethingRunnable.runSomething() } これに対して、以下のコードはnullオブジェクトパターンを用いた「何もしない」関数を呼び出しています。この場合は、インスタンスに対して runSomething 関数を呼び出しても、実際には何の処理も行われません12。
fun main(args: Array&amp;lt;String&amp;gt;) { val doNothingRunnable: AwesomeRunnable = object : AwesomeRunnable { override fun runSomething() { // NOP } } doNothingRunnable.</description></item><item><title>[Kotlin] underscore prefixに関するコーディング規約</title><link>https://okuzawats.com/blog/kotlin-underscore-prefix/</link><pubDate>Wed, 02 Feb 2022 22:39:00 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-underscore-prefix/</guid><description>Kotlinのunderscore prefixに関するコーディング規約について書きます。
KotlinのCoding Conventions Kotlin公式のCoding conventionsには、「If a class has two properties which are conceptually the same but one is part of a public API and another is an implementation detail, use an underscore as the prefix for the name of the private property」との記述があります。
つまり、外部にはinterfaceのみを公開し、privateなプロパティとしてその実装クラスのインスタンスを持っている場合です。この場合に、interfaceに対してunderscore prefix無しの名前を、実装クラスのインスタンスに対してunderscore prefix有りの名前をつけるとしています。
サンプルコードを以下に示します。 _awesomeStrings が実装クラスのインスタンス、 awesomeStrings がinterfaceです。interfaceに対してgetterを定義し、getterが実装クラスのインスタンスを返す、というKotlinでよく見る実装です。
class AwesomeClass { private val _awesomeStrings = mutableListOf&amp;lt;String&amp;gt;() val awesomeStrings: List&amp;lt;String&amp;gt; get() = _awesomeStrings } Kotlin公式のCoding Conventionsでは、上記のような場合に、privateプロパティにunderscore prefixを付けるとありました。他にはunderscore prefixに関する記述は見つけられませんでした。</description></item><item><title>「Advanced Android App Architecture」を読みました📚</title><link>https://okuzawats.com/blog/advanced-android-app-architecture/</link><pubDate>Mon, 31 Jan 2022 22:10:37 +0900</pubDate><guid>https://okuzawats.com/blog/advanced-android-app-architecture/</guid><description>「Advanced Android App Architecture」 (Cheng、Olivares (2019))を読みました。Androidアプリ開発におけるアーキテクチャの基礎がまとまっていてよい本でした。もう少し早く読んでおけばよかったな、と思います。あと、2019年に出版された書籍の内容がこんなにも早く古びてしまうのか、とも思いました（後述）。
何故、アーキテクチャを構築するのか アーキテクチャが何故重要なのかという点について、最初の方に議論があります。extensibleでmaintenableでtestableなアプリを作るためのベストプラクティスのパターンがアーキテクチャとしてまとまっているということ、アーキテクチャを構築することで関心事が分離されてユニットテストが書きやすくなってこれらの目的が達成されるということ、などが書かれています。
だいぶ端折りましたが、大筋としてはこんな感じのことが書かれていたと思います。
何故、AndroidアプリではMVCがうまくいかないのか アーキテクチャと聞くと真っ先に思い浮かぶのはMVCだと思うんですが、Androidアプリ開発だとMVCがうまく行かない理由が書いてありました。これを読んで思い出したのが @konifar さんの以下の記事です。もう7年も前の記事ですか。月日が経つのは早いものですね。
AndroidではMVCよりMVPの方がいいかもしれない - Konifar&amp;rsquo;s WIP Androidアプリ開発（プログラミング）初心者だった私は、この記事を何度何度も読みましたが、結局のところ、何でAndroidアプリ開発でMVCがうまくいかないのかは理解できませんでした。Advanced Android App Architectureにはこのあたりの話が詳しく書かれていてわかりやすいので、興味がある方は読んでみてください。
余談ですが、MVCという概念がなかなか理解できませんでした。自分は初心者の頃にAndroidだけをやっていた時期が長かったわけですが、振り返って考えると、Androidアプリ開発ではMVCはうまくいかないので、MVCで考えようとしてもうまくいかないわけですね。何故ならうまくいかないので。うまくいっていないものを見て理解しようとしても理解できないわけです。自分はRailsに触れた時にMVCってそういうことね、と閃きました。
MVP、MVVM MVCがうまくいかないとする一方で、Androidアプリ開発において、MVP / MVVMがその問題をどうやって解決しているのかという話が続きます。一言で超訳すると、MVCがActivity / Fragmentから責務を引き剥がせない一方で、MVP / MVVMだとActivity / Fragmentからうまく責務を引き剥がせるということでしょう。「何故、AndroidアプリではMVCがうまくいかないのか」の答えの一つになるかと思いますが、コードがActivity / Fragmentに書かれると途端に単体テストが困難になってしまうわけなんですよね。
MVP / MVVMにすることで、Activity / FragmentをViewとして振る舞わせ、関心事をActivity / Fragmentから分離することで、単体テストが突如として書きやすくなるということです。
VIPER、MVI さらに応用的なアーキテクチャとして、VIPERとMVIが紹介されています。VIPERはMVPに近いアーキテクチャで、RouterやInteractorといったレイヤが設けられたものだと理解しています。MVIもMVPに近い気はしますが、リアクティブ / ファンクショナルな考え方を取り入れているもののように思います。
これらの発展的なアーキテクチャが存在するにもかかわらず、MVPやMVVMがAndroidアプリのアーキテクチャとして語られることが多い（要出典）のはどういう理由か、ということを考えてみると、VIPERやMVIというアーキテクチャがMVPやMVVMに比べて重厚なんだろうなと思います。アプリやチームの規模がさほど大きくなければMVPやMVVMといったアーキテクチャで事が足り、そこから成長していくにつれ、抽象化層を増やし、関心事の分離を進めたアーキテクチャが欲しくなってくるのであろう、ということです。
Advanced Android App Architectureにも書かれていますが、穴を掘るのにスプーンを使うのかシャベルを使うのかは、掘る穴の大きさに依るわけです。
RxJava 冒頭に「2019年に出版された書籍の内容がこんなにも早く古びてしまうのか、とも思いました（後述）」と書いたわけですが、その理由がRxJavaです。本書では、多くのサンプルコードにRxJavaが使われています。2019年から2022年の間に、Kotlin Flowが存在感を増しました。今、同様の書籍を書くのであれば、きっとRxJavaよりもFlowを使ったサンプルコードが増えるのではないかと思います。この界隈、技術の移り変わりが激しいですね。
Reference Advanced Android App Architecture、Yun Cheng、Aldo Olivares（2019）、Yun Cheng &amp;amp; Aldo Olivares、raywenderlich.com AndroidではMVCよりMVPの方がいいかもしれない - Konifar&amp;rsquo;s WIP（最終アクセス日：2022年1月31日）</description></item><item><title>何故、依存性注入（DI）するのか</title><link>https://okuzawats.com/blog/dependency-injection/</link><pubDate>Mon, 24 Jan 2022 22:34:00 +0900</pubDate><guid>https://okuzawats.com/blog/dependency-injection/</guid><description>DI（Dependency Injection、依存性注入）とは何かということと、何故DIを行うのかということをここに書きます。
DI（Dependency Injection、依存性注入）とは DIは、理解してしまえばシンプルな考え方です。
まずはDIを行わないパターンのコードを見てみます。プログラミング言語はKotlinですが、DIの考え方についてはプログラミング言語によらないので、コードについては参考程度に考えてください。
以下のコードでは、AwesomeClassがSomeClassを持っています。SomeClassのインスタンスは、AwesomeClassが生成しています。Kotlinの入門書に出てきそうな、普通のコードです。
class AwesomeClass() { val someClass: SomeClass = SomeClass() } 次に、DIを行うパターンのコードを見てみます。あまりKotlinらしくないコードな気はしますが、Kotlinに慣れていない方への説明のためにこうしています。
class AwesomeClass constructor(val someClass: SomeClass) 1個目のパターンではクラスの内部でSomeClassのインスタンスを生成しているのに対して、2個目のパターンではAwesomeClassのコンストラクタでSomeClassのインスタンスを受け取っているのがわかるかと思います。1個目の例の「生成している」に対する2個目の例の「受け取っている」という表現がミソで、これを「SomeClassのインスタンスを外部から注入している」と考えるのがDIです。DIというのは、突き詰めるとこれだけのことです。
補足としては、上記2個目のパターンのようにコンストラクタでインスタンスを渡すことを「コンストラクタインジェクション（Constructor Injection）」と呼びます。その他に、外部からsetterを呼ぶことでインスタンスを渡す場合がありますが、このことは「セッターインジェクション（Setter Injection）」と呼びます。
DIとはこれだけのことなのですが、これだけのことが、プログラムを驚くほど柔軟にしてくれるのです。
DIの活用 こんな感じのinterfaceがあったとします。
interface Greetable { fun greet() } Greetableを使うHelloクラスを定義します。以下のHelloクラスは、Helloクラス自身がGreetableのインスタンスを生成しています。GreetableのインスタンスをDIしないパターンの実装です。
class Hello { private val greetable: Greetable = object : Greetable { override fun greet() { println(&amp;#34;Hello!&amp;#34;) } } fun greet() { greetable.greet() } } コードから想像がつくと思いますが、このクラスは以下のように用います。
fun main(args: Array&amp;lt;String&amp;gt;) { val hello = Hello() hello.</description></item><item><title>[Kotlin] 「何もしない」関数をいい感じに書きたい</title><link>https://okuzawats.com/blog/kotlin-no-operation-function/</link><pubDate>Sat, 22 Jan 2022 22:06:36 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-no-operation-function/</guid><description>Kotlinで「何もしない」関数をきれいに書きたい、というtrialです。
返り値を持たない関数 返り値を持たない関数は、通常、何らかの副作用を持つ処理を実行する関数です。例えば、特定の文字列を標準出力する関数などですね。以下のようなコードです。
fun doSomething() { println(&amp;#34;Hello World&amp;#34;) } Kotlinでは、このような関数は Unit 型を返します。Kotlinにおいては、「返り値を持たない関数」というのは、実は「返り値が Unit である関数」であると言えそうです。
fun main() { val value = doSomething() value is Unit // true } そのため、最初のサンプルコードに示した doSomething 関数の正確なシグネチャは以下のようになります。もちろん、返り値の型が Unit の場合には、通常関数の返り値の型を省略します。
fun doSomething(): Unit { println(&amp;#34;Hello World&amp;#34;) } 何もしない関数 ところで、何もしない関数を定義することがあります。
例えば、こういう interface があったとします。
interface AwesomeInterface { fun doSomething() } この interface を実装するけど、実際には何もしない、という場合があります（「nullオブジェクトパターン」というやつでしょうか）。こんな感じです。
fun main() { val awesome: AwesomeInterface = object : AwesomeInterface { override fun doSomething() { // NOP } } awesome.</description></item><item><title>[Kotlin] sealed classに親しむ</title><link>https://okuzawats.com/blog/kotlin-sealed-class/</link><pubDate>Thu, 20 Jan 2022 06:11:20 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-sealed-class/</guid><description>Kotlinの sealed class に親しんでいきます。
sealed class は、継承に制約を課す言語機能です。Kotlinのdocsによれば、 sealed class として定義されたクラスのサブクラスは、すべてコンパイル時に定義されている必要があります。
Sealed classes and interfaces represent restricted class hierarchies that provide more control over inheritance. All direct subclasses of a sealed class are known at compile time. No other subclasses may appear after a module with the sealed class is compiled. For example, third-party clients can&amp;rsquo;t extend your sealed class in their code. Thus, each instance of a sealed class has a type from a limited set that is known when this class is compiled.</description></item><item><title>[Android] SnackbarをBuilderパターンっぽく表示したい</title><link>https://okuzawats.com/blog/create-snackbar-like-builder-pattern/</link><pubDate>Mon, 10 Jan 2022 22:44:00 +0900</pubDate><guid>https://okuzawats.com/blog/create-snackbar-like-builder-pattern/</guid><description>2022年の今、遅きに失したというか今更感があるんですが&amp;hellip;。AndroidのSnackbarについて、テキストの色、背景色、アクションなどよく変更する設定をBuilderパターンっぽく書きたいなと思いまして、ちょっと試してみました、というのがこの記事です。
Builderクラスを作るパターン 最初に試したのが、SnackbarBuilderというクラスを作るパターン（ソースコードは後述します）。本当は Snackbar.Builder() というようにBuilderのコンストラクタを呼び出したかったのですが、Kotlinの文法ではいい感じにできなさそうです。そのため、SnackbarBuilderというクラスを作った、というのがこのパターンです。
SnackbarBuilder() .view(view) .text(&amp;#34;Awesome Text&amp;#34;) .textColor(R.color.text_color) .backgroundColor(R.color.background_color) .length(Snackbar.LENGTH_LONG) .action(&amp;#34;Action&amp;#34;) { /* TODO */ } .actionTextColor(R.color.text_color) .build() .show() 本来やりたかったことがだいたいできているんですが、viewとtextは必須にしたいです（lengthはデフォルト値を決めておけば必須でなくても良い）。SnackbarBuilderのコンストラクタでviewとtextを受け取るようにもできますが、それならば標準で用意されている Snackbar#make を使った方が筋が良さそうです。
ということで、没案となったSnackbarBuilderの（実験的な）ソースコードはこちらです。このコードブロックのあとに改善版を示しますので、改善版をすぐに見たい方は急いでスクロールしてください。
class SnackBarBuilder { private var view: View? = null private var string: String? = null @ColorRes private var textColor: Int? = null @ColorRes private var backgroundColor: Int? = null private var length: Int = Snackbar.LENGTH_SHORT private var actionString: String? = null private var action: ((View) -&amp;gt; Unit)?</description></item><item><title>[Android] OkHttpのMockWebServerを用いた、OkHttp + Retrofitのユニットテスト</title><link>https://okuzawats.com/blog/unit-testing-with-okhttp-mockwebserver/</link><pubDate>Mon, 10 Jan 2022 19:43:00 +0900</pubDate><guid>https://okuzawats.com/blog/unit-testing-with-okhttp-mockwebserver/</guid><description>OkHttpのMockWebServerを用いて、OkHttpとRetrofitを用いたRESTful APIアクセス部分のユニットテストを書いていきます。Android Developersに掲載されているアプリアーキテクチャガイドにおける、Data layerのRemoteDataSourceにあたる部分です。
Data layer | Android Developers 以下のサンプルコードのOkHttpとMockWebServerのバージョンは4.9.1、Retrofitのバージョンは2.9.0です（バージョンが少し古いのは、このサンプルコードを書いたのがしばらく前だったからです）。MockWebServerは testImplementation としています。
dependencies { implementation(&amp;#34;com.squareup.okhttp3:okhttp:4.9.1&amp;#34;) implementation(&amp;#34;com.squareup.retrofit2:retrofit:2.9.0&amp;#34;) implementation(&amp;#34;org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0&amp;#34;) implementation(&amp;#34;com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0&amp;#34;) testImplementation(&amp;#34;com.squareup.okhttp3:mockwebserver:4.9.1&amp;#34;) } MockWebServerを用いた、OkHttpとRetrofitを用いたRESTful APIアクセス部分のユニットテスト はじめにテストクラスの最終型を示します。サンプルコードの元になったのが自分の個人プロジェクトなので、趣味に走っているところがあります。それについては後段で説明を加えていきます。ポイントは、 @Before と @After でMockWebServerの起動と停止をおこなっていること、各テストケースでMockWebServerのレスポンスコードとレスポンスボディを enqueue していることになるでしょうか。
class RemoteDataSourceImplTest { private val mockWebServer = MockWebServer() private lateinit var target: RemoteDataSource @ExperimentalSerializationApi @Before fun setUp() { mockWebServer.start() target = RemoteDataSourceImpl( apiClient = TestApiClientProvider().provideWith(mockWebServer), ) } @After fun tearDown() { mockWebServer.shutdown() } @Test fun testGetAwesomeData_returnRightIfSuccess() = runBlocking { mockWebServer.enqueue(MockResponse().setResponseCode(200).setBody(dummyJson())) val actual = target.</description></item><item><title>[Android] UseCaseの実装</title><link>https://okuzawats.com/blog/implement-usecase-in-android/</link><pubDate>Wed, 05 Jan 2022 08:46:49 +0900</pubDate><guid>https://okuzawats.com/blog/implement-usecase-in-android/</guid><description>昨年（2021年）末にAndroid Developersに掲載されているアプリアーキテクチャガイドが更新されていましたね。更新版の内容で参考になったことの一つが、UseCaseの実装についてでした。Domain layerに関する以下のページです。
Domain layer | Android Developers ドメインとは何か、UseCaseとは何か、ということについては上記のリンクに譲ることにして、ここではその実装方法を見ていきたいと思います。
リンク先では、以下のようにUseCaseの invoke を実装することで、UseCaseがただ一つの機能のみを持っていることを強制できるようにしています。以下のサンプルコードは上記のリンク先のものです。
operator fun invoke(date: Date): String { return formatter.format(date) } 例えばコーディング規約などでUseCaseは invoke のみを実装していることを定めれば、一つのUseCaseがただ一つの機能のみを提供していることが保証できるようになるかと思います1。 invoke の引数と返り値は自由に定義できるので、実装上も不便はなさそうです。
UseCaseの命名は、アプリアーキテクチャガイドにあるように、「動詞＋名詞＋UseCase」というように命名します。例えば、LogOutUserUseCaseというような命名です。このように命名した場合は、インスタンスに対して logOutUserUseCase() というように書けば invoke に実装した処理を実行できます。この命名規則に従うことにより、このUseCaseが「ユーザーのログアウトを行う」という処理を実行していることがわかりやすくなると思います。
また、 invoke を実装する場合も、UseCaseのinterfaceを切ったり、 suspend を付けることもできます。例えばUseCaseの invoke でFlowを返す、という時にはこんな感じで実装できます。 @Inject はDaggerのアノテーションです。
interface LogOutUserUseCase { operator fun invoke(): Flow&amp;lt;LogOutState&amp;gt; } class LogOutUserUseCaseImpl @Inject constructor() : LogOutUserUseCase { override operator fun invoke(): Flow&amp;lt;LogOutState&amp;gt; = flow { // do something here } } invoke をsuspend funにする時はこんな感じで書けます。</description></item><item><title>2021年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2021/</link><pubDate>Sat, 25 Dec 2021 21:50:49 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2021/</guid><description>2021年も残すところわずかになりました。今年は、かれこれ18年ほど飼っていた飼い猫が亡くなり、ちょっと気持ちが沈んでいた時期もありましたが、いくつかの夢を叶えることができて全体的には良い年になりました。
本題に入る前の雑談なんですが&amp;hellip;。今年叶えることのできた夢のひとつについて書かせてください（もし時間がないという方がいらっしゃいましたら、以下の一段落をスキップしてください）。
今このブログを書いているのはUbuntuをインストールしたThinkPad X1 Carbonなんですが、いつかThinkPadにUbuntuを入れてメインマシンにしたい、という夢を数年前から持っており、それがついに叶いました。モバイルアプリエンジニアをやっているので、iOSのアプリを開発するにはMacが必要&amp;hellip;という縛りもあったりしてもうずっとMacを使っていたんですが、ソフトウェアエンジニアならLinuxぐらい使いこなせないと、みたいな気持ちや、iOSはもう個人でやることはあまりないんじゃないか、みたいな気持ちもあり、Macじゃなくていいのではないかという結論に至りました。それにしてもThinkPad X1 Carbonには本当にシビれました。端末を触っていて興奮したのはひさしぶりです。いやあ、本当に格好いい端末ですね。スペック的にはちょっと妥協しまして、メモリを32GB積もうと思ったんですが、そうすると3ヶ月以上待つことになりますよ、とサポートの人に言われまして、そこまではちょっと待てないし、お値段的なことも考えて、メモリだけは16GBで妥協しました。「お前にはまだ早い」と言われているような気持ちです。今後はより精進し、メモリ32Bが似合う人間になろうと思います。それにしても、Ubuntuをインストールするのがとても楽でした。前からこんなに楽でしたっけ？ちょっと歯応えがなかったですが、まあ無事にインストールできて元気に動いているので良かったです。いい時代になりましたね。
前置きが長くなってしまいましたが、始めていきます。去年のふりかえりはこちらです。
2020年のふりかえり 2021年1月 TDDのお勉強。 Hugoのテーマを自作していた。 Pythonで始める数学の冒険を読んだ。 Flutterをやっていた。 SwinjectでDIしていた。 UoPeople CS1102。 2021年2月 Flutterをやっていた。 GitHub Actionsで始めるFlutter CI入門を書いた。 UoPeople CS2203。 2021年3月 Flutterをやっていた。 Fast APIにHello WorldしてHerokuにデプロイしていた。 プロゲートのSQLをやっていた。 プロゲートのRailsをやっていた。 2021年4月 Haskellをやっていた。 書籍のレビューに参加させていただいた「ユニコーン企業のひみつ」が発売された。あとがきに名前が載った。 子どもが生まれた👶 2021年5月 FlutterでGraphQLをやっていた。 数独のソルバーを書いていた。 「カッコウはコンピュータに卵を生む」を読んだ。 2021年6月 「Goでつくるインタープリタ」をやっていた。 Haskellをやっていた。 KotlinのOptionとEitherを提供するライブラリを作っていた。 2021年7月 Rubyをやっていた。 Dockerを触っていた。 2021年8月 アルゴリズムの勉強をしていた。 Cracking the Coding Interviewをやっていた。 JavaScriptをやっていた。 2021年9月 執筆したJetpack ComposeによるAndroid MVVMアーキテクチャ入門が出版された🎉 2021年10月 RubyでFizzBuzzやライフゲームを作って遊んでいた。 「RubyでつくるRuby」をやっていた。 KotlinJSでPWAのマインスイーパーを作って遊んでいた。 2021年11月 Rubyのテンプレートリポジトリを作っていた。 書籍「クリーンアーキテクチャ」を読んでいた。 2021年12月 AWSとRailsと戯れていた。 その他 子どもが生まれた 今年の4月に子どもが生まれました。もう8ヶ月になります。子どもの成長は早いですね。自分も負けずに成長していかなければならないという気持ちを日々新たにしています。とりあえず元気に生まれてくれてよかったです。
技術書を書いた #技術書を一冊書き、ネクストパブリッシング様より発売いただきました。</description></item><item><title>[Android] GitHub ActionsでRoom / Realmの自動テスト</title><link>https://okuzawats.com/blog/room-or-realm-test-on-github-actions/</link><pubDate>Sat, 25 Dec 2021 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/room-or-realm-test-on-github-actions/</guid><description>この記事はフラー株式会社 Advent Calendar 2021の25日目の記事です。
フラー株式会社 Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 24日目の記事は @su8 さんによる「コンテナ遠洋航海 ~そこらへんの草でも食わせておけ プロセス分離の旅路 ~ - Qiita」でした。
Androidのローカルデータベースアクセスの自動テスト 2021年現在、Androidアプリ開発でローカルデータベース（SQLite）にデータを保存する場合は、Roomを使用することが多いと思います。数年前はRealmが流行っていたので、今もRealmを使用しているというプロジェクトも多いと思います。この記事では、RoomとRealmを用いたローカルデータベースアクセスの自動テストをGitHub Actionsで行う方法について書きます。
Roomのテスト Roomのテストは、Dao単位で行うことを想定します。Roomのインメモリデータベースを用いてテストを行います。エミュレータテストになるので、 androidTest にテストを書きます。
本記事の例では、Contextの取得に androidx.test.core.app.ApplicationProvider を、テストランナーとして androidx.test.ext.junit.runners.AndroidJUnit4 を使用します。
androidx.test.core.app | Android Developers AndroidJUnit4 | Android Developers setup と tearDown までは以下のように書けます。ここで、AwesomeDaoはRoomのDao、DatabaseはRoomDatabaseのサブクラスです。 setup でインメモリデータベースをビルドした後、テストのtargetとなるDaoを作ります。 tearDown では、データベースをcloseしています。
@RunWith(AndroidJUnit4::class) class AwesomeDaoTest { private lateinit var target: AwesomeDao private lateinit var database: Database @Before fun setup() { val context = ApplicationProvider.</description></item><item><title>依存関係逆転の原則</title><link>https://okuzawats.com/blog/dip/</link><pubDate>Sat, 04 Dec 2021 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/dip/</guid><description>この記事はフラー株式会社 Advent Calendar 2021の4日目の記事です。
フラー株式会社 Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 3日目の記事は @masaya82 さんによる「スクリーンリーダー対応の備忘録 - Qiita」でした。
依存関係逆転の原則 書籍「Clean Architecture 達人に学ぶソフトウェアの構造と設計」（以下、Clean Architectureと呼ぶ。本記事でのClean Architectureとは、本書のことを指す）を読んでいると、中盤に差し掛かったところでSOLID原則の話が出てきます。
SOLID原則の話の中で依存関係逆転の原則に触れられていますが、自分は長らくこの原則の意味がよく理解できませんでした。最近になって「もしかしてこういう意味なのかもしらん」というくらいの理解が得られてきましたのでテキストにしてみました、というのがこの記事です。
よく出てくる図 Clean Architectureには、こんな感じの図が出てきます。
Fig-1 よく出てくる図（Robert、p.105より筆者作成） まずはこの図をよく見て&amp;hellip;忘れます。
依存関係とは 依存関係逆転の原則とは、依存関係が逆転するという原則です。では、依存関係とはなんでしょうか。
難しく考える必要はありません。 A というモジュールから B というモジュールを使う、というだけのことを「 A が B に依存する」とお洒落に言い換えているだけです。
具体的なコードにするとこういう状況です。 A から B を使っているので、 A は B に依存している、という状況です。この「 A は B に依存している」という関係を、 A と B の依存関係と呼びます。依存関係とは、つまるところこれだけのことです。
package a; import b.B; public class A { public B b = new B(); public A() { b.</description></item><item><title>[Android] スクリーンショットを撮影するShell Script</title><link>https://okuzawats.com/blog/shellscript-to-take-a-screenshot-of-android-device/</link><pubDate>Tue, 15 Jun 2021 20:46:50 +0900</pubDate><guid>https://okuzawats.com/blog/shellscript-to-take-a-screenshot-of-android-device/</guid><description>Androidのスクリーンショットを撮影するShell Scriptです。adb を使える状態となっていることが前提です。ローカルの /sdcard/ にスクリーンショットを一時的に保存し、その後、カレントディレクトリに移動します。画像のフォーマットはPNGで、 {timestamp}.png というファイル名で保存します。
filename=`date &amp;#34;+%s&amp;#34;` adb shell screencap -p /sdcard/${filename}.png adb pull /sdcard/${filename}.png adb shell rm /sdcard/${filename}.png adb の -p というオプションは、スクリーンショットをPNGで撮影するためのものです。ドキュメントではこのオプションが省略されていたので、なくてもいいのかもしれません🤔
上記のスクリプトを screenshot.sh として保存し、実行します。
% sh screenshot.sh 以下の環境で動作を確認しました。
macOS Big Sur 11.4 zsh 5.8 References Android Debug Bridge (adb) | Android Developers (最終アクセス日：2021年6月15日)</description></item><item><title>Androidアプリ開発入門2020</title><link>https://okuzawats.com/blog/fuller-advent-calendar-2020/</link><pubDate>Fri, 25 Dec 2020 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/fuller-advent-calendar-2020/</guid><description>この記事はフラー Advent Calendar 2020 - Adventarの25日目の記事です。24日目の記事は、shmokmtによる「multipart をGoで扱ってみる」でした。
さて、元気にAndroidアプリ開発してますか。僕はしてます。
突然ですが、Androidアプリ開発をする上でつらいことの一つは、Androidアプリ開発の初心者にAndroidアプリ開発のことを教えることだと思ってます。まずはこの図を見てください。
Fig-1 Android in 2020 出典：来年に備えるために Android の知識を網羅する / Looking back on this Android year in preparation for next year. - Speaker Deck
こちらのスライドは、GDG DevFest Tokyo 2019にてwasabeefさんが発表されていたスライドです。Androidアプリ開発でよく使われるライブラリやらツールやらを示しています。多いですね。多いだけならいいですが、RxJavaやDagger2など、単体で多くの学習コストを払わないといけない人がカジュアルに混ざっていて困ります。
こちらのスライドは前述のとおり2019年のものですので、日進月歩のAndroidアプリ開発の世界ではちょっと内容が古いと言えます。このような混乱した状況がそう長く続くわけはありません。2020年の今はきっともっと楽になっているはずです。そうに違いない。
Fig-2 Android Developers right now 出典：(20) KeithYokomaさんはTwitterを使っています 「Android Developers right now 😂 https://t.co/vhQgjPJYqo」 / Twitter
こちらの画像（ツイート）が投稿されたのが2020年6月26日です。見て分かるとおり&amp;hellip;新たなラプトルが襲いかかってきており、状況は悪化しました。その他にも、Kotlin Android ExtensionsがDeprecatedになったり、Androidアプリエンジニアが退屈することはなさそうです。
Say Good-Bye to Kotlin Android Extensions - Speaker Deck Androidアプリ開発入門2020 学ばなくてはならない概念が多く、今からAndroidアプリ開発に入門するのはしんどそうです。が、これからAndroidアプリ開発に入門しなければならない人もいるでしょう。そういった方のために、これから学ぶならこの辺から&amp;hellip;という指針を自分なりに書いておきます。キーワードを散りばめておくので、検索しながら頑張ってください。大丈夫、Androidアプリ開発は楽しいから&amp;hellip;。
Kotlin Androidアプリ開発で使うプログラミング言語といえば、Kotlinですね。Java（Android Java）も使えますが、Kotlinを使った方が生産性が高いでしょう。公式でサポートされていることもあり、Kotlinを選ばない理由はあまり見当たりません。
この辺をやったり（自分はやったことないけど）、適当な入門書を読めばとりあえず書くことはできるでしょう。
Kotlin Bootcamp for Programmers | Training Courses もっとKotlinのことを詳しく学びたい人は、英語の電子書籍しかないと思いますが、Effective Kotlinを読むのがいいと思います。</description></item><item><title>社会人学生をやる上で気を付けていること</title><link>https://okuzawats.com/blog/advent-calendar-20201220/</link><pubDate>Sun, 20 Dec 2020 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/advent-calendar-20201220/</guid><description>本記事は社会人学生 Advent Calendar 2020の20日目です。19日目の昨日はid:fushiroyamaによる働きながら修士課程1年目を終えてでした。
米国University of the People（以下UoPeopleと呼ぶ）にてBachelor of Science in Computer Scienceコース（以下CSコースと呼ぶ）に所属している者です。普通にフルタイムで働いてます。UoPeopleのCSコースについて何か書こうと思ってましたが、同じUoPeopleのCSコースにおられるえんぴつさんが既に詳しく書かれていたので、目線を変えて書いてみます。
Computer Scienceの学位を取るために学費無料のオンライン大学UoPeopleに入ってもうすぐ1年 - えんぴつぶろぐ 2回目の社会人学生 実は、社会人学生をやるのは2回目です。1回目は、公共政策学の修士号を社会人夜間コースで取りました。27歳の時に入学し、29歳の時に修了しました。その後、歩いていた道が自分の目的地に通じていないことがわかって、別の道を探して歩き直しています。その過程で出会ったのがCSということです。
この1回目の社会人学生の時は、仕事が終わった後と土曜日に大学院に通い、講義を受け、講義のない日に課題をこなしていたものでした。修士論文を書いていた時は、夜な夜な秋葉原のルノアールでMacbook Airを叩いたものです。楽しかったです。
なんでこんなに大学にばかり通っているのかというと、やっていることを深く学ぶということがどうしても好きなんですね。今はソフトウェアのことをやっているので、CSの学位を取るというのは自分の中では自然なことでした。また、人生最初の大学であまり真面目に勉強をしなかったことに対する後悔もある気がします。
今はMOOCsとかでもCSの知識は得られると思うんですが、体系的な知識を得られたという自信を得るには、学位というのはちょうど良い目標になります。単位を一個一個取得していくという過程は、TODOリストに赤線を引いていくような快感があります。
この時は独身で、時間も有り余っていたので好きなだけ学問に励めて良かったです。
社会人学生をやる上で気を付けていること その後、僕は結婚して嫁がいます。嫁がいるということは、余暇を全て自分のために使うことができないということです（余暇という言葉がそういう家族のための時間を差し引いた後に残る自分のための時間という意味だったら、上の文はニュアンスを汲んで読んでいただければ幸いです）。
1回目の社会人学生の時は、上述の通り、独身で、一人暮らしで、パートナーもいなかったので、仕事と生活を成り立たせるための時間を差し引けば、全てを学問に捧げることができました（その全てを捧げた知は滅却しました）。今はそれをできないということです。これはフラストレーションとなりますが、これは人生における選択の問題で、人生における他のプライオリティーの高い事柄とのトレードオフです。自分は、自己を全て学問に捧げられるほどには、学問と仲良くなれませんでした。
つまり、仕事と家族と生活を成り立たせた上で、大学での学びを行う必要があるということです。仕事と家族と生活が土台で、大学での学びはそれらを全て成立させた上での「趣味」の領域です（自分にとっては）。趣味にそれなりの時間（UoPeopleでは、1教科あたり週15時間程度の学習時間の確保が推奨されています）を使うためには、仕事と家族と生活に対して貢献し、周囲の理解を得ることが重要です。
仕事と家庭と生活は、どれも優先順位が付けられません。「全部最優先」です。社会人学生をやる上では、これら最優先のことを毎日こなした上で、「趣味」の時間を確保することが求められます。これは、学問以外の趣味に情熱を持っている人と同じことであると思います。
簡単に言いましょう。仕事では他の人と同じかそれ以上にアウトプットし（自分がそうできているのかどうかはわかりませんが）、家庭は円満で家族の会話があり、家事をそつなくこなして家族に不便を感じさせてはいけません。その上で、余暇として学問をやるのです。
具体的には 具体的なアクションプランに落とし込みましょう。
朝早く起きてやる ちょっとした空き時間にやる 家族が風呂に入っている間にやる 家事がひと段落したタイミングで、家族がコタツに入ってみかんを食べながらテレビを観ている時にやる こうです。子供がいたらもう少し難しくなるでしょう。これはあくまで自分のやり方で、例えば家族が寝静まった後に一気にやる方が良い人もいるでしょう。自分は睡眠時間をしっかり確保しないと仕事も学問もパフォーマンスが出ないし、すぐに体調を崩してしまうので、睡眠時間を削らない方向に倒しています。
まとめ 社会人学生をやる上で気を付けていることは、仕事と家族と生活をこなし、周囲の理解を得た上で、余暇として学問を行うこと
以上、よろしくお願いします。
社会人学生 Advent Calendar 2020 21日目の明日は、トマト中毒のげんまいさんによる「コロナや異動で大変だった社会人D2のお話」です。</description></item><item><title>2020年のふりかえり</title><link>https://okuzawats.com/blog/looking-back-2020/</link><pubDate>Sun, 13 Dec 2020 21:21:42 +0900</pubDate><guid>https://okuzawats.com/blog/looking-back-2020/</guid><description>2020年1月 UdemyのFlutter Bootcamp（Angela先生の英語のやつ）をやった BLoCアーキテクチャの勉強をしていた Flutterでサンプルアプリを作っていた Firebaseの勉強をした 情報系の学位のことをちょっと調べた 確か2019年の年末にこの記事を読んだのがきっかけだったが、前々からじぶんで調べたりはしていたと思う 働きながら米国のコンピュータサイエンスの学士号を取得する、UoPeopleという選択肢 - Velocity 「情報系大学院入試への道」という本があったのを読んだ 情報系大学院入試への道 - yukikogamo - BOOTH not for meという感じだったが、参考にはなった DroidKaigi 2020の公式アプリにコントリビュートした 沖縄に旅行に行った 2020年2月 FlutterとFirebaseで趣味アプリを作っていた Firebase Authとか実装していたと思う Effective Kotlinを読んでKotlinに開眼した どこかにKotlinの記事をいくつか書いた気がする 水戸で開催されたもくもく会でKotlinについてのLTをした 社内の勉強会でKDocについて発表した Amazonプライムで無料で観られる映画をたくさん観た 2020年3月 RxJava for Android Developer（英語の本）を読んでRxJavaに開眼した Androidアプリ開発関係の同人誌を読み漁った GitHub Actionsをちょっとやった AtCoderの問題を解き始めた アメリカの大学のコンピュータサイエンスコースにapplyした 今更デスノートにハマっていた 2020年4月 アメリカの大学のコンピュータサイエンスコースの授業を受け始めた（英語のクラス） AtCoderのABCに参加してみた GitHub PagesにHugoで作った静的サイト（ブログ）を公開した ReactNativeをちょっと触ってみた 2020年5月 引き続き英語のクラスを受講した 引き続きReactNativeを触っていた ReactNativeに飽きて、Flutterでサンプルアプリを作っていた クリーンアーキテクチャを読んでいた どこかにDartの記事をいくつか書いた気がする 法務事務所に何回か行ったりしていた ジャッキーチェンの映画にハマっていた 福満しげゆきの漫画にハマっていた 2020年6月 英語のクラスの最終試験に合格して、入学を許可された（本科生？みたいな扱いにはなってない） 次のクラスが始まった N予備校でScalaをやっていた気がする 関数型プログラミングについていくつか読んだ 趣味のAndroidアプリ開発を始めた（設計とかライブラリとか試したいものがたくさんあったから） スターローンの映画にハマっていた 2020年7月 Google Certified Associate Android Developerになった 引き続き大学のクラスを受講した 引き続き趣味のAndroidアプリを開発した アカウントとか銀行口座とかクレジットカードとかの解約を頑張った 草津に旅行に行った 2020年8月 大学の2個目のクラスの最終試験を受けた YUMEMI.</description></item><item><title>[Dart] 基本的な文法</title><link>https://okuzawats.com/blog/dart-basic-syntax/</link><pubDate>Thu, 21 May 2020 21:47:08 +0900</pubDate><guid>https://okuzawats.com/blog/dart-basic-syntax/</guid><description>Dartの基本的な文法についてまとめます。
コンストラクタ Dartにおけるコンストラクタの最も原始的な構文は以下のように書けます。コンストラクタの引数としてString型のパラメータnameを受け取り、コンストラクタの本体の中でメンバ変数に代入しています。
class Dog { String name; Dog(String name) { this.name = name; } } 以下の構文では、コンストラクタの引数として受け取ったパラメータを直接メンバ変数に代入しています。この構文では、メンバ変数をfinalにすることができます。
class Dog { final String name; Dog(this.name); } 上記の構文を用いた場合にも、コンストラクタ本体を定義することができます。
class Dog { final String name; Dog(this.name) { print(name); } } Dog dog = Dog(&amp;#39;pochi&amp;#39;); // =&amp;gt; pochi また、this.nameの部分を{}で囲うと、コンストラクタ呼び出しを名前付き引数で行うことができます。
class Dog { final String name; Dog({this.name}); } Dog dog = Dog(name: &amp;#39;pochi&amp;#39;); Dartでは、コンストラクタのオーバーロードができません。その代わりに、Dartでは名前付きコンストラクタを定義することができます。
class Dog { String name; Dog(String name) { this.name = name; } Dog.</description></item><item><title>[Kotlin] 基本的な文法</title><link>https://okuzawats.com/blog/kotlin-basic-syntax/</link><pubDate>Sun, 23 Feb 2020 21:18:09 +0900</pubDate><guid>https://okuzawats.com/blog/kotlin-basic-syntax/</guid><description>Kotlinの基本型 Kotlinでは全てはオブジェクトであり、Javaにあるようなプリミティブはありません。以下に挙げるような基本的な型もオブジェクトとして扱われます。ただし、これらの基本的な型はコンパイル時にプリミティブへと最適化されるため、パフォーマンスが犠牲になることはありません（総称型の型パラメータで使われている場合など、一部例外はある）。
真偽値型（Boolean） Boolean型は真偽値を表し、値としてtrueまたはfalseをとります。trueは真、falseは偽を表します。Boolean型の変数は、以下のように宣言します。
val boolean: Boolean = true ※ 説明のため明示的に型を記載していますが、実際にコードを書く際は、型推論を用いて適宜型の記載を省略してください。
以下のように、何らかの評価結果を直接代入することも可能です。括弧は省略しても問題ありません。
val boolean: Boolean = (a &amp;gt; 0) 真偽値の判定には!を用います。not()を用いても同様の結果を得ることができます。個人的には、not()を使った方が可読性が高くて良いかな、と思います。
!boolean boolean.not() 数値型（Number） Kotlinでは、全ての数値型はNumberを親クラスに持ち、Number型で用意されている関数を使うことができます。また、数値型同士の暗黙的な型変換を行うことはできず、Number型で用意されているtoInt()、toDouble()などを用いて明示的に型変換を行います。
整数型 Kotlinで用意されている整数型は、Byte型、Short型、Int型、Long型があります。
型 ビット数 最小値 最大値 Byte 8 -128 127 Short 16 -32,768 32,767 Int 32 -2,147,483,648 2,147,483,647 Long 64 -9,223,372,036,854,775,808 9,223,372,036,854,775,807 基本はInt型 これらの数値型の中で、基本となるのはInt型になると思います。もちろん、要件次第で他の型を使うのは問題ありません。
数値に区切りを入れる 数値リテラルには、_を用いて区切りを入れることができます。_を用いて区切りを入れた場合、実際の数値には影響を与えません。
val int: Int = 1_000_000 // 1000000 Long型の宣言 Long型は、数値リテラルの後にLを付けて表します。
val long: Long = 0L Long型の変数は以下のように数値リテラルにLを付けずに宣言することも可能ですが、Long型を使いたい時に誤ってInt型を使用しないよう、明示的にLを付けた方が良いでしょう。
val long: Long = 0 浮動小数点型 Kotlinで用意されている浮動小数点型は、Float型とDouble型があります。整数を扱う整数型に対して、浮動小数点型は少数を扱います。</description></item><item><title>フラー株式会社に入社して5ヶ月が経った</title><link>https://okuzawats.com/blog/fuller-advent-calendar-20191225/</link><pubDate>Wed, 25 Dec 2019 08:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/fuller-advent-calendar-20191225/</guid><description>この記事は、フラー Advent Calendar 2019の25日目の記事です。
フラー Advent Calendar 2019 - Adventar こんにちは、okuzawatsです。今年の8月からフラー株式会社でAndroidアプリエンジニアとして働き始めて、はや5ヶ月が経ちました。日々、クライアントワークでアプリを作っています。楽しいです。
この記事では、フラー株式会社でAndroidアプリエンジニアとしてやっていること・やってきたことを書ける範囲で書いていこうと思います。よろしくお願いします。
フラー株式会社について スマートフォンアプリの会社です。詳しくはWebサイトを見てください。
フラー株式会社 若い人が多くて、自分みたいな年上は少数派です。でも、そのことで居心地が悪かったりとかは別にないです。
弊社の良い点は、
自由 アイデアはとりあえず言ってみると割と実現したりする 働きやすい 週一でリモートワークできる リモートワークの人がいる前提でみんな動いている コアタイム以外はどこで働いてもいい（らしい） 自分はやったことない 赤ちゃんを連れてきている人もいる 休みを取りやすい 入社してすぐ有給休暇みたいな休暇の枠をもらえる プロダクトのことを真剣に考えている人が多い 福利厚生で温泉に入れる 逆に悪い点は、
柏の葉キャンパスのランチ事情が良くない だいぶ改善されてきたらしい これからも改善されていきそうな感じはある 新潟オフィスはランチ事情がとても良いらしい みたいな感じです。
やっていること クライアントワークでAndroidアプリを作っています。
日々の仕事 Androidアプリを作っています。
今、自分は2つの案件を持っていて、機能の追加やメンテナンスをしています コードレビューをしたりされたりしています 優しい雰囲気でやっています 弊事業部にAndroidアプリエンジニアは私を含めて4人います 柏の葉キャンパスに2人、新潟に2人 みんな勉強熱心でとても良いです We are hiring 勉強会 全社的なエンジニアの勉強会 他の事業部のAndroidエンジニアを含めたAndroidの勉強会 私は関わっていないですが、新潟でモバイルアプリのカンファレンスとかも開催してます。登壇者すごい フラー新潟、新潟最大級のモバイルアプリカンファレンス「MOBILE CREW NIIGATA」を主催 | フラー株式会社 社外の勉強会への参加の費用は会社から補助が出ます やったこと 機能の追加やメンテナンスは当然として、その他にこんな感じのことを進めました。
アーキテクチャのないプロダクトにアーキテクチャを導入し始めた とある歴史の長いプロダクトがSmart UIっぽくなっており、だんだんメンテナンスがつらくなってきたので、MVPアーキテクチャを導入し始めた 画面が多いのでまだまだ終わらないです 誰か一緒にやってくれる人はいないかな？（チラッ） 同時にユニットテストを書き始めた。 テスト書きたいねとAndroidアプリエンジニア全員が思ってましたが、実際に書き始めたので偉い ちなみに弊事業部ではMVVMで作っているプロダクトが多いです。
バグバッシュ大会 先日の記事にも書きましたが、担当しているプロダクトのバグバッシュ大会を開催しました。詳しくは以下の記事をご覧ください。</description></item><item><title>フラー株式会社でもバグバッシュ大会をやってみた</title><link>https://okuzawats.com/blog/fuller-advent-calendar-20191211/</link><pubDate>Wed, 11 Dec 2019 08:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/fuller-advent-calendar-20191211/</guid><description>この記事は、フラー Advent Calendar 2019の11日目の記事です。10日目の昨日は@ManabuSekiによる「GitHub Actions SelfHostedを試してみた - Qiita」でした。
フラー Advent Calendar 2019 - Adventar こんにちは。okuzawatsです。フラー株式会社でAndroidアプリエンジニアをやっています。入社5ヶ月目です。現在、フラー株式会社で一緒にAndroidアプリのテストを書いてくれるAndroidエンジニアを個人的にwantedしています。よろしくお願いいたします。
バグバッシュ大会 ところで、バグバッシュ大会という概念をご存知でしょうか？わたくしは以下の記事を読んで知りました。一言で言うと、みんなで楽しくバグを見つける大会です。いいですね。
『B1グランプリ(Bug Bash)』を2時間やって細かいIssueを洗い出しました - Kyash Product Blog paymoチームでもバグバッシュ大会を開催してみたらめちゃくちゃ良かった | by kirimin | Medium わたくしもKyashチームをリスペクトしているので、いつかバグバッシュ大会を開催してみたいと思っていました。思っていたので、入社から3ヶ月くらいで最初のプロジェクトがひと段落したタイミングでカジュアルに提案したら開催する運びになりました。いい会社です。
やってみた ということでやってみました。対象はクライアントワークで作っている某アプリです。わたくしがフラー株式会社に入社して最初に担当することになったアプリになります。
とりあえずカジュアルに開催したかったので、カジュアルに参加できるように短めの時間で区切ってやりました。ルールは以下のような感じです。KyashさんとAnyPayさんのやり方を雑に真似ました。
バグバッシュ大会の参加者は、15分間、アプリを操作してバグを見つける 見つけたバグはSlackのチャンネルに投稿する 15分経過後、審査員がバグの影響範囲と致命性を考慮して点数を付ける 最も獲得点数の多かった人が優勝です 参加者は事業部のrandomチャンネルで募集して、飛び入り含めて6名の参加者が集まりました。加えて、不肖わたくしが審査員として参加しました。
結果、参加者6名・15分間のバグバッシュ大会で、iOS/Androidあわせて25個のバグが見つかりました。短い時間でも結構な数のバグが見つかるものですね&amp;hellip;。見つけたバグは、チケットを起票して、順次対応していきます。
感想 よかったです。バグを洗い出すことができたし、プロダクトに真剣に向き合う時間を作ることができたかなと思います。また、プロダクトに対する当事者意識を向上する効果もあった&amp;hellip;のかな。あったといいな。
バグバッシュ大会、繰り返し開催して、アプリのクオリティと品質意識を向上していきたいですね。他のアプリにも展開したいし、他の事業部からも参加者を募りたいです。
雑になりましたが、以上です。よろしくお願いします。
明日 誰が書くんだろうか。</description></item><item><title>[Android] DataBindingのBindingAdapterでGlideを使う</title><link>https://okuzawats.com/blog/glide-binding-adapter/</link><pubDate>Sat, 02 Nov 2019 21:54:58 +0900</pubDate><guid>https://okuzawats.com/blog/glide-binding-adapter/</guid><description>bindした時にGlideで画像を読み込んで欲しいのでBindingAdapterを実装します。
こういうデータクラスを作ります。もちろん他のプロパティがあっても大丈夫です。
data class Image( val uri: Uri ) レイアウトファイルを作ります。この例はRecyclerViewのアイテム用のレイアウトファイルです。先ほど作ったImageをvariableとしてバインドします。ImageViewに対して app:imageURI=&amp;quot;@{image.uri}&amp;quot; としてUriを渡します。
&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt; &amp;lt;layout xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34; xmlns:app=&amp;#34;http://schemas.android.com/apk/res-auto&amp;#34;&amp;gt; &amp;lt;data&amp;gt; &amp;lt;variable name=&amp;#34;image&amp;#34; type=&amp;#34;com.okuzawats.sampleapp.model.Image&amp;#34;/&amp;gt; &amp;lt;/data&amp;gt; &amp;lt;androidx.constraintlayout.widget.ConstraintLayout android:layout_width=&amp;#34;match_parent&amp;#34; android:layout_height=&amp;#34;wrap_content&amp;#34;&amp;gt; &amp;lt;ImageView android:id=&amp;#34;@+id/thumbnail&amp;#34; android:layout_width=&amp;#34;0dp&amp;#34; android:layout_height=&amp;#34;wrap_content&amp;#34; android:adjustViewBounds=&amp;#34;true&amp;#34; app:imageURI=&amp;#34;@{image.uri}&amp;#34; app:layout_constraintTop_toTopOf=&amp;#34;parent&amp;#34; app:layout_constraintStart_toStartOf=&amp;#34;parent&amp;#34; app:layout_constraintEnd_toStartOf=&amp;#34;@id/information&amp;#34;/&amp;gt; &amp;lt;LinearLayout android:id=&amp;#34;@+id/information&amp;#34; android:orientation=&amp;#34;vertical&amp;#34; android:layout_width=&amp;#34;0dp&amp;#34; android:layout_height=&amp;#34;wrap_content&amp;#34; app:layout_constraintTop_toTopOf=&amp;#34;parent&amp;#34; app:layout_constraintStart_toEndOf=&amp;#34;@id/thumbnail&amp;#34; app:layout_constraintEnd_toEndOf=&amp;#34;parent&amp;#34;&amp;gt; &amp;lt;!-- 略 --&amp;gt; &amp;lt;/LinearLayout&amp;gt; &amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt; &amp;lt;/layout&amp;gt; あとは適当なKotlinのファイルを作ってBindingAdapterを実装すればOKです。
@BindingAdapter(&amp;#34;imageURL&amp;#34;) fun ImageView.imageURI(uri: URI) { Glide.with(this) .load(uri) .into(this) }</description></item><item><title>[Android] RecyclerViewのLayoutManagerをxmlで指定する</title><link>https://okuzawats.com/blog/set-layoutmanager-in-xml/</link><pubDate>Sat, 26 Oct 2019 22:19:29 +0900</pubDate><guid>https://okuzawats.com/blog/set-layoutmanager-in-xml/</guid><description>RecyclerViewのLayoutManagerをKotlin / Javaのコードで指定しているケースを散見しますが、RecyclerViewのLayoutManagerはxml側でも定義できます。個人的には、LayoutManagerをxml側で定義した方がロジックとレイアウトを分離できて良いと感じています。
xml側でRecyclerViewのLayoutManagerを指定する方法は、以下のように app:layoutManager にLayoutManagerを指定します。
&amp;lt;androidx.recyclerview.widget.RecyclerView android:id=&amp;#34;@+id/recycler_view&amp;#34; android:layout_width=&amp;#34;match_parent&amp;#34; android:layout_height=&amp;#34;match_parent&amp;#34; app:layoutManager=&amp;#34;androidx.recyclerview.widget.LinearLayoutManager&amp;#34;/&amp;gt; 上記の例ではLayoutManagerにLinearLayoutManagerを指定しています。LinearLayoutManagerは、Orientationに縦か横のどちらかを指定できます。デフォルトのOrientationは縦ですので、特に指定がなければ縦に要素が並びます。LinearLayoutManagerのOrientationを明示的に指定するには、 orientation に vertical か horizontal を指定します。以下は vertical の例です。
&amp;lt;androidx.recyclerview.widget.RecyclerView android:id=&amp;#34;@+id/recycler_view&amp;#34; android:layout_width=&amp;#34;match_parent&amp;#34; android:layout_height=&amp;#34;match_parent&amp;#34; android:orientation=&amp;#34;vertical&amp;#34; app:layoutManager=&amp;#34;androidx.recyclerview.widget.LinearLayoutManager&amp;#34;/&amp;gt; LayoutManagerにGridLayoutManagerを指定する場合、一行あたりのセルの数は、 spanCount で指定できます。以下は spanCount として2を指定する例です。
&amp;lt;androidx.recyclerview.widget.RecyclerView android:id=&amp;#34;@+id/recycler_view&amp;#34; android:layout_width=&amp;#34;match_parent&amp;#34; android:layout_height=&amp;#34;match_parent&amp;#34; android:orientation=&amp;#34;vertical&amp;#34; app:spanCount=&amp;#34;2&amp;#34; app:layoutManager=&amp;#34;androidx.recyclerview.widget.GridLayoutManager&amp;#34;/&amp;gt;</description></item><item><title>[Android] Fragmentに値を渡す</title><link>https://okuzawats.com/blog/pass-value-to-fragment/</link><pubDate>Sat, 28 Sep 2019 21:41:10 +0900</pubDate><guid>https://okuzawats.com/blog/pass-value-to-fragment/</guid><description>Navigation Safe Argsを使わない場合と使う場合に分けて書きます。
Navigation Safe Argsを使わず、Fragmentに値を渡す Navigation Safe Argsを使わずにFragmentに値を渡す時は、Bundleを使って渡します。Fragmentのインスタンスを生成するstaticなメソッドを作るのは良くあるパターンだと思いますが、この時にFragmentのargumentsにBundleをセットします。
companion object { private const val ARG_TEXT = &amp;#34;arg_text&amp;#34; fun newInstance(text: String) = MainFragment() .apply { arguments = Bundle().apply { putString(ARG_TEXT, text) } } } Bundleから値を取り出す時は、 by lazy の中で取り出すのが個人的には気に入っています。
private val text: String by lazy { arguments?.getString(ARG_TEXT) ?: &amp;#34;&amp;#34; } 必ずFragmentに値が渡ってくるのであれば、 arguments の代わりに requireArguments が使えます。つまり、 requireArguments().getString(ARG_TEXT) というように書けます。
Navigation Safe Argsを使って値を渡す Navigation Safe Argsを使って値を渡す方法について以下に示します。
app/build.gradle に追加します。
apply plugin: &amp;#39;androidx.navigation.safeargs.kotlin&amp;#39; build.gradle にも追加します。
buildscript { // Navigation Safe Args def nav_version = &amp;#34;2.</description></item><item><title>[Android] ライブラリを使ってRuntime Permissionをリクエストする</title><link>https://okuzawats.com/blog/android-runtime-permission/</link><pubDate>Sat, 28 Sep 2019 21:41:10 +0900</pubDate><guid>https://okuzawats.com/blog/android-runtime-permission/</guid><description>ライブラリを使ってAndroidのRuntime Permissionをリクエストする方法をまとめます。Runtime Permissionをリクエストするために使える有名なライブラリには、PermissionsDispatcherとRxPermissionsがあります。
PermissionsDispatcherを用いたRuntime Permissionのリクエスト PermissionsDispatcherを使ってRuntime Permissionをリクエストする方法を示します。
permissions-dispatcher/PermissionsDispatcher: A declarative API to handle Android runtime permissions. とりあえずAndroidManifest.xmlにパーミッションを追加します。
&amp;lt;uses-permission android:name=&amp;#34;android.permission.READ_EXTERNAL_STORAGE&amp;#34;/&amp;gt; app/build.gradleにPermissionDispatcherとkaptを追加します。
apply plugin: &amp;#39;kotlin-kapt&amp;#39; dependencies { // PermissionDispatcher implementation &amp;#34;org.permissionsdispatcher:permissionsdispatcher:4.5.0&amp;#34; kapt &amp;#34;org.permissionsdispatcher:permissionsdispatcher-processor:4.5.0&amp;#34; } Fragmentに @RuntimePermissions というアノテーションを付けます。PermissionsDispatcherによって自動生成されるメソッドがあるので、以下、適宜ビルドしながら進めます。
@RuntimePermissions class StartFragment : Fragment() { // do something here } READ_EXTERNAL_STORAGE のパーミッションを得て、ギャラリーを表示するみたいな実装を想定して、パーミッション周りの処理を実装していきます。
/** Permission Dispatcher */ @NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE) fun showGallery() { findNavController().navigate(R.id.action_start_to_gallery) } @OnShowRationale(Manifest.permission.READ_EXTERNAL_STORAGE) fun onShowRationaleForReadExternalStorage(request: PermissionRequest) { showRationaleDialog( requireContext(), request, R.string.start_request_permission_for_read_external_storage ) } @OnPermissionDenied(Manifest.permission.READ_EXTERNAL_STORAGE) fun onReadExternalStorageDenied() { Toast.</description></item></channel></rss>