builderscon tokyo 2017にコアスタッフとして参加しました!

instagram.com

builderscon tokyo 2017にコアスタッフとして参加しました。

builderscon.io

セッションに関しての感想はどなたかが書いていると思うので、運営として行ったことを書きます。

そもそも何故コアスタッフとして参加しようとしたか

同僚兼運営を行っている@morizoooさんに勢いのある若者枠?として誘われたのがきっかけです。 と言うのは半分本気で半分冗談ww

コアスタッフ用のSlackチームでは勢いのあるアイコンを登録してましたが、いざスタッフMTGで牧さんと初めて会った際にイメージ違うと言われましたね😂😂😂

f:id:to4iki:20170807000134p:plain

真面目な事言うと、

  • カンファレンスを企画や運営として関わり作り上げていくのは単純に楽しそう
  • 主催している勉強会にノウハウを持って帰りたい
  • 自分が変わるきっかけが欲しかった

と思い参加を決めました!

スタッフとして何をしたか

  • スポンサー様から頂いたロゴの管理/サイトへの掲載
  • ボランティアスタッフの取りまとめ、リーダー的なポジション
  • 当日はほぼほぼメインホールにいました
  • iOSアプリの作成(これは勝手にやりました)

スポンサーロゴの掲載について

まずは頂いたロゴをレギュレーションに沿って加工します。
最初は作業に時間がかかったのですが、慣れてくると楽しいものですね、Illustrator力、Sketch力が上がりました💪

次にスポンサー登録です。こちらに関してはほとんどが自動化されているので脳が死んでてもできました(自動化最高!)

blog.builderscon.io

ボランティアスタッフの取りまとめについて

事前にtwitterブログで告知を行い、たくさんの方にご協力して頂きました。本当にありがとうございます!!!
monmonさんはじめ当日スタッフの皆様から学ぶことはとても多かったです!

他にはスタッフ向けのあんちょこ作成を行いました。

  • 受付スタッフのやる事リスト
  • 部屋スタッフのやる事リスト(録画確認、タイムキーパー作業など)
  • 司会のカンペ
  • その他(ゴミ捨てや避難経路など)

などを記載したチートシートですね。これを大量に印刷し配りました(任意でスマホにもPDFのインストールもしてもらいました)。
現在はbuilderscon tokyo 2017に特化した内容となっていますが、汎用化できる余地はあるので修正し公開したいなと思っています。

当日の作業について

前夜祭では名札を配ったりノベルティを渡すなどの受付補助を行いました。
当初はPeatixのチケット番号と紐づいた名札番号を目グレップで探しあて渡すというなんとも原始的な作業で効率が悪かったので、机の位置を調整しつつ直接参加者の方に探して頂くなど工夫をしました。
イデアを出しトラブル対応や効率化を測るのもスタッフとしての醍醐味ですね。(目グレップ中はSlackを開く余裕が無かったので、炎上案件しゃもじで増員を求めたかった。。)


2, 3日目はメインホールのリーダーを@uessy_akrさんと一緒にやりました。
1番の懸念点だった同時通訳用のレシーバーの紛失ですが、こちら全て回収できました!!!!!!!
回収の協力をしてくださった参加者のみなさんありがとうございます!
大きなトラブルもなくこなせたかなーと思いつつも、2階席がある部屋での質問者へのマイク受け渡し係の配置や、照明の調整など次回改善すべき課題も見つかったなといったところです。

iOSアプリ作成

speakerdeck.com

うん。とにかくブラックでしたw

反省/改善点は山のようにありますが、とにかくアイデアを出しからの着工が遅すぎた!これに尽きる。

また、ネタバレになるので書けないのですがビルコン開催中にさらなるトラブルがありました。。
やはり炎上案件しゃもじが欲しかったですねー
詳細はiOSDC Japan 2017で報告したいと思います!

設計に関してのエントリがあるので興味のある方は是非!
to4iki.hatenablog.jp

参加してみて

クロージングスピーチでの牧さんの言葉がとても印象的でした、

技術力は当然だが、「つながり」が重要なのではないか
カンファレンスでは自分の「安全地帯」の外に飛び出そう

今回スタッフ&アプリ作成をしているのもあって声を書けてもらうことが多かったです。
自分からも懇親会などで多くの人に声をかけ話すことができました。
普段属するコミュニティを越え全く異なるバックグラウンドの人たちと話すこともできました。

スタッフという立場でもありますが、いち参加者として新たなつながりを持てたのはbuildersconのおかげです。

控えめにいって最高でした!

