コネヒト開発者ブログ

コネヒト開発者ブログ

おすすめの英会話

f:id:tommy_kw:20171213092851p:plain

この記事はコネヒトアドベントカレンダーの15日目の記事です! qiita.com

こんにちは!Androidエンジニアの富田です。今年は周りのエンジニアさんで英会話を始めていた方が多く、特にDMM英会話を始めている方が多かった印象です。僕もDMM英会話、NativeCamp、Gabaを習っていたので、各種英会話の比較と学習継続方法について紹介します。

英会話を始めたきっかけ

英語を始めたきっかけは月並みですが、「英語を喋れるようになりたい!!!」と思ったからです。英会話学習は3年続けているのですが、当時は、「yes/no」しか喋れず、いきなりオンラインで海外の方と話すのはハードルが高いと感じたため、対面での学習ができるGabaを選択しました。

今まで習った英会話

Gaba

www.gaba.co.jp Gabaはマンツーマンの英会話教室で日常会話とビジネスの2種類があり、さらにその中でレベルが1〜10まで分かれています。最初のレッスンでレベル診断があり、そこでネイティブの先生と一対一の簡単な自己紹介をします。僕はほとんど無言になってしまった結果、レベル1からのスタートでした。自分の自己紹介がある程度できればレベル2もしくは3になるのではないでしょうか。

Gabaでは料金プランがいくつか決まっており、僕は受講回数90回の60万くらいかかるプランを受講しました。ぼぼ休むことなく1年間で90回のレッスンを消化し、イギリスやアメリカの講師の方々にレッスンをしていただきましたが、教え方が上手でまた受けたいと思うレッスンでした。僕の場合は、全く喋れないレベルでネイティブの先生とレッスンしていたので、お金の無駄で後悔する部分もありますが、対面でのやりとりができたおかげで英会話って楽しいなと感じました!

DMM英会話

eikaiwa.dmm.com

DMM英会話とはSkypeを用いたオンラインの英会話で一番よく利用されている印象があります。僕はGabaの後にこちらを利用しており、料金が安価なところが魅力的で、さらにDMM英会話は24時間受講でき、講師の数が豊富です。どの講師も親切で楽しめた結果、学習時間が30000分を超えるところまでDMM英会話を続けることができました!

f:id:tommy_kw:20171213175557p:plain

DMM英会話の特徴として、iKnow!アプリを無料で利用できます。このアプリは隙間時間を使って簡単にフレーズやボキャブラリや音声機能を用いてリスニングの勉強ができるところがオススメです。

f:id:tommy_kw:20171213175236p:plain

NativeCamp

nativecamp.net

最後に現在受講中のNativeCampについて紹介します。NativeCampはいつも利用しているブラウザを使って、しかもレッスン回数は無制限に利用できるオンラインの英会話です。

NativeCampの注意点として、DMM英会話と比べると講師の数が少ないため、時間帯によってはレッスンを受講できない時があります。さらに、「いますぐレッスンを受ける」は無料なのですが、レッスンを予約する場合は別途料金が発生します。いくつか注意する点はありますが、うまく活用することによってDMM英会話よりも安価にまた多くのレッスンを受講できます。ご興味があればフリートライアルを受けてみることをオススメします。

f:id:tommy_kw:20171211223631p:plain

英会話の比較

Gaba DMM英会話 NativeCamp
料金 90回のレッスンで60万くらい 月額5,500円*1 月額4,950円
デイリーレッスン数 チケット数による 1レッスン*2 受け放題
当日予約できる? 難しい できます できます
レッスン時間 40分 25分 25分
レッスン開始時刻 各スタジオで異なる 毎時0、30分 いつでも受けれる
レッスンの時間帯 だいたい7時〜22時*3 24時間 24時間
フリートライアル なし レッスン2回分 7日間
日本人講師 いない いる いない
講師 アメリカ、イギリス... フィリピン、セルビア...*4 フィリピン、セルビア*5

僕はお金と時間があればGabaを選びます。理由は対面での学習の方が楽しいですし、ネイティブ、特にアメリカとイギリス英語の違いが面白いからです。僕はGabaでイギリス講師の方に教えてもらうことが多く、例えばoftenの発音は「オフトゥン」と習っていました。でも他のオンライン英会話で同じ発音をすると、「オッフン」と発音するように注意されます。こんな違いがあるんだなという学びが生まれるのが面白かったです。

