「食べる世界地図」を読んだ

食べる世界地図」を読みました。

食の変化とか、様々な地域での話とか。

レシピが載ってたり、歴史が載ってたり。色々と、食べ物という点から世界を覗くことができて面白いです。

「食の世界地図」を読んだ

食の世界地図を読んだ。

食の起源を、文献などから辿れるだけ辿って、そのルーツを垣間見ることができる文庫。その食の時代背景なども含めて見ることができる。

少し前に読み終わっていたのだけれど、メモ。

「わかる! ドメイン駆動設計~もちこちゃんの大冒険~」を読んだ

そういえば読もうと思って買っていた、わかる! ドメイン駆動設計~もちこちゃんの大冒険~を読んだ。

DDD本は読んでいて、ユビキタス言語やコンテキストの境界といった考え方は馴染みのあるものでした。が、少し前からAndroid界隈でDDDの話をよく耳にすることになったので、よくまとまっていると知人から聞いたので読んでみました。

実装よりな話よりも、コンテキストの共有というような範囲でよく話がまとまっていて読みやすかったです。

メモメモ。

「Swift実践入門」を読んだ

同僚や、知人が書かれていることもあり、Swift実践入門を読んでSwift言語への理解を深めてみました。

私個人のスキルでいうと、公式のThe Swift Programming Languageの2.1向けのものや、Functional Swiftとかの英語書籍を読んだり写経したりして簡単なSwiftプログラムを書いたり読んだりはできる感じです。iOSエンジニアとして会社でコードを書き続けているわけではないです。

内容は、うろ覚えだったり把握していなかったとところを補足することができ、言語自体の学びを整理することにとても役立つ書籍でした。iOS周辺の開発になると、こことは別にAPIへの理解も必要なのですが、私はそこはまだまだ足りていない…

全体的に、Swiftの様々な機能をどういう形で使うと良いのか、というところで参考になりました。以下、私が読んでいてメモしておきたかったところをメモしておきます。

2章

Swiftにおける範囲型、Optionalの話とか、復習になった。特に、 ?! のforce unwrapの話。実行時に評価されて無理やり値を取り出す ! と、 .none になる ? の話とか。

テストコードだと、例えばEarlGreyのようなやつだと実行時評価が必要なことが多く、 ! を使ったりしていた。けれど、Swiftの理想でいうとやっぱり ! は思想に反する(実行時にしか評価されないし、クラッシュするし)のでやぱりよくないのだなーと。

as? によるダウンキャストや as! as? によるアップキャストの話もちらほら。

3章

switch の制御で以下のようにかける形、Erlang/Elixirを学んでいたので自然な感じだった。こういうの書き始めると、Androidの世界にも時折欲しいと思う時がある…

switch a / 2 {
case let b where b < 2:
    print("lower than 2")
case let b where b >= 2:
    print("more than or equal to 2")
default:
    print("no")
}

繰り返しの for ... in ... {} は使ったこともあるのですが、 case 使う場合もinを支えたのですね。把握していなかった…

for value in 1...4 { print("\(value)") }
for case let (2, value) in [(1, "a"), (2, "b"), (3, "c")] { print("\(value)") }

switchの中、 break を置くことはよくやることですね。Javaとかやっていると。これ、breakしないと多くの場合は次々と case を実行していくのですが、swiftでは明示的に fallthrough を与えないといけないのですね。

let a = 10

switch a / 2 {
case let b:
    print("first")             // "first\n"
    fallthrough
case 5:
    print("after fallthrough") // "after fallthrough\n"
    break
    print("after break")
default:
    print("no")
}

あと、 breakやcontinueの遷移先を制御するために label をつけることができるとは知らなかった…

4章

@discardableResultがあったのですね。 _ = someMethods で処理を書いていた。どのみち、使わない、使わなくて良いことを明示するスタイル。

Swift、以下のような形で副作用をもたせた書き方もできたのですね。JavaとかRubyといったオブジェクト指向の書き方では書いていたのですが、Swift(のstructとか)Elixirとかみたいな関数型をメインで触っていると、こういうことが頭から離れることが多い…

func add(_ x: Int, _ y: Int, _ a: inout Int) {
    a += x + y
}

