未分類

...now browsing by category

 

「オブジェクト指向プログラミング入門」ティモシイ・A・バッド/ピアソン・エデュケーション

月曜日, 6月 24th, 2019

私が最初に読んだオプジェクト指向プログラミングの本です。よくあるオブジェクト指向の本は、特定の言語やフレームワークに特定して語られるものが多く、偏った見方のものが多いと思います。しかし、この本では、4つの言語を使用し、それぞれの言語で書かれたサンプルコードを提示したり、同じ機能に対してそれぞの言語のアプローチの違いや、実装の違いなどの解説しています。特定の言語やシステムに偏ることなく、オブジェクト指向本来の概念や思想について書かれている良書です。

最初に買ったのは第一版で、出版されたのは1995年でした。その当時 Java はまだ生まれたばかりなので、サンプルコードの言語に入っていませんでした。その後、第二版を買ったのですが、Objective-Pascal が外され、代わりに Java が入ってきました。原書は第三版が出ているようですが、まだ日本語訳は出ていないようです。

Firebase

金曜日, 6月 7th, 2019

中島聡さんのメルマガを購読していますが、Google I/O に参加した成果として、Firebase の良さを知ったとのこと。
今までは、サーバー側のシステムを作るのに、別の人に頼まないといけなかったのが、自分でサクサクと作れてしまうらしい。

早速、以下のようなゲームのサービスを作って見たとのこと。
https://tourneygames.com/play/be7eMqKVNtydv0mJrUah

  • React.js + Firebase で開発
  • NoSQL Database(firestore) + サーバーレス(firebase + Cloud Functions)上に作られている。
  • ユーザー数が100万人に増えても勝手にスケールしてくれる。そんなスケーラブルなサービスが、Firebase だとあっさりと作れてしまう。

今まで、自分で作るアプリはサーバーが不要なものだけだったけど、これでサーバー側もいけるかも。

ちょっと調べてみよう。

「現場で役立つシステム設計の原則」増田亨/技術評論社

水曜日, 5月 29th, 2019

借りて読んだので、気になった箇所を簡単にまとめました。
基本的に Web アプリケーション向けの内容なのですが、随所に他のシステムでも役に立ちそうな Tips が入ってます。

第1章 小さくまとめて分かりやすくする

ValueObject

  • 電話番号なら String ではなく TelephoneNumber 型など業務専用の型を作って、長さなどの制限する。
  • 完全コンストラクタ(初期化時に値が決まり、以降変更できない。Immutable なもの)にすると、コードを読む時に値の変化を気にする必要がなくなる。
  • 金額と数量はどちらも Int で表せるが、それぞれ独自の型を作っておくと誤った代入をコンパイル時に検出できる。
  • typedef のような型を別名で定義するのと比べて、コンパイル時に上記のような型誤りの検出が可能。

コレクションオブジェクト

  • List や Array のプロパティを1つだけ持ち、それの操作メソッドを持つ。
  • immutable にする
  • 操作の結果は、同じ型のコレクションオブジェクトとして返す。

第2章 場合分けのロジックを整理する

  • 早期リターンを使って if 文の else 節を排除すると、コードの見通しが良くなる。
  • インターフェイス宣言(Swift なら protocol)と区分ごとの専用クラスを組み合わせて、多態(Polymorphism)を実現する。
  • 区分オブジェクト:列挙型を使って業務で扱う区分の一覧を宣言する。

第3章 業務ロジックをわかりやすく整理する

  • ドメインモデルに業務データと業務ロジックを集める。
  • ドメインモデルは画面やデータベースの都合から独立させる。

第4章 ドメインモデルの考え方で設定する

  • 業務の関心ごとはヒト/モノ/コトで整理できる。
  • コトの整理を軸にする。
  • ドメインモデル設計のインプットは、業務の言葉の正しい理解。

第5章 アプリケーション機能を組み立てる

  • 業務的な判断、加工、計算の詳細はドメインモデルに集約する。
  • データベース操作はリポジトリクラスに持っていく。
  • サービスクラスは小さく分ける。
  • 小さく分ける基本は、まず登録系のサービスと参照系のサービスを分ける。
  • 小さく分けたサービスを組み立てる。
  • 必要に応じて、基本的なサービスクラスを組み合わせた複合サービスを提供するシナリオクラスを作る。

