ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

読んだ: Android Pattern Cookbook マーケットで埋もれないための差別化戦略 / あんざいゆき 著

読みました。

Android Pattern Cookbook マーケットで埋もれないための差別化戦略

Android Pattern Cookbook マーケットで埋もれないための差別化戦略

あんざいゆき Cookbook シリーズ待望の第三弾、フルカラーでさらに見やすく分かりやすくなりました。 本書では、Android 4.4 (KitKat) 時点でのデザインガイドラインを踏まえ、アプリの UI を設計するうえでどのような選択肢があり、どうやって実装すればよいのかを解説していきます。 また、デザインガイドラインに沿いつつも、他との差別化のためにブランディングが重要になってきます。 実際のアプリを例にあげながら、ブランディング手法についても紹介します。

Impress Japan: Android Pattern Cookbook マーケットで埋もれないための差別化戦略

ということで、最新の Android アプリの標準的なアプリの UI パターンの紹介と実装方法の説明 *1 などが書かれています。 Google Play ストアで公開されている実際のアプリが例に挙げられており、図も豊富に使われているので、非常にわかりやすかったです。 実装方法の説明もあるのでその点はプログラマ向けですが、Android アプリの UI/UX を考える人ならプログラマ以外でも読めば参考になると思います。

本書で紹介されている UI のパターンがどのようなものかは、次のスライドを見るとわかりやすいかと思います。

本書を読んだあとは、Android Developers の Design の部 も読んでいきたいところです。

Kindle 版もあります。

*1:すべての UI パターンについて実装方法が書かれているわけではないです。

読んだ: CODE COMPLETE 第 2 版 下 — 完全なプログラミングを目指して

『CODE COMPLETE 第 2 版 下』 を読み終えました。

CODE COMPLETE 第2版 下

CODE COMPLETE 第2版 下

上巻と同じく、ソフトウェア開発の中の、詳細設計やコーディングとデバッグ単体テストなどの部分 (本書では 「コンストラクション」 と呼んでいる) に焦点を当てた書籍です。 コラボレーティブコンストラクションやプロジェクト管理といった話題もあるので、経験のあるプログラマでも上巻 (かなり初心者向け) よりは面白く読めると思います。 上巻の感想は次のブログ記事を参照してください。

全体的な感想

変数名がどうだの文の構造がどうだのといった初心者向けの話題が多かった上巻と違い、コラボレーティブコンストラクションやプロジェクト管理、工数見積もりといったコーディングよりも上位の層の話題が多く、いろいろと面白かったです。 上巻の内容は読むほどじゃないなー、と感じている人でも下巻は面白く読めるかもしれません。

下巻は 「一人でコードを書くことについては一人前だと思うけど、チームでの開発とかコンストラクション全体の管理といったところはまだこれからだなー」 というぐらいの人にちょうどいい内容だと思います。 広範な内容に触れている書籍で、書かれている内容は良いことだらけなので、広く浅く学ぶために読む本として適しているでしょう。

内容と細かな感想

第 5 部 コードの改良

第 20 章 ソフトウェアの品質
  • 単体テストや統合テストによる欠陥検出よりも、公式のコードレビューや大規模なベータテストによる欠陥検出の方が検出率が大きい。
  • ほとんどの研究では、欠陥検出のコストについても、テストよりもコードレビューの方が小さいという結果。
  • コードリーディングではインターフェイスの欠陥が多く発見され、機能テストでは制御の欠陥が多く発見された。
    • 複数の方法を組み合わせると効果的
  • ソフトウェア品質の原則: 品質を改善すると開発コストが低くなる。
    • デバッグとそれに伴う修正に多くの時間がかかっている。 品質を改善し、デバッグなどにかける時間を削減することで開発コストを小さくする。
  • コンストラクション時の品質保証も大事だし、コンストラクションの前段階での品質保証も大事。 適切にリソースを配分する。

実際のところ糞みたいな欠陥の調査に結構な時間が割かれるので、リリース前にちゃんとしたいし、して欲しい。

第 21 章 コラボレーティブコンストラクション