var a: Int = 10
add(10, 10, &a)
a // 30

7章

protocolの話。
Swiftはprotocol oriented programmingと言われるように、このprotocolが重要になります。
associatedTypeによる、protocolでは抽象的な文字を定義しつつ、具体的な型はそれを受け継いだstructなどで定義する。それらの定義は明示しなくとも類推されて補完されもします。個人的には、Swiftは明記によって安全性を表現しているので、推論ばかりに頼りたくない(明示していきたい)なーとも思います。

protocol SomeProtocol {
    associatedtype AssociatedType

    var value: AssociatedType { get }
    func someMethod(value: AssociatedType) -> AssociatedType
}

struct SomeStruct : SomeProtocol {
    typealias AssociatedType = Int

    var value: AssociatedType
    func someMethod(value: AssociatedType) -> AssociatedType {
        return 1
    }
}

struct SomeStruct2 : SomeProtocol {
    var value: Int
    func someMethod(value: Int) -> Int {
        return 1
    }
}

struct SomeStruct3 : SomeProtocol {
    struct AssociatedType {}

    var value: AssociatedType
    func someMethod(value: AssociatedType) -> AssociatedType {
        return AssociatedType()
    }
}

指定する型とそれを受け継いだサブクラスの話。
それら。

where 句によるprotocolに対するextensionの制御の話。例えば、以下だとWebContentの型を持ったやつ。

protocol Item {
    var name: String { get }
}

protocol WebContent {
    var url: String { get }
}

extension Item where Self : WebContent {
    var description: String {
        return "hi"
    }
}

struct EBook: Item, WebContent {
    let name: String
    let url: String
}

struct Book: Item {
    let name: String
}

いくつかの標準ライブラリに付与されるプロトロル。

8章

Any関数はダウンキャストが必要。

if let int = something as? Int {
  // something
} else {
  // else
}

なので、ジェネリクス良いですね。

10章

参照型のクラスと、値型の構造体。その選定基準がとても為になった。

クラスは参照型なので、新しくインスタンスを作ってもそのインスタンスに保持されている値はつながっている。つまるところ、副作用がたくさんあるということですね。一方、structはimmutableに物事を扱うことが可能、と。

class Temp {
    var c: Double = 0
}

class Country {
    var temp: Temp

    init(temp: Temp) {
        self.temp = temp
    }
}

let t = Temp()
t.c = 25
let c1 = Country(temp: t)
t.c = 40
let c2 = Country(temp: t)

c1.temp.c
c2.temp.c

そのため、クラスは何らかのライフサイクルに添いたいところや参照を共有する必要がある。

11章

OptionalとImplicitlyUnwrappedOptionalの使い分けの話。どう使うべきか、という話。
クロージャを使うときの、キャプチャリストと weak / unowned の違い、その使い分けも。

let closure = { [weak object1, unowned object2] () -> Void in
    print(object1)
    print(object2)
}

第11章の話の中では、いくつかのデザインパターンの説明も出て来た。これは通知をやり取りするための手法として。その中にObserverパターンがあった。

import Foundation

class Poster {
    static let notificationName = Notification.Name("SomeNotification")

    func post() {
        NotificationCenter.default.post(name: Notification.Name("a"), object: nil)
    }
}

class Observer {
    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNotification(_:)),
            name: Notification.Name("a"),
            object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc
    func handleNotification(_ notification: Notification) {
        print("I got a message")
    }
}

var observer = Observer()
let poster = Poster()
poster.post()

12章

非同期処理の話。GCD(Grand Central Dispatch)をSwiftから使う話とか。DispatchQueueの話。Foundationに含まれる Operationを使った話も。
ここら辺はやっぱり複雑なところになるので、中身を調べた上でなにかのライブラリに乗っかりたいですね。

13章

Resultによるエラー処理の話などだった。enumで定義した成功/エラーを switch を使って分けていく方法ですね。

enum Result<T, Error> {
    case success(T)
    case failure(Error)
}

Erlang/Elixirの {:ok, xxx}{:error, xxx} に対するパターンマッチなどん処理を思い浮かべました。
毎回 switch を書く必要もありますが、ここは将来パターンマッチ含まれるともっとErlang/Elixirに似た記述になりそうですね。