来年があれば、自分で企画考えたり、スピーカー側に行けたらいいな!

最後に

builderscon iOSアプリの簡易説明

先日、スタッフとして関わっているbuildersconiOSアプリをリリースしました!🎉

blog.builderscon.io

本エントリで簡易的なアプリの紹介と構成の紹介を行います。

機能

f:id:to4iki:20170801233159p:plain

  • 複数日付のタイムテーブル表示
  • フロアマップ表示
  • QRコードーリーダーの搭載

構成/設計

project構成はDDDのレイヤードアーキテクチャをベースに、
関心毎の分離(描画処理と業務ロジック)ができるよう下記のような構成にしています。

tech.recruit-mp.co.jp

── AppDelegate.swift
├── data
│   ├── dataSource
│   │   └── SessionDataSource.swift
│   ├── extension
│   │   ├── CollectionExtension.swift
│   ├── storage
│   │   ├── DiskCache.swift
├── domain
│   ├── repository
│   │   └── SessionRepository.swift
│   ├── translater
│   │   ├── TimetableTranslater.swift
│   └── usecase
│       └── TimetableUseCase.swift
├── environment
│   ├── Config.swift
└── presentation
    ├── view
    │   ├── Timetable.storyboard
    ├── viewController
    │   └── TimetableViewController.swift
    └── viewModel
        ├── Timetable.swift

当初はレイヤー毎の責務分離がはっきりしている + テスタビリティが高いClean Architectureの導入を考えていたのですが、

  • 現状、そこまで複雑なアプリになりえない想定だったのでオーバースペック気味
  • とにかく時間がなかったので開発速度優先
  • 但し、責務分離の観点で費用対効果が高そうなクラス分けは取り入れる

上記3点の理由から一部取り入れています。

描画

複数日付のタイムテーブルの表示には、下記2つのライブラリを使用しています。

セル結合部分はとても泥臭い実装をしているので、リファクタリングしたいところ。

ネットワーク関連

buildersconにはAPIが用意されています

github.com

JSON Hyper-Schemaに対応しているので、これに沿った形式でSwiftのマッピング用のクラスを生成できればよかったのですが、最初は必要な項目も限られるし自分で定義した方が早いなと判断し自前でクライアントを作成しました。

github.com

クライアントはコールバックベースで完了時の処理を実装しているのですが、
ネストが深くなってきた + テストが書きづらいという理由から、呼び出し側で非同期オブジェクトを返すような形式にラップしたいなと考えております。#61

キャッシュ

当初よりオフライン及びキャッシュ対応はマストで入れようと決めていたので、下記の方針で実装しています。

  • 初回アプリインストール後はディスクに書き込んだデータを使用
  • Repositoryの実装で、ディスクから取得するかAPI経由で取得するかを隠蔽(API経由で取得した場合はディスクに書き込み)
  • 起動時にAPI経由で最新のデータを読み込みバックグラウンドでディスクに書き込んでおく

3つめはpull to refresh(引っ張って更新)でデータ再取得/再描画すべきだとは思いつ、初回バージョンでは富豪的APIを叩くようにしています。

Repositoryの実装はこんな感じ

func find(completion: @escaping (Result<Conference, RepositoryError>) -> Void) {
    localDataSource.find { localResult in
        if case .success(let value) = localResult {
            completion(.success(value))
        } else {
            self.remoteDataSource.find { remoteResult in
                switch remoteResult {
                case .success(let value):
                    completion(.success(value))
                    self.localDataSource.store(value) { writed in
                        if case .failure(let error) = writed {
                            log.error("store error: \(error.localizedDescription)")
                        }
                    }
                case .failure(let error):
                    completion(.failure(.find(error)))
                }
            }
        }
    }
}

うう、ネストが深い。。

また、APIのtokenを公開できない都合上、普段開発するDebugビルドの際にはプロジェクトに埋め込んだFileからデータを読み込むようにしています。

開発手順

セットアップ

リポジトリは個人アカウント配下にありますが、ゆくゆくはbuilderscon配下に移動予定です。

github.com

READMEにも書いてありますが、

  1. Ruby製のツール(fastlane..)を幾つか使用しているので、Bundlerでローカルにgemの依存をインストール。*1

    $ bundle install --path vendor/bundle

  2. iOS/Swift関連の依存ライブラリをCarthageを使ってインストール。

    $ carthage bootstrap --platform iOS

  3. (任意)SwiftLintをローカルマシンにインストール。

ビルド