ペアプログラミングやコードレビューなど、複数人での共同作業について。 本書では、次のようなコラボレーティブコンストラクションが紹介されている。

  • ペアプログラミング: コーディング時に 2 人のプログラマがペアを組んで作業する。
    • コード品質の向上や、コーディング時間の短縮、若手の教育に効果的といった利点がある。
    • コーディング規約で議論する、とかしていると無駄だし、初心者同士が組んでも効果は薄いなど、気を付けるべきことはいろいろある。
  • 公式なインスペクション: 準備ののち、会議室に集まって仕様やコードのレビューを行う。
    • 役割として、モデレータ (進行役)、レビュア、仕様やコードの作成者、記録係、が必要。
    • 準備として、予めレビュアが仕様やコードについて読んで欠陥を洗い出しておく。
    • その後、会議室に集まり、設計をわかりやすく説明させたり、コードの流れを追ったりして、その中で欠陥を報告していく。
    • 記録係は報告された欠陥を記録する。 欠陥についての議論は、それが欠陥であるという認識に達した時点で終了すること。
    • 組織的にインスペクションを行い、インスペクションごとの記録を次に活かすことでより改善されていく。
  • ウォークスルー: 2 人以上で集まって設計やコードについて話し合う、というぐらいのざっくりした定義。
    • 参加者全員が予め設計やコードを読んでおく。
    • 参加者が集まり、作成者が進行役になって欠陥を検出していく。
    • 基本的には公式なインスペクションの方が費用対効果が高い。
  • コードリーディング: ソースコードを読み、欠陥を探す。 また、設計やスタイル、可読性、保守性、効率といった品質面について意見を述べる。
    • 一般的に 2 人以上のレビュアが、コードを読んで問題点を探す。
    • その後、作成者を進行役として会議をする。
    • インスペクションやウォークスルーと違い、コードを読むことに時間をかける。

ざっくりと利点などを書くと次のような感じ。

  • コラボレーティブ開発プラクティスは、テストよりも効果的に欠陥検出する傾向。
  • 検出しやすい欠陥の種類はテストによるものとは異なるので、テストと組み合わせる必要がある。
  • ペアプログラミングは一般にインスペクションと同程度のコストで同程度の品質のコードを生み出す。
  • 公式なインスペクションは、コード以外にも、要求、設計、テストケースなどの作業に利用可能。
  • ウォークスルーとコードリーディングは公式なインスペクションの代替。 時間を柔軟に使いやすい。

今はチームで簡易的なコードリーディングをやってるのだけど、やっぱりそれだけだと品質を十分に保証できないし、チームメンバーの教育効果という観点でも微妙なんだよなー。 簡易的にするなら仕様のウォークスルーとコードリーディング、って感じが良さそうかなぁと今のところは思ったりしてる。

22 章から 26 章

それぞれ 「デベロッパーテスト」、「デバッグ」、「リファクタリング」、「コードチューニング戦略」、「コードチューニングテクニック」 という章。 ここら辺は個人的にはそんなに学ぶことはなかった。

品質改善のプロセスにおいてテストは重要ではあるけれども、上にも書いたようにインスペクションとかコードレビューとかも重要だよね、とか。 デバッグは科学的に行おう (憶測で 「ここを変えたら良さそう」 と思ったところを変更して、実行してみて直ってるかどうか確かめる、みたいな試行錯誤はやめろ) とか、欠陥修正は場当たり的に行うのではなく本質的な変更をせよ、とか。 欠陥が多いクラスはそもそも設計が悪い可能性があるので、設計から見直して一から書きなおすということも検討せよとか。 パフォーマンスの改善をするなら測定は欠かせないし、環境 (コンパイラの違いとか) によってもパフォーマンスは違うということを意識せよ、とか。

確かにプログラミングの勉強を始めたころはこんな感じだったなー、と懐かしい感じ。 あと、意識してても 「時間がないから」 などの理由で場当たり的な修正をしてしまうってことはあると思うので、場当たり的な変更をするならするで後から適切に修正するための時間を確保するとか、そういう感じのことをせねばなー、と思ったり。

第 6 部 システムの考察

6 部は、プログラマがコードを書く、という部分ではなく、より上位 (コンストラクション全体の管理、というような) の作業について記述されている。

27 章 プログラムサイズが及ぼす影響

小規模なプロジェクトと比べると大規模なプロジェクトでは生産性が低くなるし行あたりの欠陥の数が多くなる、とか、参加するソフトウェアエンジニアが多くなるのでコミュニケーションのサポートが必要になる、などの話が書かれている。 ここら辺はソフトウェアエンジニアなら肌感覚でわかっていると思うけれど、実際の調査結果が提示されているので 「なるほどー」 という感じ。