do-catchはまとめてエラー処理を描きたいときなど

エラー処理の選定

エラー処理を行う --no--> リリース時のプログラムの
    |                        終了を許容 ----no--> assert
   yes                             `----yes---> fatalError(_:)
    |
エラー処理の詳細が必要 ----------------------no--> Optional
    |
   yes
    |
同期処理 ----------------------------------no--> Result
    `------------------------------------yes-->  do-catch

まとめ

この書籍、やっぱり良いですね。Swiftに関して、言語仕様ではなく経験からどう使うと良いのか、という話がまとまっている。
これを読む/読まないで知識のつけ方が大きく変わりそう。

ありがとうございました。

「消極性デザイン宣言」を読んで、approchiabilityという言葉を知った

消極性デザイン宣言-消極的な人よ、声を上げよ。……いや、上げなくてよい。」を読みました。

シャイハック。
私自身、ここに書かれていたように消極的な人間で、V字タイプな人。少人数や大人数だとある程度大丈夫だけれど、微妙な人数になると「・・・」となるような。

そんな人たちのコミュニケーションの話から入り、だんだんとモチベーション、インタラクションの話へと内容が移ってきます。個人的に面白かったのは、approchiabilityという考え方と、モチベーションの話。ここのモチベーションはやる気を出していく話ではなく、やる気がわかないことを前提とした(意識の低い)モチベーションの話なので、疲れず良かったです。

人間は基本的には消極的

これが基本的な立ち位置でした。消極的なので、自然にできるようにどうデザインするかとか、そういう話になってきます。

機能があることではなく、”機能する”こと、その機能を使おうとしやすいことなど。

Usability と Approachability

Usabilityは使いやすさとしてよく言われます。品質の話になるときや、人間工学の話、デザインの話といったように様々なところで出てきます。一方、Approachabilityという言葉は私が把握している限りでは初耳でした。

Usabilityとの対比としては、Usabilityが製品/サービスそのものの使いやすさを評価の対象とするのに対して、Approachiablityは対象となる製品/サービスがどれだけ”使おうとしやすいか”を評価しようとしている、という感じ。なので、製品/サービスのその周辺から連続した出来事を評価の対象に加えるという感じでしょうか。モバイル端末などの使いやすさとしてはこういった連続性に言及しているものもちらほら見ますが、そこに焦点を当てたものがこの”Approachiablity”という感覚を受けました。

使おうとしやすさ、行為の切り替え・接続、やめやすさ、いかに無理せず自然とできるか。

特別ではなく日常に溶け込む系のサービスとか製品ではこういう考え方って大事なデザインの話になりそうですね。

そういえば、インタラクションデザインにも言及していて、その中であったモチベーションの設計は色々なところで関係しそうな感じがしました。

締め

こういう書籍は時折読みますが、Approchiabilityという言葉の定義はなかなか良い発見でした。

2016年に新たに読んだ書籍群を振り返って

昨年の 2015年に新たに読んだ書籍群を振り返って に続き、読んでBlogに書いたものをピックアップ。

昨年と比較すると、読んだ書籍の本数は減った。これは翻訳だったり発表、OSSメンテといったことに手を出していることもあり、時間の傾け方が変わった感じ。あと、有名どころは読み終えて大体は新しい書籍中心になったからというのもありそう。ただ、Webの記事やプログラミング言語でも書籍を元にしないものをトライする量も増えてきたので、入力の量は案外どっこいどっこいなのかもしれない。

よかったものは★をつける。

programming language

Erlang

Development

Software Test / Organization

Educational

Design

Other

「レガシーソフトウェアー改善ガイド」を読んだ

レガシーソフトウェア改善ガイドを読みました。英語では “Re-Enginnering Legacy Software” なので、”改善ガイド”とするには少し内容とタイトルに乖離があるかもしれないですね。

この書籍は、最近のアーキテクチャ(モノリシック/SOA/Microservices)や言語特性の変化、CI/CD環境など含め最近の流れを踏襲した上でレガシーソフトウェアを継続してより改善できる形にするためのtipsが書かれています。そのため、開発環境/スタイル/設計などを含んだ全体的な改善の話が書かれていました。レガシーコード改善ガイドをベースとすると、テストできない、継続して機能を壊さず改善することが困難なソフトウェアがレガシーなものになります。