継続的な学習方法

英会話学習の継続はとても難しいことだと思います。朝起きれず、仕事が終わった後はもう疲れ切っているので学習する時間がありません。僕が直近2ヶ月でトライしているのは、仕事のお昼休憩を利用して英会話をすることです。お昼であればまだ元気が残っているので、これを続ければ最低でも平日5回は英会話学習ができます。

NativeCampは「いますぐレッスンを受ける」ことができ、受講者のライフスタイルに合わせて10分、15分だけ受けることができるので継続しやすいです。さらにお昼に受講しておくことによって、「あそこがちょっとよくわからなかったな」、「今日のうちに復習したいな」と次回の学習へのモチベーションに繋がります。

まとめ

英会話を始めてみたい!という方はDMM英会話のサポートが充実しているので良いのではないでしょうか。もしたくさん受講したいという方がいればNativeCampをお勧めします。僕はこの3年間の英会話学習時間が「600時間」くらいなので、今後は英会話学習時間が「1000時間」になるように頑張ります!

明日は@o0h_さんのターンです!お楽しみに!!

*1:5,500円、9,200円、12,800円プランがあります

*2:5,500円プランが1レッスン、9,200円プランが2レッスン、12,800円プランが3レッスン

*3:各スタジオで異なる

*4:ネイティブプランを利用することもできます

*5:ネイティブプランを利用することもできます

CakePHP3.5.8にアップデートしました

こんにちは!みなさま、そろそろ2017年のNo.1コミック作品を決め始める時期でしょうか?
個人的には、女子攻兵ロスが一時期ありましたので いちげきの第2巻は嬉しかったですね!

いちげき 2 (SPコミックス)

いちげき 2 (SPコミックス)

さて、アドベントカレンダー真っ最中ですが、CakePHPの更新をしたので投稿致します。 cakephp

今回は、3.5.7へのアップデートを見送っていた関係で、3.5.8になりました。

CakePHP3.5.7アップデート超訳

links