28 章 コンストラクションの管理

ソフトウェア開発の管理のうち、特にコンストラクションに関連する部分について述べられている。 例えばコーディングの標準を設定することについてや、プロジェクトの構成管理、コンストラクションスケジュールの見積もり方法についてなど。

工数の見積もりはソフトウェア開発における難題の一つであって、プロジェクトの開始時点での見積もりでは実際の工数と数倍程度の開きがある見積もりをしてしまうこともよくある。 複数の方法で見積もりをして結果を比較することでより正確な見積もりを出すとか、定期的に見積もりをし直すことで当初の見積もりの誤りを修正していく、ということが書かれていた。

ソフトウェアエンジニアが自分の担当箇所の工数を見積もる際の難しさもさることながら、プロジェクト全体の工数見積もりはより一層難しいよなぁと最近思ってる。 プロジェクトのリーダーとエンジニアのやり取りの際に、意図している工数見積もりの見積もり対象が違っていたり (例えばサーバーサイドの実装の期間の見積もりをプロジェクトリーダーから依頼されて、エンジニア側は単純に設計とコーディングとテストの部分だけを見積もったけど、プロジェクトリーダーの意図としてはインフラの準備なども含めた工数を見積もって欲しかった) とか。 まあそこら辺はコミュニケーションの問題なのだけれど。

あとこの章で面白かったのが 「プログラマは人間である」 という節。 改めて言われるまでもないことだけど、プログラマの能力には個人差があって、コーディングやデバッグにかかる時間、それからソフトウェアの品質や実行速度に大きな差が付きうるとか、作業環境と生産性の間に強い因果関係がある、という話が書かれている。 良い環境で仕事したい。

29 章、30 章

29 章 「統合」 は、複数のソフトウェア部品を 1 つのシステムにまとめる作業について。 プロジェクトが小さければコンストラクションの最後に統合しても良いが、大きなプロジェクトであればインクリメンタルに統合していく方が効果的。 それから、毎日ビルドしてスモークテストすることで、品質低下のリスクを減らしたり、欠陥を発見した場合にいつ混入したのか調査しやすくできる。 ということが書かれていた。

30 章は 「プログラミングツール」 で、ソフトウェア開発に便利なツールがいろいろあるから使いましょう、という話。

第 7 部 ソフトウェア職人気質とは

7 部では、コーディングスタイルについてや、プログラマとしての心構え、といったことが書かれている。 読み物として結構面白かった。

32 章 読めばわかるコード

そもそも 『CODE COMPLETE』 を読もうと思ったのは、この章に書かれているコメントについて読みたかったから。 一年ぐらい前にコメント付けについて考えていたので、本書に書かれている内容が気になっていた。

で、読んでみてどうだったかというと、本書に書かれていたコメント付けについての思想は基本的に私が上の記事に書いた思想と同じだった。 (と思ってる。) 適切なコメント付けってそんな感じだよなー、という感想。 本書では、コメントの種類を次の 6 つに分けていた。

  • コードの繰り返し: コードの行うことを別の言葉で置き換えたもの。
  • コードの説明: 複雑なコードの説明など。
  • コードの目印: TODO コメントなど。
  • コードの概要: コードの要約。
  • コードの意図の説明
  • コード自体では表せない情報: 著作権表示とか設計上の注意点とか関連する仕様への参照とか。

完成されたコードに含まれていて構わないのは最後の 3 つである、と本書では書かれていた。 コードの説明を書くぐらいならリファクタリングして説明を不要にすべきではあるけれど、(何らかの制約で) リファクタリングできない場合は説明をコメントで書いておくと良い、とも書かれていた。

35 章 さらに情報を得るには

さらに学ぶための書籍の情報がいろいろ書かれていた。 特に興味深かったのが、著者が所属する会社である Construx のソフトウェア開発者がプロとしての地位を獲得するために消費しなければならない読書計画が掲載されていたこと。 本書自体がちょっと古い書籍なので今だとまた違っているかもしれないが、参考にはなると思う。 *1 良さそうな本はそのうち読みたい。