シミュレーターで開発する分には、Xcodeでprojectを立ち上げProduct > Run(⌘R)で実行可能です。
実機に転送したい場合は、Xcode8.xでのiPhone実機デバッグメモ - Qiitaを参考に、projectファイル内のSigning/Teamを自分の登録してあるAppleIDに置き換え試してみてください。

まとめ

ざっくりとアプリの全体像を説明しました。
まだまだ追加したい機能やbugfixもあります(Issues)ので、ご興味のある方はPRを送ってくれると嬉しいです!

そして皆さん! 8/3, 4, 5にbuilderscon tokyo 2017が開催されます!
参加する方は、是非アプリをインストールし使ってみてくださいー!😄

*1:現時点ではマストではないので、1はスキップ可能

try! Swift Tokyo 2017に参加した

3/2~3/4に開催された www.tryswift.co

に参加してきました。

会社からの支援でチケットは購入して貰っていたので一般参加者として。
またカンファレンスの裏側の仕組みを知りたい。少しでも貢献したいと思いボランティアスタッフをやらせてもらいました。

ボランティアスタッフとして何をしたか

簡単に紹介すると

  • 設営
    • スポンサーブースのお手伝い
    • ノベルティ(シールやパンフレット)をエコバッグに詰める作業
  • 受付の案内
  • 質問時のマイク係

を行いました。

700名の受付という事もあり、時間をかけすぎたら後続が詰まるという焦りの中なんとかこなせたと思います。
日本人以外の参加者も多いカンファレンスという事もあり 、慣れない英語での対応に苦労しました。。

セッション開始後は、マイク係として会場袖に待機。
try! Swiftは1トラック構成で行っているので、ほぼほぼ全てのセッションを見ることが出来ました😊

参加者として

#tryswiftconf をひたすら眺める&呟いていました。
幾つか気になったセッションの内容をメモしていたので共有します。

テスト可能なコードを書くということの2つの側面

@mbrandonwさんのセッション

関数を完全にテスト可能にするためのものが2つあります。作用の分離と共作用を表面化です。この2つの側面の背景にある理論を探り、どのようにすればテスト容易なコードに導けるかを示します。

サンプルコード: kickstarter/ios-oss

  • テストの目的は、"テストできるコードだけを書きたい"から
  • テスト対象の入/出力に関しての話
  • アウトプットのテストが難しいのは副作用(side effects)があるから
    • => 副作用をコードの境界に持っていく
  • インプットを難しくしているのは共作用(co effects)があるから
    • ある特定の世界の状態がなければ実行できないということ
    • => テストの為に特定の世界を作る(DIと呼ぶ人もいる)
    • 共作用に対してグローバルな関数に直接アクセスしなくて良いように EnvironmentStruct を作成する ios-oss/AppEnvironment.swift
    • テストコードはwithEnvironmentで任意の環境(グローバル変数)を上書きしつつ、テストを実行できるようにしてる ios-oss/XCTestCase+AppEnvironment.swift

@niwatako さんの書き起こし niwatako.hatenablog.jp

iOSにおけるDocument IndexingとApp Search

@gridNAkaさんのセッション

ZalandoのiOSアプリでApp Search機能をどのように使っているのかを説明し、さまざまなタイプのコンテンツ向けのApp Search機能を紹介し、経験と実例を共有します。

サンプルコード: gridNA/appSearchExample

@niwatako さんの書き起こし niwatako.hatenablog.jp

ハッカソン

3日目のハッカソンは参加者として参加しました。

devpost.com

アクターモデルに関して知見はなかったのですが、並行処理はもちろん、
iOSにおける通知実装の一つの案として興味があったので、今回作成するSwiftActorのサンプル実装を書きました(未完成..)

github.com github.com

惜しくも入賞は逃してしまったけど、
@rizumitaさん @ikesyoさん @applideveloperさんはじめ、優秀な方々と貴重な時間を過ごせてとても楽しく勉強になりました!
(iOSクライアントの実装において、アクターモデルの有用性を示すのは中々難しかったです。。)

SwiftActorの開発は継続していくので、興味のある方はPRを!*1

参加してみて

*1:Slackチームもありますよ

迷いなく行動する

而今(にこん)とは、禅問答の言葉で

「今という瞬間」は二度と戻ってこない 「過去」や「未来」をあれこれ思い悩むのではなく今を一生懸命に生きるという教え

この言葉を自分なりに解釈すると、
今を後悔せず、 “迷いなく行動する” ことだと思った。

失敗を選択することがあった際に、ヘコんでしまう時はある。
現状を分析し、未来に不安がる時もある。