第6章 データベースの設計とドメインオブジェクト

  • カラム名は省略形にしない。
  • 全てのカラムに NOT NULL 制約を付ける。
  • NULL を入れる必要があるカラムが出てきたら、別テーブルに分けるサイン。
  • 一意性制約でデータの重複を防ぐ。
  • 外部キー制約でテーブル間の関係を明確にする。
  • 記録のタイミングが異なるデータはテーブルを分ける(NULLを防ぐ)。
  • UPDATE を使わずに、DELETE, INSERT を使う(訂正の記録を残せる)。
  • データベースの設計変更でカラムを追加する場合は、テーブルを追加して、そこに入れる。
    • 元のテーブルがそのまま利用できる。
    • 追加したカラムに NULL を入れなくて済む。
  • 基本は「コト」を記録するテーブルを作る。
  • 「コト」によって変化する「状態」などの派生的なでデータは別テーブルに記録する。
  • 銀行口座で例えるなら、「コト」は入金、出勤、「状態」は残高。
  • ただし、この方法では厳密な即時性には対応できない。
  • オブジェクトとテーブルは似てくるが、兼用させないで、違うものとして明示的にマッピングする。

第7章 画面とドメインオブジェクトの設計を連動させる

  • タスクごとに画面を分ける。
  • 画面表示ロジックに業務ロジックを書かない。
  • 画面表示で if 文を使っている場合は、その条件判断をドメインオブジェクトに移動する(特定の条件で赤字で表示、0件の場合の特別表示、など)。

第8章 アプリケーション間の連携

  • POST と PUT の違い。POST は識別子を指定しないで登録し、レスポンスで識別子を返す。PUT は識別子を指定して登録する。
  • Web API は、修正を繰り返すうちに何でも出来る肥大化した API になりがちだが、それだど修正や拡張が難しくなる。
  • 修正や拡張を重視する場合、組み合わせて使用するような適度な大きさの API に分割する(ただし、あまり細かくすると組み合わせるのが大変になる)。
  • 初期段階では単純な API だけを提供し、フィードバックを得ながら追加、変更して行く。
  • 単純な API は、登録と参照を分ける、リソースの単位を分ける、ことに気をつける。

第9章 オブジェクト指向の開発プロセス

  • 更新すべきドキュメント:利用者向けのドキュメント、画面や帳票、データベース仕様
  • 個人的にはAPI仕様も加えた方が良いかも

第10章 オブジェクト指向設計の学び方と教え方

  • 過激なコーディング規則
    1. 1つのメソッドにつきインデントは1段階までにすること(good)
    2. else 句を利用しないこと(good)
    3. 全てのプリミティブ型と文字列をラップすること
    4. 1行につきドットは1つまでにすること(too much)
    5. 名前を省略しないこと(good)
    6. 全てのエンティティを小さくすること
    7. 1つのクラスにつきインスタンス変数は2つまでにすること(too much)
    8. ファーストクラスコレクションを使用すること(good)
    9. getter、setter、ブロパティを使用しないこと(too much)
  • ↑ 「過激」と銘打っているだけあって、さすがにやり過ぎだと思う項目が・・・

参考文献の中で読んでみたいと思ったもの

アルゴリズムは使用するプログラミング言語に引きずられる

火曜日, 10月 9th, 2018

某所で5分以内にプログラムを考えるという課題がありました。

最初にプログラミング言語を選択するのですが、最近は swift ばかりなので swift を選択しました。

その後に出たお題は「文字列を逆順にする。ただし、プログラミング言語にある逆順にする命令などは使わないこと」というものです。

そこで私の思考は、以下のようになりました。

  1. 文字列は文字の配列
  2. 配列を処理するならイテレータ
  3. 先頭から文字をとっていき、新しい配列の先頭にインサートしていけばいける

IDEなしだったので、仮想コードですが、以下のような感じに書きました。

let src = "hogemoge"
var dest = ""

for char in src {
dest.insert(0, char)
}

しかし、帰りの電車で、C言語ならもっと効率良くできることに気づきました。

  1. 最初と最後の文字をスワップ
  2. 最初+1と最後-1の文字をスワップ
  3. 上記の処理を「文字数 / 2」回繰り返す