ちなみに本書自体は 「初級」 レベルのところに入っているので、このエントリ内の 「感想」 にも書いたように、本書はソフトウェア開発を始めて日が浅い人が読むべき本だと思う。

次のものが 「初級」 レベルより上に進むために読まなければならない本。

珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造

珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造

ソフトウエア開発 55の真実と10のウソ

ソフトウエア開発 55の真実と10のウソ

新訳 ソフトウェアプロジェクトサバイバルガイド

新訳 ソフトウェアプロジェクトサバイバルガイド

CODE COMPLETE 第2版 下

CODE COMPLETE 第2版 下

CODE COMPLETE 第2版 上

CODE COMPLETE 第2版 上

「実践」 レベルの地位を獲得するには次の書籍。

パターンによるソフトウェア構成管理 (IT Architects’ Archive―ソフトウェア開発の課題)

パターンによるソフトウェア構成管理 (IT Architects’ Archive―ソフトウェア開発の課題)

UML モデリングのエッセンス 第3版 (Object Oriented SELECTION)

UML モデリングのエッセンス 第3版 (Object Oriented SELECTION)

ソフトウエア・クリエイティビティ

ソフトウエア・クリエイティビティ

基本から学ぶソフトウェアテスト

基本から学ぶソフトウェアテスト

実践UML 第3版 オブジェクト指向分析設計と反復型開発入門

実践UML 第3版 オブジェクト指向分析設計と反復型開発入門

  • 作者: クレーグ・ラーマン,依田智夫,今野睦,依田光江
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2007/11/12
  • メディア: 単行本(ソフトカバー)
  • 購入: 8人 クリック: 179回
  • この商品を含むブログ (28件) を見る
ラピッドデベロップメント―効率的な開発を目指して (MicrosoftPRESS)

ラピッドデベロップメント―効率的な開発を目指して (MicrosoftPRESS)

ソフトウェア要求

ソフトウェア要求

「プロフェッショナル」 レベルについてはそれぞれの開発者に合わせて調整されるらしいが、下記のものは最低限必要っぽい。

Software Architecture in Practice (3rd Edition) (SEI Series in Software Engineering)

Software Architecture in Practice (3rd Edition) (SEI Series in Software Engineering)

リファクタリング―プログラムの体質改善テクニック (Object Technology Series)

リファクタリング―プログラムの体質改善テクニック (Object Technology Series)

  • 作者: マーチンファウラー,Martin Fowler,児玉公信,平澤章,友野晶夫,梅沢真史
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/05
  • メディア: 単行本
  • 購入: 94人 クリック: 3,091回
  • この商品を含むブログ (308件) を見る
オブジェクト指向における再利用のためのデザインパターン

オブジェクト指向における再利用のためのデザインパターン

Principles Of Software Engineering Management

Principles Of Software Engineering Management

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 方法論・実践 (IT Architects’Archive CLASSIC MODER)

オブジェクト指向入門 第2版 方法論・実践 (IT Architects’Archive CLASSIC MODER)

*1:この下では、本書に書かれている版より新しいものが出ている場合はそれを掲載している。 また、日本語版がある場合は日本語版のみを掲載している。

android.casual.test #2 に参加しました & LT しました

android.casual.test とは

android.casual.test は、Android のテストについてカジュアルに語るイベントです。 2 回目の開催となる今回は、4 月 3 日に行われました。

私は去年の 5 月ごろから Android アプリ開発の勉強を始めたのですが、なかなか社外の Android アプリ開発者と交流する機会がなく、交流したいなーという気持ちが高まっていたので参加してきました。

関西でもこういう感じのイベント (勉強会) をやりたいですね。

LT: はてなにおける Android アプリのソフトウェアテスト

私は 「はてなにおける Android アプリのソフトウェアテスト」 というタイトルで LT してきました。

はてなでは、最近 (ここ数ヶ月ぐらい) Android アプリのソフトウェアテストを行うようになりました。 どういう環境でテストを動かしているのかや、どういうテストを書くようにしているのかということを紹介し、また、テストを書く中で得られたノウハウなども紹介しました。 上のスライドで紹介しているのは、あくまで Gradle を使う場合の基本 (だと私は思ってます) のテスト手法です。 より実践的には、@rejasupotaro さんが紹介されていた RoboSpock を使うなどの方法もありますが、「まだテストを書いたことがないけどテストを書いた方が良さそう」 と感じている人 (あるいは組織) は、まずは導入として Android 端末 (実機 or エミュレータ) 上で動くオーソドックスなテストを書くところから始めてみると良いのではないでしょうか。