但し瞬間瞬間の判断において、出来るだけ迷いは無くしていきたい。
迷うとブレる、自信が無くなる(無さそうに見える)、勿体無い。

2016年

2016年のまとめ。サクッと振り返り。

去年のはこちら 2015年

仕事

昨年度に引き続きiOSを中心に。

など下回りの整備などを数多くこなしていました。

もちろん、下回りの整備/改善系は腐敗を防止(遅らせる)ために必要な作業です。
ただ今年はそこにフォーカスしすぎたのかなと少し反省しています。

来年は、もう少し機能開発とのバランスを意識しようと思います。

プライベート

  • Qiitaに4記事
  • はてなブログ(読書ログ中心)に14記事
  • その他、#shinjukultという身内だけのコミュニティで3回ほどLT

昨年と変わらずくらいのアウトプット量かなと。

来年はより技術的なアウトプットを増やし、対外的な自分マーケティングを意識したいところ。*1

旅行

南の方を中心に(宮古島ベトナム、台湾)
来年もあったかいところに行きたい🌞

来年の目標

  • 個人のプロダクトを持つ
  • iOSに特化しつつも、脇差を準備しておく
  • 対外的なアウトプットを増やす

*1:多少、手段と目的が逆になっても良いところだと考えている

「最強シンプル思考術」を読んだ

スーパープログラマーに学ぶ 最強シンプル思考術

スーパープログラマーに学ぶ 最強シンプル思考術

ものごとに対する本質を見抜く思考法 "モデルベース思考"についての本

TL;DL

  • モデルは意図を説明する存在、知識を"要約"したシンプルで分かりやすい説明
  • "モデルを作る"と"思考する"の両輪を回していくのがモデル化
  • 要素・事象をどのように分割するか、関係性から抽象化・具体化を考えどのようにバラしていくか、バラした要素からどのように全体を適切に説明できるようになるかの往復運動(思考)こそがモデル作りの本質

モデルとは

  • 根本は無駄を省いて物事をシンプルに考える
  • シンプルに考えるためにモデルを使う
  • モデル: 複雑なものごとをシンプルに表現したもの
    • 型がモデル

モデルの作り方

  • 四角(要素)と線(関係)だけであらゆるものに関するモデルを作成できる
  • "分かることは分けること"

モデルを作るメリット

  • モデルを作ると、漏れなく、重なりなく 物事が整理されていることが確認しやすくなる

より良いモデルを作るには

  • なんのためにモデル化するのかを一言で表してみる
  • 具体 is a 抽象
  • 抽象化とは汎用性を高めること。汎用性を高めることで広い文脈でモデルを用いることが出来る
  • モデルを使う場面を意識して、その場面や目的に合った抽象度でモデルを作る

「POODR」を読んだ

Practical Object-Oriented Design in Ruby

オブジェクト指向の規則が纏まっている本。
(依存関係を管理し、インターフェースを作るためのコードの書き方についての規則)

設計に緊張が伴う理由は、これらの規則を破るためです、上手に破ることを学べば、それは設計者の一番の強みとなります。

TL;DL

ソフトウェア設計の核は

  • 作成するソフトウェアの共通部分を探し出しモジュール化する
  • 作成するソフトウェアが将来変更される部分を抽象化し変更しやすくする

1.オブジェクト指向設計

  • オブジェクト指向設計とは多態を実装する部分を決めること、依存関係の管理
    • 如何にI/Fを定義するか、実装オブジェクトを隠し抽象I/Fでやり取りをする
    • 「対応しない」責任を決めることが鍵
  • 設計の行為と実装の行為が乖離したとき、オブジェクト指向ソフトウェアは失敗する
  • 少し知識を得たころが危険。知識が増え、その見返りを求めるようになり、執拗に設計するようになってしまう
  • 不適切な場所に原則を適用し、存在しないところにパターンを見出す。手段と目的が逆になりがち

2.単一責任のクラスを設計する

  • クラスを変更する理由は複数存在してはならない
  • = 一つのクラスには複数の責任(=役割)を持たせない
  • 提供したい機能(責任、役割、関心)
  • 1つのクラスに専念するクラスは、その1つのことをアプリケーションの他の部位から隔離します
    • この隔離によって悪影響を及ぼすことのない変更と重複のない再利用を実現する

3. 依存関係を理解する

  • メソッドチェーンは依存を作り出す
  • DI, 依存の隔離, 抽象への依存
    • クラス内で別のインスタンスを作成するのはやめよう(生成は外で)
    • クラス名を知っておく責任、そのクラスに送るメソッド名を知っておく責任がどこか他のクラスに属するのでは
  • 依存方向の選択
    • “自身より変更されないものに依存しなさい”
    • 領域分け, 方向の制御