ソフトウェア開発においてしばしば言われるように、コードがレガシーとなる原因の多くは人に関係します。それは例えばサービス開発におけるサービスの成長フェーズに対するビジネスの要求に応えるためのものだったりとします。そのため、レガシーに見えるものも実はサービス開発を試行錯誤しながら行い、成長した結果と言える面もあるかと思います。(ここは組織の力に依存しそうですが)

この書籍の中で、コード品質の指標として欠陥密度に対する言及があります。それがCoverityによる2012年のLinuxカーネルの静的解析において、コード1000行あたりの欠陥密度(defect density)が0.66/klocであるというところでした。これは純粋に興味深い内容でした。OSSとして多くの意見が入る可能性の高い成果物が、高品質なコードであると示される珍しいものではないでしょうか。そしてそれを支える為に重視しているものがコードレビュー。これにより、低品質なコードの混入を防ぐ、知識の共有とそれらのサポートといった保守も含めた知見を共有しているとあります。

開発の中では心理的な障壁は最善の仕事を効率よく行うことを妨げます。この中に”恐れ”があります。この恐れは未知なものに対峙するときに顕著になため、未知な領域(コード)に足を踏み入れながら、未知を克服していくことが必要となってきます。このような未知を克服しながら進むことを”調査的リファクタリング”(exploratory refactoring)と呼んでいました。

Exploratory Testingが探索的テストと呼ばれる一方、こちらは調査的と表現しているのですが英語をベースとするとどちらも似たようなことをしながら”中身を理解し明らかにしていく”ことを達成しようとしているのですね。

ちなみに、これらを補助するためのツールなども書かれています。

理想のシステムは、コードの品質を開発者の努力なしに自動的に監視し、その情報をチームメンバ全員が利用できるようにするもの。意識しない、努力しないというのは大事で、それが系として組み込まれている状態を指します。やはり意識によって改善するには人は確率的に誤りをおかしすぎてしまいますからね。

そういえばミカドメソッドの話が出てました。これは修正したい対象の周辺をグラフに落としていって、見通しをよくした上で優先順位を定めて取り組むというものです。言及されるとは思いませんでした。

あとはmutableなものをimmutableにしていくところも言及されていました。これは最近の関数型言語に対する風潮もありますね。これは複雑奇怪なビジネスロジックをテスト可能にし、確認可能な状態で単純化することに貢献する説明の箇所で出てきています。

当然、テストの自動化にも言及していました。単体テストを自動化することに対しては誰もが納得することだろうという前提のもと。私もここ数年でモバイルアプリの領域でやってきたことなのですが、 とくに自動化を必要とするのがUIテストの領域 と書かれています。ここがちゃんとできているところはおそらくできていないところに比べて多くの利益を享受しています。不具合の見つからないごく一部の自動化されたUIテストではなく、不具合をちゃんと見つけてくれる多数の自動化されたUIテスト。個人的に、それは特にGUIが差別的な要素になる可能性の大きな特にモバイルアプリの領域では差が出てくるところだと考えています。(ここら辺は今度機会があるのでそこで話すかもしれません)

英語ではこれらのように書かれています。

– Unit tests are not a silver bullet.
– One area that cries out for automation is UI testing.

(4.3.2. Regression testing without unit tests)

他に面白かったところは、Webアプリのアーキテクチャの話でモノリス/SOA/Microservicesなどを比較しているところでした。特に、組織面での利点まで言及していたところが個人的には好印象でした。アーキテクチャはやはり組織に影響を及ぼしあうので。その中で、やはり情報伝達はモノリスがオーバーヘッドが小さく、個々の独立性が高まると従来の情報伝達はオーバーヘッドが大きくなるところが印象的。(いっていること自体は至極真っ当)

まとめ

主な対象はWebサーバアプリでしたが、これはモバイルアプリにも多く転用できるものでした。実際、私がモバイルの領域でやっていたものはこの書籍における改善案の方針として言及されているものが多かったです。

refactoring/rewriteしながら継続して価値を出しているサービスをより継続して開発し続けることができるように取り組んでいきたいですね。