Android アプリのテストについての基本的な部分は、次の書籍も参考になります。

Androidアプリテスト技法

Androidアプリテスト技法

あくまで基本的な部分は、です。 初心者向けの本なのである程度テストを書ける人が読んでも得られるものは少ないでしょう。 次の感想記事も参考にしてください。

各 LT 感想

android.casual.test #2 での各 LT の感想です。

JUnit テストを 1 日やってみた」

@amyu_san さんの LT。

生まれて 20 年で初めてテストを書いた、ということだったけど、個人開発者で 「テストを書こう」 という意識を持ってるのがすごいなーと思った。

Gradle とかビルドシステム周りのことをあまり知らなくても IntelliJ でテストを書けるっぽく (ちゃんとわかってない) て、新しい発見 (気付き?) だった。 そういえば通常の Java プロジェクトを Eclipse で書くときは、GUI 上でぽちぽち操作してテスト用のクラスを作ったりテスト実行したりしてるので、Android アプリ開発でもできて当然という気はする。

「ノット・ジャバ・テスト」

@rejasupotaro さんによる LT。 「テストを書き続けられる環境を作ろう」 という話や、RobolectricSpockRoboSpock などの紹介。

今のうちの会社だと 「自然とテストを書けるような雰囲気 (?)」 みたいなのができていると思うけど、人が変わったり状況が変わったりするとテストを書くのが苦しいような状況にもなり得るので、テストを書くのが難しくない仕組みや環境づくりについてはいつも意識しておく必要があるなーと思った。

あと Spock というものや RoboSpock というものを初めて知った。 また今度使ってみよう。

「もしもの時にも安心な uiautomator の watcher 機能」

id:sumio_tym さんの LT。 uiautomator 自体は知っていたけど使ったことがないので興味深かった。 uiautomator は、他者が作ったアプリの UI テストもできるらしくて、アプリをまたぐような操作シナリオのテストなどに重宝するとのこと。

テスト中に NullPointerException が発生してエラーダイアログが表示された場合、(その挙動がテストシナリオで想定されていないものであれば) 後続のテストが全て失敗する、というようなことが起こるので、UiWatcher を使って監視する、という感じの話。 uiautomator を使うようなテストを書くことってなかなかないけど、今度使うようなことがあれば UiWatcher 周りも検討しようと思う。

「テストツール導入しようとしている話」

id:androhi さんの LT。 UI テストを実施するために Robolectric や各種 Gradle プラグインを試したりしたけどうまくいかず、結局 Espresso に落ち着いた、という話。

rejasupotaro さんもブログ記事に書かれてるけど、UI 周りのテストってどこまで自動化するか難しいなー、という気がする。 今のところ、個人的には Espresso を使った単体テスト (?) 程度に留めておくのが吉かなー、と思ってる。 (もちろん条件次第だけど、私が関わってる Android アプリでは、という感じ。)

「テストプラットフォームサービスの舞台裏」

@_touchy_ さんによる LT。 Android 端末の実機上での動作確認やテストをリモートで行うことができるサービスである Scirocco Cloud の舞台裏ということで、実機の運用に特有の苦労話などが紹介された。 実機の運用という全然知らない世界の話だったので、純粋に面白かった。

お疲れ様でした!

LT でも懇親会でもいろいろな話が聞けて有意義でした。 参加者の皆様お疲れ様でした!

Gradle プラグイン vc-android-sdk-manager 0.1.0 をリリースしました

リポジトリ

Git プロジェクトを GitHub 上に置いています。 Maven リポジトリGitHub 上に置いてあります。

このプラグインの目的

Android プロジェクトの Gradle ビルドスクリプトから Android SDKandroid update sdk を実行することです。

通常、既存の Android プロジェクトの開発に携わるとき、最初に次のようなことを行う必要があります。

  1. Android SDK (と IDE など) をダウンロードしてくる。 (まだしていない場合。)
  2. 既存の Android プロジェクトを手元に持ってくる。 (git clone とか。)
  3. Android SDK アップデートを行い、プロジェクトで必要なコンポーネントをダウンロードする。 (← これ)
  4. 開発を始める。