4. 柔軟なインターフェースを作る

  • 再利用困難 = 自身について外部に晒しすぎている + 近隣オブジェクトについて知りすぎている
  • 合意と約束を意識する
  • このクラスが必要なのは知ってるけどこれは何をすべきなんだろう => このメッセージを送る必要があるけど誰が応答すべきなのか
    • メッセージを送るためにオブジェクトは存在する
  • オブジェクトがそのコンテキストから完全に独立していることが求められる
  • 誰の責任なのかを明確にする、知識を隔離する
  • 「どのように」を伝えるのではなく「何を」頼むか
  • 「私は自分が何を望んでいるかを知っているし、あなたがあなたの担当分野をやってくれると信じている」
  • 明示的なI/F: 「どのように」よりも「何を」になっている
  • リファクタリング: デメテルの法則(Law of Demeter, LoD)

5. ダックタイピングでコストを削減する

  • オブジェクトが何で「ある」かではなく、何を「する」か
  • ポリモーフィズム: 多態性(多岐にわたるオブジェクトが同じメッセージに応答できる能力)
    • メッセージの送り手は受け手のクラスを気にすることなく、受け手はそれぞれが独自化した振る舞いを提供する

6. 継承によって振る舞いを獲得する

  • 継承とは根本的に"メッセージの自動委譲"の仕組み
    • 理解されなかったメッセージに対して転送経路を定義する
    • 2つのオブジェクト間の継承関係を定義するだけで転送を自動で行う
  • サブクラスはそのスーパークラスを"特化したもの"
  • 新たな継承の階層構造へとリファクタリングする際は、抽象を昇格できるよう具象を降格させないようにする
  • サブクラスがsuperを送る == そのアルゴリズムを知っている
    • p172. post_initialize のようなフックメッセージを用意するだけ。そうすることで、サブクラスは必ず super を呼ぶ責任から逃れら れます。「いつ」初期化が行われるか知らなくてよいのは大きい。結合度の低減です。

7. モジュールでロールの振る舞いを共有する

  • オブジェクトは自身を管理すべき = 自身の振る舞いは自身で持つべき StringUtil.empty(“”)
  • クラスによる継承 == である(is-a) / モジュール == のように振る舞う(behaves-like-a)
  • サブクラスはスーパクラスと置換できる(リスコフの置換原則)
  • サブクラスとスーパークラス疎結合にする(サブクラスからsuperの送信をしたくない)
  • サブクラスが自然と特化できるようにテンプレートメソッドパターンを用いる

8.コンポジションでオブジェクトを組み合わせる

  • コンポジション: 組み合わされた全体が単なる部品の集合以上となるように個別の部品を複雑な全体へと組み合わせる行為
  • 大きいオブジェクトと部品がhas-a関係になることで繋がる
  • コンポーズされたオブジェクトは"ロール"を担うオブジェクトのI/Fに依存する
  • 集約はコンポジションのようなものだが、独立したライフサイクルを持つ
    • コンポジッションは親が消えたら自身も消える、集約は消えない

9. 費用対効果の高いテストを設計する

  • テストの目的はコストの削減
  • 良い設計は自然と抽象に依存する、独立した小さなオブジェクトの集まりになる
  • テストはオブジェクトの境界に入ってくる(受信する)か、出ていく(送信する)メッセージに集中すべき
  • オブジェクトは自身のパブリックインターフェースを構成するメッセージに対して"のみ"、状態についての表明を行うべき
  • 受信メッセージはその戻り値の状態がテストされるべき
  • 送信コマンドメッセージ(副作用)は送られたことがテストされるべき
  • 送信クエリメッセージはテストするべきではない(受け手のパブリックインターフェースの一部なので、必要な状態のテストはそちらで実装しているため)
  • テストダブルとはロールの担い手を様式化したインスタンスで、テストでのみ使われる
  • 大量のプライベートメソッドを持つものは新しいオブジェクトが負う責任かもしれない
  • 状態のテストとは対照的にモックは振る舞いのテスト。メッセージが何を戻すかを表明するのではなく、メッセージが送られているという期待を定義する
    • 送信メッセージが送られたことの証明は、モックに期待を設定すれば終わり
  • 最も良いテストとは対象のコードと疎結合であり全てに対して一度だけテストをし、それが適切な場所で行われているもの(コストを上げることなく価値を追加する)

See also