unsinged char *src = "hogemoge";
unsigned char swap;

for (int i = 0, int last = strlen(src) - 1; i < strlen(src) / 2; i++, last--, ) {
swap = src[i]
src[i] = src[last]
src[last] = swap
}

なぜ、思いつかなかったのだろうと考えたのですが、最初に言語を選択していたため、そこでよく使う手法に囚われていたのです。swift だと文字列を文字単位で扱うことはあまりないため、配列として処理しようと考えてしまったのです。それに対してC言語はビット単位やバイト単位で扱うことが多いので、すんなりと効率が良いアルゴリズムに導かれたのでした。

「オブジェクト指向プログラミング入門 第二版 (ティモシイ・A. バッド)」の「1.2 言語と思考」にも、APLのプログラマが行列のソートで解決した話が載っていましたが、まさにその通りのことを身を以て体験したのでした。

Bose QuietComfort 35 wireless headphones

月曜日, 5月 1st, 2017

以前、通勤中に使っていたBluetooth接続のヘッドホンが壊れたため、新しいのを買いました。

考慮した点

絶対条件として、まずはBluetooth接続であること。以前のもBlutoothだったのですが、コードがないのは本当に便利で、身にしみていました。もうコード付きには戻れません。

次にオーバーイヤータイプであること。純正のようなイヤフォンだと、私の場合、耳からポロポロ落ちてしまうのです。また、前使っていたのはオンイヤータイプだったのですが、時々耳からずれることがありました。そんな中、家で使っている有線のオーバーイヤータイプのヘッドフォンは、外れたりずれたりする事がなく、とても具合が良かったのです。なので、今回は通勤用のヘッドフォンもオーバーイヤータイプにすることにしました。

それとノイズキャンセリング機能です。以前からとても興味があったのですが、購入したことはありませんでした。なので、今回はこれにこだわりました。

競合との比較

そうなるとSONYのMDR-1000Xも気になる所です。こちらも上記の条件を備えていて、値段も同じくらいです。

QuietComfortが良いところは、操作がシンプルであることです。電源のON/OFFはスライドスイッチで、曲のスキップとバックはダブルクリックとトリプルクリックです。対してMDR-1000Xは、電源のON/OFFは長押しで、曲のスキップとバックは専用のボタンです。実は前使っていたヘッドフォンはSONY製なのですが、この点が使いづらかったのです。専用のボタンが多い方が使いやすそうに思えるのですが、確かに目で見て操作する分にはボタンが多い方が使いやすいのですが、目で見ずに手探りで操作する場合はボタンが少ない方が分かり易いのです。特に曲のスキップとバックは、音量ボタンと取りちがえることが時々あり、またスキップとバックどちらが上のボタンだったかもよく忘れていました。

一方でMDR-1000Xの方が優れている点は、ペアリング記憶台数が8台であることです。対してQuietComfortは2台です。音源機器の数が多い場合は大変魅了的なのですが、とりあえずiPhoneとMacにつながればOKだったので、そのあたりは気にしませんでた。

良かった点

何と言ってもノイズキャンセリングがとても優秀です。基本的に通勤電車の中で使っているのですが、在来線が新幹線並みの静かさになります。これを付けていると時間が立つのが早く感じます。やはり静かなのは落ち着くみたいで、通勤がとても楽になりました。音によるストレスって以外に大きかったんですね。

また、静かになった分、音楽も小さな音でも充分に聞こえるので、耳に負担が少ないです。でも車内アナウンスはちゃんと聞こえます。車内アナウンスも音が小さくはなるのですが、走行音ほどは減衰されません。ノイズキャンセリングを周波数によって分けているみたいです。感覚としては新幹線の車内アナウンスくらいの音量です。

いまいちな所

大きくて重い点です。これはオーバーイヤータイプを選んだ時点で覚悟していたのですが、やはり荷物になります。重量はケース込みで400gくらいで、通勤カバンの中ではそれなりの容量と重さです。

あと、静かすぎるので歩きながら使うのは危険です。車が背後から来ても気づかないレベルです。ノイズキャンセリングがOFFにできないのもそれに拍車をかけます。じっと座っていられる環境でしか使ってません。