上の流れの中の、「これ」 と書かれた部分を自動化します。 (ビルドスクリプトの実行時に行うようにする。)

こういう問題を解決します

  • 手元でビルドする場合: Android SDK をインストールした後、Android SDK Manager でどのコンポーネントをインストールすればいいのかわかりづらい。
  • Jenkins で CI している場合: build.gradle の設定を書きかえた後、Jenkins 上でコンポーネントのインストールやバージョンアップをしないと Jenkins 上でのビルドに失敗するようになってしまう。

使い方

GitHub 上に Maven リポジトリを展開していますので、次のようにビルドスクリプトの依存を記述すれば使用できるようになります。 これはルートプロジェクトにのみ記述すればよいです。

buildscript {
    repositories {
        maven {
            url 'https://raw.githubusercontent.com/nobuoka/vc-gradle-android-sdk-manager/mvn-staging/m2repo/'
        }
    }
    dependencies {
        classpath 'info.vividcode.android.build:android-sdk-manager:0.1.+'
    }
}

次に、プラグインを使用するプロジェクトにプラグインを適用します。

apply plugin: 'vc-android-sdk-manager'

そうすると、そのプロジェクトでは androidSdkManager という変数が使えるようになります。 androidSdkManagerupdateSdkComponents メソッドや updateSdkPlatformAndBuildToolsAfterEvaluate メソッドを持っていて、次のように実行することで、Android SDKコンポーネントのインストールや更新を行います。 (まだ最新のリビジョンがインストールされていない場合。)

// このメソッド呼び出し時に、指定のコンポーネントをインストールする。
// コンポーネントの指定は、android update sdk コマンドの filter オプションに指定する値。
androidSdkManager.updateSdkComponents(['tools', 'platform-tools', 'extra-android-m2repository'])
// プロジェクトの評価後に 'build-tools-XXX' と 'android-XXX' をインストールする。
// プロジェクトの `android` extension に設定された値を見て、どのバージョンをインストールするか決定する。
androidSdkManager.updateSdkPlatformAndBuildToolsAfterEvaluate()

また、上のように実行すると、インストール時のライセンスに同意するかどうかの入力はユーザーに委ねますが、次のように acceptLicenseAutomatically オプションを使うと、自動でライセンスに同意します。 自動でライセンスに同意しますので、使用する際には自身の責任でもって使用してください。

androidSdkManager.updateSdkComponents(['tools', 'platform-tools'],
        acceptLicenseAutomatically: true)
androidSdkManager.updateSdkPlatformAndBuildToolsAfterEvaluate(
        acceptLicenseAutomatically: true)

必要な場合にのみ実行するようにする

Android SDK の更新は毎回のビルド時にする必要はないので、次のように指定の Gradle プロパティがある場合にのみ実行するようにすれば良いでしょう。

// `setupAndroidSdk` プロパティがある場合にのみ SDK の更新を行う。
if (project.hasProperty('setupAndroidSdk')) {
    apply plugin: 'vc-android-sdk-manager'
    androidSdkManager.updateSdkComponents(['tools', 'platform-tools'])
    androidSdkManager.updateSdkPlatformAndBuildToolsAfterEvaluate()
}

上のようにビルドスクリプトに書いておくと、通常時は Android SDK の更新は実行されず、次のように setupAndroidSdk プロパティを設定したときには Android SDK の更新が実行されます。

./gradlew -PsetupAndroidSdk assembleDebug

内部でやっていること

内部的には次のことを行います。

  1. android list sdk --extended を実行し、指定されたコンポーネントが含まれているかどうか確認する。
    • 含まれているもののみをカンマで連結し、文字列 filters 生成。
  2. android update sdk --no-ui --all --filter filters を実行し、コンポーネントをインストール。

ただし、build-tools に関しては、未インストールでも android list sdk の出力に現れないため、インストール先ディレクトリが存在するかどうかを見てインストール済みかどうか判別しています。

(android コマンドは Android SDK の tools ディレクトリに入っているものです。)

類似のプロジェクト

Cookpad による類似のプロジェクトがあります。

読んだ: CODE COMPLETE 第 2 版 上 — 完全なプログラミングを目指して

『CODE COMPLETE 第 2 版 上』 を読み終えました。