contents

  • テストコード中のアサーションのイディオムを「better」な書き方に #11422
    • すごいPR(diffが・・・
    • 内容は「例外検査をどうするか」というものでして、「アノテーションでやるより、ケースの中でメソッドを呼ぶほうが良さそう」というプラクティスを反映したもの
  • phpstanに従う修正 #11451
  • Digest Authenticationにおけるhash アルゴリズムの利用の修正#11453
  • (Databaseの)Typeの再設定をする際に、内部キャッシュ残存してうまく動かない問題の修正#11457
  • MariaDBでtmestampの初期値の扱いに問題があったのを修正 #11473
  • Routingで、配列による _methodの複数指定に対応#11474
    • これ今までなかったのでしたっけ・・・
  • FormHelper::button()で、confirm属性の注入に対応#11483
  • Responseクラスで、 bodyに文字列が入ってきたときに誤ってinvokeされる脆弱性の修正#11502
    • Response::body('phpinfo') のような 「callable」な値を入れると、、 phpinfo()の実行結果が取り出されてしまう・・・みたいなことですね
    • 当該のメソッドはdeprecatedではありますが><
  • ServerRequest::referer() で、意図していないサイトへの誘導が可能になっていた脆弱性の修正#11503

commments

今回は、「PHP7においてエラー処理に問題があることが発覚した」という情報があったので、コネヒトでは採用を見送りました。
この情報を拾えたのはSlackのCakePHP#Japanese チャンネルで動きを眺めいてのことだったので、とても助かりました。
source: Slack

また、同時期に「実は今まで、RequestHandlerCompoentとBakeプラグインの利用に、情報漏えいリスクに関わる問題が潜在していたのでは」という話題も上がってきていました。
詳細な内容がCakePHP Advent Calendar day-7に上がってきているので、CakePHP3をご利用の方はぜひ一度ご確認ください。

PHPUnitの例外の検査については、個人的には、アサーションメソッド expectExceptionvs@expectedExceptionみたいな話は、どこかで聞いたことはあったけど・・くらいの感覚でスルーしていました。(Cakeに入りてはCakeに従えばいいのかな、という面もあります。)
表面的に考えると「アノテーションでやるほうが簡潔」なんですよね。discussion にてPHPUnitの作者の記事が引用されているのですが、大変興味深かったです。ぜひ御覧ください。
特にA New Best Practice: expectException()のセクションは注目です。時代背景を踏まえた「今ならこの方が利便性が高い」という内容は、なるほど!と・・・
また、But going forward I will recommend using expectException() etc. for testing exceptions.とまで言っているので、結構温度感高めな感じがありますね

CakePHP3.5.8アップデート超訳

links

contents

  • emailのエンコーディング周りの修正 #11488
  • Response::isOk() にて、従来の200-202に加え203,204も許容(true)するように #11521
    • 余談ですが、弊社内では @itosho がコレを喜んでました
  • PHP7でのエラーのハンドリングの問題を修正#11518
    • このあたりは、もともとCakePHP3が持っているThrowableの扱いに関する問題(と言って差し支えないと思います)が絡んでいますね・・*1

comments

bakeryに挙げられている変更箇所は3点で、普段のアップデートに比べたらボリュームは少ないです。またこの期間中に注意喚起を行うためのポストもなされています。 bakery.cakephp.org

こういった様子を見ていて、「最近とてもbugfix/securityな雰囲気が色濃いなぁ」と感じていたところでした。

周辺のことを

本体の更新も去ることながら、個人的にCakePHP関連の大きな変更は bake pluginでtwigが標準採用されたということでした。 現状ではbakeのテンプレートをカスタムはしていないですが、適用箇所によっては利便性がとても高いと思うので、機を見て投入してみたいな!と思っているところです。 github.com

また、cakephp-codesniffer も 3.0.1 ... 3.0.2 に更新されています。
フレームワーク本体とがっちり合わせることで、こうしてstandardsも自然とレベルが引き上げられていくのは恩恵だな!と思っています。

所感

今回は、随分とSlackからの情報に助けられたと思っています。やはり日常的にキャッチアップをしていること・耳を傾けておくことが大事ですね・・と痛感しているところです。
3.5.7における脆弱性の修正は、chinpeiさんご本人から報告があがってきています。*2
もし複雑な内容で理解が追いつかなかったらその場で聞けそうというのも利点ですし、安心感を覚えました。

Advent Calendarの影響もあって?か、先月末くらいから #japaneseチャンネルもワイワイしている印象があります。Cakeユーザーがもっと増えるといいですね〜

それでは、また!

私の周りでも風邪やインフルエンザが流行ってきました、怖いですね気をつけよう・・・

qiita.com

明日(15日目)のコネヒト Advent Calendar 2017はコネヒトが誇るAndroidエンジニア @tommykw のターンです!お楽しみに!

*1:個人的に、 こちらの話の行方を見守っています・・

*2:https://cakesf.slack.com/archives/C1FT02VQA/p1512535795000014 にてご報告が上がっていました

CakePHPのModelのないフォームを使ってRequestバリデータを作ってみた話

こんにちは!! きららファンタジアが始まりましたね!6CMKYFGHPJまでフレンド申請お願いします!
@super_mannerです。

この記事はコネヒトアドベントカレンダーの11日目の記事です!
qiita.com

「CakePHPのModelのないフォームを使ってRequestバリデータを作ってみた話」 をします。

http://1.bp.blogspot.com/-zsoZgEuuKw0/UZYlSmKRIjI/AAAAAAAATMg/EFt9gd3L1ek/s400/christmas_cake.png

作ろうと思った動機

コネヒトでサーバーサイドでCakePHP3.xを使用し始めて1年が経ちました。
今でこそ、CakePHPの機能をある程度使えてきたかな?と思えるようになったのですが、使い始めた当時は以前使用していたLaravelと比べて癖があるな…という気持ちを持っていました。
当時を振り返ってみます。 「Laravelだったらこうできるのに!」と一番強く思ったのは、「入力値をバリデートをするタイミングが、Modelにバインドするタイミングである」という点でした。
Laravel他、これまで使用してきたフレームワークの多くがRequestそのものにバリデーションをかけるケースが多かったからです。

このようにControllerのレイヤーで行われるLaravelに対し、 
CakePHPはModelで行っています

もちろん、データをバインドするタイミングでチェックできていれば問題はないというのも最もだと思うのですが、 データを保存する箇所には関係ないRequestパラメータを早めに処理したいケースでは、やはりControllerで気軽にRequestパラメータをチェックしたいな、という気持ちが高まりました。

どうやって作ったのか

着想

今回私がベースにしたのは、CakePHPの「Modelのないフォーム」と呼ばれているものです。 https://book.cakephp.org/3.0/ja/core-libraries/form.html

ドキュメントにもあるように、主たる用途はお問い合わせフォーム等、データ保存を必要としないケースのFormの作成に使用される機構です。

  • Requestパラメータが検知できる
  • CakePHPのValidationの機構がそのまま流用できる

この2点から、フォームだけではなく通常のAPIでも使用できるValidationが作成可能では?!しかもCakePHPに乗っかる形で作れるのでは?!というノリと勢い、メンバーの後押しもあって開発してみようということになりました。

実装方法と使い方

現在実際に使用されているコードの一部を用いて説明しようと思います。
まず、Controllerではこのようにバリデーション用のFormのインスタンスを作成します。 ValidationForm と命名しました。

<?php
$rules = [
    'name' => [
        'rules' => [
        'require' => ['message' => 'お名前は必須です'],
            'notBlank' => ['message' => 'お名前には空白文字以外を入力してください']
        ]
    ],
    'url' => [
        'rules' => [
        'require' => ['message' => 'URLは必須です'],
          'url' => [
            'message' => 'URLの形式が正しくありません',
              'option' => true
            ],
          'custom' => [
            'message' => 'URLの形式が正しくありません',
              'option' => "/:\/\/(.*).exsample.com\//",
            ]
        ]
    ]
];
$validationForm = new ValidationForm($rules);
$validationForm->execute($this->request->getData());

見たままで何のひねりもなくて恐縮なのですが、

  • パラメータ名をkeyにしてCakePHPのバリデーションルールを配列形式でわたす
  • フォームのインスタンスを作成
  • executeメソッドを実行

と言った3ステップで使ってもらうようにしました。本当は1行で書けるように…もっと簡単に….と思ってルールセットの書き方をよりLaravelライクにしたり等の試行錯誤はしてみたのですが、

を優先してこの書き方を選びました。 (なお、やはりルールセットを書く行数がかかるのでここは色々再考の余地があると考えております 😂)

次に、ざっくりとですが、ValidationForm の実装内容をフローチャートでお見せしたいと思います。
流れだけでは伝わりづらい部分もあるかと思いますので、末尾に注釈を加えております。
f:id:supermanner:20171211115726p:plain


まとめ

今回この機能の実装を通して「フレームワークの機能を応用して別の使い方にしてみる」ということの面白さを体感したように思います。 作成者の意図には反していたかもしれないのですが、実際自分が普段あまりつかっていなかったForm周りの機構の再発見へとつなげることができました。 もう少し汎用的な作りにして、プラグインとして公開できればいいなと思っております!( ˘ω˘)スヤァ

明日は katsutomu さんによる記事です!!!お楽しみに 💁

WebViewをES2015+Reactで実装した時のTips

f:id:dachi023:20171204020041p:plain

こんにちは!ちょうど1ヶ月前に子供が生まれ、忙しくも楽しく日々を過ごしている安達(@ry0_adachi)です🍼🍼🍼

今回は「コネヒト Advent Calendar 2017」の7日目の記事として、WebViewで使われる機能をReact+Fluxの構成で実装してリリースした時の辛かったことと、それをどうやって解決したか?について書いていきます。

qiita.com

やりたいこと

この3つをクリアすればOKです。

  • Android/iOS両方のWebView上で動作すること
  • アプリの対応OSバージョン(iOS9〜/Android4.1〜)で動作すること
  • アプリの中でも違和感を与えないような動作を実装すること
続きを読む

僕のKotlinコントリビュータへの道のり

f:id:tommy_kw:20161106193050p:plain

こんにちは!Androidエンジニアの富田です。先月KotlinのPRが一つマージされてコントリビュータになりました!実はコントリビュータになると決心して、今年の1月からKontributeをスタートしたのですが、コントリビュータになるまでになんと「11ヶ月」もかかりました。珍しい事例だと思いますので、僕のコントリビュータまでの道のりを時系列で紹介したいと思います!

なぜKontributeしようと思ったのか?

昨年末に書いたKotlinを導入したお話というブログでたくさんのはてぶをいただき、もっと自分が会社に対して何かできることがないかと考えた時にKontributeが良いのではないのかと考えました。Kontributeの結果として、以下の2点がアウトプットできれば嬉しいと思い活動を進めました。

  • 当時は社内でOSSのコントリビュータが少なかったため、Kontributeをすると刺激を与えられるのかなと考えました。
  • 会社の知名度向上に貢献できればと考えました。

コントリビュータになるまで

Kontribute開始(2017/1〜2017/3)

Kontributeを開始しました!が、この時期は3点の問題があり、全く進捗がありませんでした。

  • 環境構築*1で心が折れる
  • どんなIssueから取り掛かればいいのかわからない
  • できそうなIssueがあっても、1、2日くらいで他のコントリビュータさんにIssueを対応されてしまう

Kontributeするための環境構築でハマっていました。今年の8月以前までビルドツールがAntでビルドが全然通らない、またテストの動かし方がわからず泣きそうでした。現在ビルドツールがAntからGradleに変わっているため、環境構築でハマることは少ないと思います。

KotlinのReadMeを見てもらうと、取り組みやすいIssueが既に管理されており、YouTrack*2の「Up For Grabs」タグが付いたものからチャレンジしてみてねとReadMeに記載されています。

We love contributions! There's lots to do on Kotlin and on the standard library so why not chat with us about what you're interested in doing? Please join the #kontributors channel in our Slack chat and let us know about your plans. If you want to find some issues to start off with, try this query which should find all Kotlin issues that marked as "up-for-grabs".

「Up For Grabs」タグが付いたIssueは以下の通りですが、何から取り掛かればいいのか当時は全くわかりませんでした。 f:id:tommy_kw:20171204225120p:plain

そのためしらじさんのHow to Kontributeブログを参考にさせていただき、まずはIntention/Inspection*3にチャレンジしようとPRを見たり、Issueを漁る時期が続いていました。

他のコントリビュータさんのPRのコードを眺めていると少しずつIntention/Inspectionについて理解ができ、それらのIssueにトライしてみました。しかし、Issueに着手する際には、Youtrack上で「僕がこのIssueをやります!」と宣言する必要があるのですが、本当にこのIssueを自分が対応できるのだろうか?と不安で調べている間に1、2日経ち、別のコントリビュータさんがすでにIssueを対応されていたケースが多かったです。

取り組み方を変えた(2017/4〜2017/7)

Intention/Inspectionの簡単なIssueであれば取り掛かれるレベルになったのですが、このままではいつまで経ってもコントリビュータになれないという危機感があり、取り組み方を変えてみました。

  • 朝1時間、昼30分、夜1時間とほぼ毎日Kontributeの時間に使う
  • 1、2日経つと誰かしらにIssueを対応されてしまうので、Youtrack上で「やります!」と宣言する

3月以前は、夜に活動していましたが次の日になると対応できそうだったIssueが既に別のコントリビュータの方が対応しているケースが多かったです。そのため朝昼晩とIssueをウォッチする時間を作りました。また、なんとなく自分でもできるかも!というIssueに対しては、「やります!」とまず宣言するようになりました。 f:id:tommy_kw:20171204203803p:plain

やっとPRを投げれるようになったのですが、まだまだマージしてもらうまでに至らず(まだレビュー中)、どうやって進めていくべきか悩んでいました。

救世主現る(2017/8〜2017/10)

なかなか成果が出ない中、救世主takahiromさんが現れました!!!!!!

takahiromさんはKotlinコントリビュータであり、Kontributeもくもく会を主催されていて僕も8月から2週間に1回の頻度で参加させていただきました。 f:id:tommy_kw:20171204201317p:plain

環境構築、PsiViewer*4、Issueについてなど教えていただきKontributeへの加速度が増しました!僕にとってはtakahiromさんやもくもく会のみなさんに教えてもらったことが大きな転機となりました。ありがとうございました!!

コントリビュータになった!(2017/11〜2017/12)

ついに11月に一つPRがマージされました!stdlibのサンプルコードの提供なのですが、僕にとっては大きな一歩です。 github.com

そして現在は以下のPRを投げています。引き続きトライしてマージされるPRの数が5、10個となるように頑張りたいと思います! f:id:tommy_kw:20171204091216p:plain

まとめ

いかがでしたか?僕のようにコントリビュータになるまで、「11ヶ月」もかかるのは珍しいと思いますが、今は環境構築でハマることも少ないと思いますし、やりやすいIssueが見つかればきっとすぐにコントリビュータになれると思います!

僕がKontributeできた要因は、継続的なトライとそれを支えて下さった社内のメンバーや社外のエンジニアさんたちのおかげです。 最終的なアウトプットの目標に掲げていた、「社内のメンバーに刺激を与えたい」、「会社の知名度向上」こちらについては、時間がかかりすぎてしまった部分はありますが、微力ながら貢献できたかなと思っています。今後の目標は、引き続きKontributeを続けて情報共有をすることです!

明日は@dachi_023さんによる「WebViewをES2015+Reactで実装した時のTips」です! qiita.com

*1:https://github.com/JetBrains/kotlin#build-environment-requirements

*2:YouTrackとは、JetBrainsのIssue管理ツール。githubのKotlinのページではIssuesタブが非表示となっています。

*3:Intentionとは、構文上の問題を改善、また最適化するための動作を提案するの機能で、いわゆるAlt+Enterのショートカットです。Inspectionは、コンパイルをする前に特定のコードの精査を行い、エラー、警告の規約違反を指摘します。Intentionで指摘されたコードの修正を行うことができます。

*4:https://plugins.jetbrains.com/plugin/227-psiviewer

リファクタリング対象を選ぶ戦略を決めよう

f:id:fortkle:20150929115239j:plain

この記事はConnehito Advent Calendar 2017の5日目の記事です。

こんにちは、ゲスの極み乙女。のライブに最近行きまくってる @fortkle です!楽曲”だけ”なら絵音は天才ですね!

さて、今日はリファクタリングについて書いていこうと思います。

フェーズによる目的の違い

スタートアップ初期の開発では、「コードが綺麗なこと」よりも「とにかく早く出してユーザーに受け入れられること」の方が重要です。

一方、サービスがある程度立ち上がった後の開発では、継続的に開発/運用するためにコードの品質を高めていく必要があります。なぜなら、コードの品質が低いと「予期せぬバグ」が発生したり、「生産性」が落ちたりするからです。

よくある問題:リファクタリング疲れ

コードの品質を高めていくために継続的なリファクタリングをしていく必要がありますが、こんな経験はないでしょうか。

  • どこからリファクタリングすればいいのか分からない
  • とりあえず目に入ったところから手当たり次第にリファクタリングを行う
  • たしかにコードは綺麗になったはずなのに、リファクタリングの努力に対して効果が実感できない
  • 効果が感じられないのでだんだん疲弊してくる

これは「リファクタリングの努力をどこに集中させるのか」という戦略が欠如しているために発生する問題です。

戦略を決めよう!

こうした問題を避けるにはどうすればよいでしょうか。 最初の努力で最大の効果を出せるようなリファクタリングを行うためにはどういった戦略が必要でしょうか。

重要なのは「推測するな、計測せよ」ということです。 データを計測することによって、「どれだけ効果が出たのか」が分かります。さらに「次のリファクタリング対象はなにか」を導くための戦略を考えることができます。

実際に戦略を考えてみよう!

データを集める

戦略を立てるために有益なデータには以下のようなものがあります。 またデータを計測するために、実際にコネヒトで使っている/検討しているツールも列挙します。

  • 不具合(バグ)
  • エラー
  • コーディング規約に対する違反
  • 性能
  • 循環的複雑度
  • CRAP (Change Risk Anti-Patterns)*1
  • 価値の高い機能
    • サービスのコア機能は何か考える
    • お金が絡む機能を考える
  • よく使われるファイル
    • 直近90日間で最も頻繁に編集された上位10ファイルを抽出するワンライナー
      • git log --since="90 days ago" --pretty=format:"" --name-only | grep "[^\+s]" | sort | uniq -c | sort -nr | head -10

戦略を考える

たとえば、「よく使われるファイル」と「CRAP」を組みわせると、「よく修正が発生しているのに質の低いファイル」を効率的に導きだすことができます。

他にも「価値の高い機能」と「不具合(バグ)/エラー」を組み合わせると最優先で対応していく必要があるものがわかりますね。

こういった戦略をチームで検討し、その戦略でリファクタリングを進めることによって効率的にコードの質を上げていくことができます。また、定期的に変化を追っていくことで「改善が上手くいっている!」というモチベーションにもなり、疲弊を防ぐこともできそうです。

まとめ

リファクタリングを始めるときに、「負の感情」から戦略もなく”えいや”で作業を進めてしまうことがあります。一時的には満たされた改善の欲求も、効果が薄いとどうしてもつらくなってきてしまいます。

そういったときに一度落ち着いて戦略を考え、チームで効率的に改善していくことで楽しく目の前のサービスと向き合えるように思います。

この記事があなたのリファクタリングライフを良いものにすることを願っています!

さて、明日は@tommykwによるオウサムな6日目の記事をお送りします。

*1:CRAPについては Hirakuさんのこのスライドが詳しい。 クソコードの測り方 - https://speakerdeck.com/hirak/kusokodofalsece-rifang

RxSwift.Variableはdeprecatedになりました

こんにちは、ガチエリアS帯のリードエンジニアの田村(@Utmrer)です。他のルールもS帯にいくため、Splatoon2サントラを聴きながら日々コーディングをしております。
この記事はConnehito Advent Calendar 2017の4日目の記事です。

今日はRxSwiftのコードを覗いていたら気づいたことを書きました。
(2017年12月4日現在の情報です)

Variableとは

VariableはRxSwiftで提供されているBehaviorSubjectのwrapperで値の取り出しや代入を直感的に扱うことができるSubjectの1つです。
MVVMでステートフルなViewModelのpropertyとして使っている人が多いのではないでしょうか。

// Example
class VM {
    let name = Variable("")
}
class VC {
    func f() {
        textField.rx.text.orEmpty
            .bind(to: vm.name)
            .disposed(by: disposeBag)
    }
}

RxSwift4でVariableはしれっとdeprecatedに

ある日RxSwift repositoryのコードを読んでいたらDeprecated.swiftという非推奨のAPIをまとめたファイルを見つけ、Variableが記載されているのを見つけました。
Warningが出ていないので気づけなかったのですが、Warningを出していないのは利用者が多いことなどが理由のようです。*1
ではVariableが非推奨になった時代に私たちはどうすればいいのでしょう。

安全なBehaviorSubjectであるBehaviorRelay

Variableのdeprecatedと同時に追加されたBehaviorRelayはBehaviorSubjectのwrapperでerrorの流れることが無い、安全なBehaviorSubjectです。この点においてVariableとほぼ同じ特性を持ちます。
Variableではvalue propertyのsetter/getterで値の操作を行っていたのが、BehaviorRelayでは下記のようなaccept() methodとvalue propertyでアクセスします。

let relay = BehaviorRelay<Int>(value: 0)
relay.asDriver()
    .drive(onNext: { value in
        print(value)
    })
    .disposed(by: disposeBag)
relay.accept(1)
print(relay.value)

Variableが非推奨になったので、同様の性質をもつBehaviorRelayに移行していくのが正道となるでしょう。

BehaviorRelayはRxCocoa

今までVariableはRxSwift moduleの一部でしたが、BehaviorRelayはRxCocoa moduleの一部になっています。BehaviorRelayと同時期に実装された安全なPublishSubjectであるPublishRelayもRxCocoaです。
これは「Relayは特定の環境で求められるものであり、Reactive Extensionsのコンセプト外である」というのが理由のようです。*2
ではRxCocoaに含まれるのが適切なのでしょうか?RelayにはCocoaへの依存はありません。ちなみに、これらRelayの設計元になったと思われるRxJavaのRxRelayはRxJavaのユーティリティという立ち位置でRxJava, RxAndroidには実装されていません。
このままRxCocoaに含まれていくような気がしますが、RxRelayとして分離されることがあるかもしれません。

BehaviorRelayへの移行はやるべき?

今すぐにでもVariableからBehaviorRelayへの移行を行うべきか、というと個人的にはちょっと待とうと思っています。なぜならば、Variableで提供されていたbind(to:)というmethodがまだBehaviorRelayには提供されていないからです。*3 RxSwiftの中の人も「ちゃんと移行方法を決めたら@availability付けて本当にdeprecatedにするよ」と言っているのでそれまで待ってもいいかなと思っています。*4
下記のようにextensionを書くことでbind(to:)を使うこともできるので待てなくなったら移行します。(副作用がちょっとわからないのでまだやってないのですが)

extension BehaviorRelay: ObserverType {
    public func on(_ event: Event<Element>) {
        switch event {
        case .next(let value):
            accept(value)
        default:
            break
        }
    }
}

まとめ

以上、RxSwift4でのVariableとBehaviorRelayについてでした。@availabilityが付くと大量のwarningが出る可能性があるので備えておきたいですね。 明日は@fortkleによるファビュラスマックスな5日目の記事をお送りします。

qiita.com