CODE COMPLETE 第2版 上

CODE COMPLETE 第2版 上

ソフトウェア開発の中の、詳細設計やコーディングとデバッグ単体テストなどの部分 (本書では 「コンストラクション」 と呼んでいる) に焦点を当てた書籍です。 プログラミングを行う際に気を付けるべきことがまとまった良い書籍です。 気を付けて当然のプラクティスばかり紹介されているという意味では常識集という感じでもあります。 プログラミングを初めて 1 年目や 2 年目の人が読むといろいろ学びがあるでしょう。

(追記) 下巻も読みました。 感想は下記記事。

内容紹介

上巻は 4 部構成です。

第 1 部 基礎を固める

第 1 部は、コンストラクションの中身に入るまでの準備などの話です。

まず第 1 章で、「ソフトウェアコンストラクション」 が表す範囲が、コーディングやデバッグ、詳細設計、統合といった 「実際にソフトウェアを作る部分」 であるという話や、それらについて論じることの重要性が述べられたりします。 上流工程が大事なのはそうですが、コンストラクションの過程も同様に大事ってことです。

2 章では、ソフトウェア開発においてメタファ (たとえ) を使用することが理解の促進につながることもあれば、悪いメタファを使用することで無用な混乱を招くこともある、という話がされます。 また、ソフトウェアコンストラクションのメタファとして、入念な準備が必要であることや、小規模なものと大規模なものの違いを理解しやすいということなどから、「建物の建築」 が適しているだろうと書かれています。 メタファに関しては、下手なメタファを用いることで混乱の要因になっている例が多々ありますので、良いメタファを用いることができるように気を付けたいですね。

3 章では、コンストラクションに入る前の準備 (上流工程) について論じられます。 アジャイル開発などの反復型の開発手法もありますが、どのような開発手法を採ろうともコンストラクションの前の準備は必要であり、課題定義や要求の策定といったことを適切に行わないと、コンストラクションの際に解決する課題を誤ったり、コンストラクション時の要求変更 (それはコンストラクション前に起こるよりもコストが大きい) が発生しやすくなったりします。 また、コンストラクションの準備として、アーキテクチャの設計も十分に行う必要があるとも書かれています。

4 章は 『コンストラクションの重要な決断』 ということで、プログラミングに使用する言語の選定や、プログラミング規約を定める、といった話が書かれています。 また、興味深い話としては、「プログラミング言語中で」 のプログラミングをするのではなく、「プログラミング言語中へ」 のプログラミングをせよ、というものがありました。

  • 「言語の中で」 のプログラミングというのは、使用している言語やツールがサポートしている構造に縛られて考えるということ。
  • 「言語の中へ」 のプログラミングというのは、(言語やツールに縛られない) 自分の考えを表現するために、使用している言語やツールでどのように実現するか決める、ということ。

わかりやすい例としては、「プライベートメソッドをサポートしていない言語を使っているときには、プライベートメソッドという概念を使用しない」 というのが 「中で」 のプログラミングで、「プライベートメソッドをサポートしていない言語では、メソッド名の命名規則でプライベートかどうかを表すことにする」 というのが 「中へ」 のプログラミングです。

第 2 部 高品質なコードの作成

第 2 部は、設計からクラス、ルーチンといった粒度での議論がなされます。 ここら辺の話を論じている本は他にもいろいろありますので、プログラミングのプラクティスがまとまっている本を読んだことがある人なら大体知ってる内容だと思います。

5 章はコンストラクションにおける設計の話です。 鉄則として、複雑さに対処するということが述べられ、単純さにこだわることが重要視されています。 モジュール間の依存関係を整理することは重要ですし、結合を疎にすることと凝縮度を大きくすることも重要です。 当然ですね。 設計はヒューリスティックな作業で、繰り返し行うことで設計が洗練されていく、ということが書かれていて、確かにそうだなー、という思いました。 (時間をかけたら設計ってよくなると思ってる。 もともとの能力次第だけど。) 特に価値の高い概念として、情報隠ぺいが紹介されていました。

6 章はクラスの作成についてで、クラスインターフェイスは一貫性のある抽象化を実現せよとか、「is a」 関係のモデリングを除き、通常は継承よりも包含の方が望ましいとか、そういう感じの話です。

7 章はルーチン (関数とかプロシージャ) の話です。 ルーチンの凝縮度を適切にせよ (1 つのルーチンで複数の機能を実現するのは多くの場合適切でない)、とか、名前を適切につけよ、とかですね。

8 章 『防御的プログラミング』 では、「無効な値が入力されたときに (通常の処理を行って) 無効な値を出力する」 というようなことをしないように入力値のチェックをするとか、例外処理を適切にするとか、そういう話がされます。 開発時には無効な値が検出されたらそれとわかるように大げさなエラーになるようにしておいてデバッグしやすくし、製品版では無効な入力に対してユーザーに適切なメッセージを出すように変更する、とか。

9 章では、擬似コードを書いてから実際のコードを書く、という手法 (擬似コードプログラミングプロセス; PPP) が紹介されました。 コードに落とし込む前に処理の流れを自然言語で記述することで、自分でも理解しやすく、他者にもレビューしてもらいやすい処理の流れを記述することができるなどの利点があります。 確かに複雑な処理だとこういう手法を採るのも良さそうですね。

第 3 部 変数

第 3 部では、変数について論じられます。 例えば以下のような感じです。

  • 変数のスコープをできるだけ狭くする。
  • 1 つの変数を複数の目的で使いまわさない。
  • 良い名前を付ける。 解読しやすく、目的がわかりやすいように。 8 から 20 文字程度の長さが良さそう。
  • 命名規則を上手に使う。 (全部大文字だと定数、とか。)
  • マジックナンバーを使わない。 (代わりに名前付き定数を使う。)
  • 必要がない限りグローバル変数を使わない。

ここら辺は、当たり前のこととしてやってくれって感じですよね。 他には、構造体やポインタのはまりどころを避けるためのプラクティスなどが書かれています。

第 4 部 ステートメント

第 4 部では、文について論じられます。 例えば以下のような感じです。

  • if 文などの条件が複雑になるようなら、ブール関数でカプセル化する。
  • 必要であればループの途中にループの出口を作る。 (A → B → A → B → A という感じの処理が必要な場合は、while (true) { A; if (...) break; B; } みたいなコードにする。)
  • goto 文はむやみに使うべきではないが、場合によっては良いものである。
  • 深いネストはルーチンの理解を妨げるので、ネストは浅くすべき。
  • 論理式を単純で読みやすいものにすること。

上には一部しか書いてませんが、第 3 部と同じで基本的には当たり前のこととしてコーディング時に気を付けてくれって感じのことがほとんどですね。

あと興味深いこととしては、18 章で述べられている 「テーブル駆動方式」 があります。 テーブル駆動方式というのは、論理文を使ってデータを取得したり処理の内容を決めたりする代わりに、テーブル (配列やマップ) を使って情報を参照するというものです。 具体的には、変数 month に何月かを表す数値 (1 月が 0 とする) が入っている場合に、その月の日数を得るために

int numDaysInMonth;
if (month == 0) {
    numDaysInMonth = 31;
} else if (month == 1) {
    ...

とするのではなく、

// 予め用意されているテーブル
int[] numDaysInMonthTable = { 31, 28, 31, ... };

int numDaysInMonth = numDaysInMonthTable[month];

みたいな感じでデータを取得する、というものです。 必要に応じて使う手ではありますが、こういう本で紹介されてるのが面白いなーと思いました。

感想

プログラマが経験的に得るであろう知見が良くまとまってるなーと思いました。 まともな環境で育った数年目のプログラマ (あるいはソフトウェアエンジニア) にとっては当たり前のことばかりなので読んでも面白くないと思いますが、1 年目から 2 年目にかけての新人が読むと得るものは多いと思います。 是非読みましょう。

数年目の人間でもここら辺の基礎がなってないプログラマも結構居ますので、そういう人間にも是非読んで欲しいですね。 (読ませたいですね。)

CODE COMPLETE 第2版 上

CODE COMPLETE 第2版 上

値段が高くて個人ではなかなか手が出しづらいですし、「そのうち買おう」 と思っているうちに経験を積んで本書の内容では物足りなくなってしまうような気がするので、チームに 1 冊とか会社に 1 冊とか置いてあると嬉しい気がします。

内容プレビュー

本書の内容の一部が web 上で公開されていますので、どういう内容なのか興味がある方は見てみると良いでしょう。