suzan2号の戯れ

SIerでインフラSE⇛WEB系でエンジニアのおっさん

RubyエンジニアがGolangのどんなところに挫折して、どんな風に再挑戦したかという内容でLTをしてきた

LTしてきた

【Go言語LT大会! 「最近、Go言語始めました」の会】でLTしてきました go-beginners.connpass.com

t.co

内容について

大体内容は前にブログで書いたような話で、 これからGolangを触る人向けに自分はこういうところで挫折した / 再挑戦してうまくいったよって話をした。

suzan2go.hatenablog.com

要約すると以下のような感じ

  • Golangで他のRuby(or 他のオブジェクト指向言語)のやり方を持ち込んでもうまくいかない事が多いよ
  • Golangの色んな先人の知見(ブログやGitHubソースコード)を参考にしたほうがいいよ
  • 書く量を少なくするためのハックよりも愚直に書いた方がいいコードになる気がするよ(個人の感想です)
  • 一度Golangの書き方に染まってみるときっと楽しくなってくるよ!

感想

  • インフラエンジニアっぽい人が多くて、アプリケーションエンジニアはあんまりいなかった印象でした(実際どうだったかは分からない)
  • Webアプリ作る時に参考にしたリンクが結構需要ありそうだったので、もうちょっとそっち方向でまとめればよかったなと思った。
  • ゲスト講演者のtenntennさんの標準パッケージ紹介が普通に勉強になった。Golangちょっと分かった気でいたけど標準パッケージでも全然知らないことの方が多かった。
  • 標準パッケージの内容読むの役に立つよって人が多かった。自分も読んでみようと思った。
  • 一緒に行った同僚の前職の後輩の人がいてビビった。更にびびったのはその人が自分のことを知っていてブログも読んでいるという事実。いぇーいXXXさん見てるー!?
  • 資料作っていると実は自分がよく分かっていないことが分かっていい。曖昧な知識で発表するのがアレだったので今回の発表内容は結構ふわっとした感じにしてしまったけど、次はもうちょっと突っ込んだ話をしていきたい。

現場からは以上です。

Railsでももっとカジュアルにapp/models配下にクラス作っていいんじゃないかなーと思っているんだけどどうなんでしょうか

Railsのプロジェクトやってると、app/models には ActiveRecord だけ、それ以外のオブジェクトは app/services とか app/forms層みたいなところに定義しないといけないと思っている人がそれなりに多い気がする。

個人的には app/models 配下に責務を分けたActiveRecordでないクラスを作っていくのはむしろ積極的にやるべきだと思っている。むしろそうしないとXX層みたいなものを導入したとしても、本来モデルの振る舞いとして表現されるべきものが手続き的に書かれてしまったり、新しく導入したXX層の処理がファットになっていってしまったりするのではなかろうか。(ActiveRecord のクラスと、そうじゃないプレーンなRubyクラスが app/models に交じるのが気持ち悪いという意見はまあ理解できるけど)

たとえば

たとえば以下のようなクラスがあったとする。

class User < ApplicationRecord
  def nanka_fukuzatu_na_shori
    if user.hoge?
       private_na_method_a
       private_na_method_c
    else
       private_na_method_b
    end
  end

  private

  def private_na_method_a
     # なんかの処理
  end


  def private_na_method_b
     # なんかの処理
  end


  def private_na_method_c
     # なんかの処理
  end
end

見るとnanka_fukuzatu_na_shoriprivate_na_method_a~c は明らかに関連をもつひとまとまりの処理なので、こいつらを実行する実態はUserクラスではないところにあっても良さそうな気がする。

これを User::NankaFukuzatsuNaShoriHandler を作って、そちらに責務を分けてみる

# app/models/user/nanka_fukuzatu_na_shori.rb
class User:: NankaFukuzatsuNaShoriHandler
  attr_reader :user

  def initialize(user:)
    @user = user
  end

  def perform
    if user.hoge?
       private_na_method_a
       private_na_method_c
    else
       private_na_method_b
    end
  end

  private

  def private_na_method_a
     # なんかの処理
  end


  def private_na_method_b
     # なんかの処理
  end


  def private_na_method_c
     # なんかの処理
  end
end

( nanka_fukuzatu_na_shori とかいう適当な名前で書き始めてしまったので User::NanakaFukuzatuNaShoriHandler#perform みたいにしちゃったけど、HandlerPerform みたいな抽象的な名前は避けたほうが良さそう)

Userクラスはこんな感じになる。

class User < ApplicationRecord
  def nanka_fukuzatu_na_shori
    nanka_fukuzatu_na_shori_handler.perform
  end

  private

  def nanka_fukuzatu_na_shori_handler
    @nanka_fukuzatsu_na_shori_handler ||= User::NankaFukuzatsuNaShoriHandler.new(user: user)
  end
end

基本的にはこんな感じで責務を分割していって、あるモデルの振る舞いとして定義するのが微妙なものだけそれこそXXX層みたいなの作ってやるのがいいんじゃないかと最近は思うんだけど、各社どうなっているんだろう。

  • Rails Wayから外れるので止めたほうがよい
  • Concern使えば?

みたいな意見はありそうかなと思っています。

参考文献

rubyblog.pro

qiita.com

あなたが成功したいならプライドを飲み込み、外に出ていって、自分が馬鹿に見えるのを恐れないようにしなければならない

最近(もう一ヶ月くらい前)、今更ながらソフトスキルズという本を読んだ。

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

この本場が話題になったのは去年の前半くらいだったと思うんだけど、買った後ちょっと読んで、忙しくなって積んでしまっていた。 あらためて読んだんだけど、タイトルにもした一文が自分的にはいい話だったのでブログにしておく。

あなたが成功したいならプライドを飲み込み、外に出ていって、自分が馬鹿に見えるのを恐れないようにしなければならない

結構自分は「自分をよく見せようとしすぎる」ところがあるなーと思っていて、そういう気持ちが何となくイベントにでて発表したりといったところに億劫になっていた気がする(あんまり失敗したくない・・・恥かきたくない的な気持ち)。

自分は影響されやすいので、この本を再度読み始めた直後に会社にお誘いのあったイベントに登壇してみることにした。 (以下が資料) speakerdeck.com

上記の資料はまあ正直フロントエンドガチ勢の人からするとそんなに参考にならないないようだった気がするし、 反省会というタイトルに引っ張られすぎて辛い内容を盛り込み過ぎたなぁと反省するところも多い。 あと結構当日までビビってて行きたくねーと回りに言いまくっていたりしたw

でもイベント終わったあと色々情報交換したいということで話に来てくれる人がいたり、 他の勉強会とかでお会いしたときに話掛けてくれる人がいたりして、今は登壇してよかったなーと思っている。 (Wantedly経由のお話しませんか的なやつの数も気持ち増えた)

【再掲】あなたが成功したいならプライドを飲み込み、外に出ていって、自分が馬鹿に見えるのを恐れないようにしなければならない

自分が成功しているとはまだとても言えないけど、外に出ていってみることで、色々分かることとか、広がるチャンス的なものがあることはかなり実感できた。今後もイベントがあったら登壇していきたい。とりあえず来週は、最近はじめたGo言語のイベントに出てみることにする。

最近Golangを触っている話

今更ながら趣味でGolangを触り始めた。家庭内アプリ用のAPIサーバとしてGolangを絶賛書いている。アプリはReact Nativeで書いていて、それはまた別の機会に書くことにしよう。

実は一年前くらいにもちょっと触っていて以下のような本を読みつつ、簡単なアプリケーションを作ろうとしていた。

Go言語によるWebアプリケーション開発

Go言語によるWebアプリケーション開発

スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

が、ちょうど仕事が忙しくなる時期と重なってしまったり若干モチベーションが落ちてしまったので、最近まではRailsにずっぷりだった。

Golang楽しい

一年ぶりに触り直してるんだけどとても楽しい。前回多少学習していたという貯金が効いている説、この1年で自分が成長している説などあるけど、明らかに前回触ったときより楽しい。 具体的には以下の辺が。

  • gofmt、golint… などで書き方をかなり強制されるので迷わず書ける。
  • ので、どうロジックを書くかといった部分に集中できる。
  • フルスタックなWAFのようなものはないので、自分で色々設計について考えられる(考えなければいけない)
  • (これは完全に自分の個人的な感想)ちょっと書く行を減らすためのハックより、愚直に書くことが好ましい雰囲気があるきがしていて、愚直に書けばいいやーという気持ちになる
  • 「それ標準パッケージでできるよ?」といったマッチョな思想があるきがしていて、ベストプラクティスを追い求めなくてよい(と、いいつつ、 echogorm を使っているけど…)

ここからは静的言語ならどれでもそうなんですが

  • コンパイルが通れば、大体動くという安心感
  • エディタ上で型、引き数が補完されるので、一々リファレンス眺めなくてよい

SIでJavaやってたときも同じメリットはあったはずなんだけど、全然思い出せないし楽しいと思ったことあんまりないな。なぜだ。

なぜ一年前はあんまり楽しくなれなかったのか

たぶんGolangRubyっぽいことやろうとしていた。Golangにはクラスがなくて構造体しかない。で、構造体を利用して、オブジェクト志向っぽく書く方法はいくつかあるにはあるけど、Rubyと同じような作りで書けるわけではない。なのに一年前はRuby(というかRails)のような書き方をしようとして、色々調べた結果うまく書けずそこでやる気が失われてしまった部分はあると思う。

Goに入ればGoに従え

今回はアプリケーションを書き始める前に、GitHubでいくつかrepositoryを見てみたり、いくつかブログを読んだりして、みんなどんな書き方をしているのか見て回っていた。そのおかげで、Golangではどう書くのかーというところをある程度インップットできたと思う。GolangGolangらしく書くことで、楽しくなったきた気がする。

Golangからの学び

Golangで今更ながら型の有り難みを噛みしめるようになった。エディタの型補完や、コンパイルが通ったときの安心感とか。 型のある言語からRuby/Railsに来た人が「型がないのが怖い」的なことを言う理由がちょっと分かった。自分がJava => Ruby に行った時には型がなくて怖いなんてことは思わなかったんだけど何で今更こんな感覚を持っているんだろうな・・・。Golangで書くようになって、インターフェース的なものを前より意識してプログラミング書くようになった気がする。

React NativeでJS書くときもflowをちゃんと使うようになった(前は使っていたけど面倒になってやめてしまった・・)。ライブラリの選定も「これくらいなら自分で書けばいいかー」という思想になってきた。

まとめ

お気づきの通り、Goに入ればGoに従え を言いたかっただけの記事です

最近アプリケーションの設計するときに気をつけてること

最近、機能の設計をレビューしたり話し合ったりするときに、うん・・・?ってなることがあって、でも駄目な理由をうまく説明できなかったのでちゃんと言語化してみる。ちなみにRailsの話です。

DBには事実だけを記録するようにする

色々開発してきて思ったのは、テーブルに状態を持たせるようにするとあっという間に複雑度が増してしまうということ。 status カラムや hoge_flag みたいなカラムを持つこと自体は全然否定しないけど、本当にそれが最適なのかは慎重に考えた方がよいと思う。

これは例ですけど、会員申し込み => 何か審査 => 会員登録完了 みたいなフローのアプリケーションを作る時に、会員情報のテーブルを1つだけ作りstatusapproved_at みたいなカラムを突っ込んで、申し込み状態と申込み完了状態を アプリ側で頑張って判定しようとしている例はまれによくある。

こうすると何が辛いかというと、他のレコードから関連を辿って参照しようとしたときに常にレコードのカラムの状態を気にしないといけなくなってしまう。それに申し込み時の情報と、会員登録後に必要になる情報は必ずしも一致しないはずなので、作ったときは同じだとしても後々拡張するときに辛くなってくる。また、会員情報にDB上のユニーク制約をかけたくなっても掛けられないのでアプリケーションでかけるしかなくなる。(そしてアプリケーションで掛けた制約は結構簡単にすり抜ける…)

こういうときは事実が何なのかに着目すると、きれいに設計ができると思う。今回でいうと申込み というテーブルと 会員情報 というテーブル二つに分けてしまう。そうすれば上記にあげたような懸念はスッキリ解決する。 同じようなカラムが二つのテーブルに別れることを懸念するかもしれないけど、本来違うものを同じテーブルに押し込むことのデメリットの方が大きい。

同じような理由で論理削除もよく考えたほうがよいと最近は思っている。削除という状態を追加するよりも、素直にそのテーブルからデータは消してしまい、必要な情報だけ履歴的に別のテーブルにコピーしておいた方がアプリケーションをシンプルに保つ事ができるとおもう。

安易にHashを作らない

Rubyはダックタイピングなのでそんなに厳密にやってもしょうがない」みたいな話は一定理解するし、そういうゆるさがRubyのいいところだと思いつつも、巨大なHashを作ってそれを色んな所に引き回したりするのは結構最悪だと思うようになった。Hashに何が入っているか、何のkeyを持つべきなのか実装を全部追わないと分からないからだ。

そしてHashが巨大化していくると、そのHashを操作するための実装がそのHashを引き回す側に出てきたりしてあっという間に良くない感じになっていく。

何かを作る場合も、ハッシュではなく、クラスを作ってそこに attr_accessor を定義したほうがよいと思う。そうしておけば、クラスを見ればどんな値を持つべきなのかすぐに分かる。それに、値の中身を書き換えたり、デフォルト値を与えたり、変換したりといった処理をそのクラスに押し込めていくこともできる。

まとめ

最近考えたことをまとめてみた。定期的にこういうの考えて吐き出しておきたい。

メンターになって1on1をやることになったので「ヤフーの1on1」という本を読んだ

ヤフーの1on1という本を読みました。

ヤフーの1on1―――部下を成長させるコミュニケーションの技法

ヤフーの1on1―――部下を成長させるコミュニケーションの技法

何で買ったのか

新卒の子のメンターになって、1on1を週次ですることになったので。今までもマネージャーの人と1on1は普通にしていたけど、そもそもどうやってやるものなのか自分自身よく知らないなと思って買ってみた。

感想

ヤフーの宣伝的な要素が結構多いのかなーと思ったけど、中身はおもったよりも参考になった。1on1といっても組織によっても位置づけは当然異なるんだろうけど、相手に「自分で考えて学びを得てもらう」ことが大切っぽい。なので上司やメンティーの立場から、安易に相手の考えを否定したり、こちらから答えや意見を出してしまうのは基本的には望ましくない。相手に考えてもらい、自分で課題ややりたいことに気づいてもらうことが大切ということだった。

自分自身のこれまでの1on1を振り返って、「◯◯さんはどう思う?」みたいな質問を何度も返されることがあって、「いや、こっちはあなたの考えを知りたいんだけど・・・」と思うことが結構あったんだけど、それは今思えば自分で考えて答えを出して欲しい、みたいな思いもあったのかもしれない(確認したわけではないので違うかもしれない)。相手の意図はわからないけど、何というか自分で考えずに相手に委ねようとしていた部分があったなーと思ってちょっと反省した。

で、実際にやってみて

予想以上に、「相手に考えてもらう」ように会話を進めるのって難しい。これまで普通に話してるときは意識してなかったけど、結構相手の意見を聞く前に自分で意見を言ってしまったり、自分の思う答えを先に出してしまおうとしていたことに気がついた。

そして実際に相手に考えてもらうように1on1を進めていくと、「A」だと思っていたやりたいことは実は「B」だった、とか「C」が自分の課題と思っていたけど実は「D」の方が課題だった、みたいなことが結構クリアになってくる。コレは自分が「A」と聞いたときに、先輩目線で適当なこと伝えていたら出てこなかったことだと思うので素直に驚いた。

マネージメントみたいなこと、正直全然興味なかったんだけど、これはこれで結構面白いなーと思ったのでした。(1on1がマネジメントと言えるのかは分からないが…)

2016年の振り返り

2016年の振り返りをします。

ちなみに去年はこんなこと書いていた。 suzan2go.hatenablog.com

2016年の振り返り

仕事で一からサービスを立ち上げた

仕事で1からサービスを立ち上げました。一昨年は既存のサービスを別WEBサイトとして立ち上げるということをしたんですが、本当に全く新しいWEBサービスを立ち上げるのは初めての経験でした。立ち上げまで殆どの期間でエンジニアが自分ひとりだったので、全体のモデル設計、決済関連の実装とか中々経験できないことを経験値として積むことができました。

プロダクト開発について色々考えた

仕様を考えるにあたって、それをやるべきかどうか判断するためのデータも少ない状態で作るのは本当にしんどかった。リーンスタートアップ的な考え方って正直あんまり好きじゃない部分もありました(いやいやちゃんと作れよ…的な)。が、正解が何か殆ど判断できない状態で作り込んでも無駄が多いっていうのは本当に実感したです。実際リリースしてから機能が全く使われない or KPIには寄与しないところを議論しまくって作ってたりとかしてました(たらればも少し入ってるかもしれないけど)。

  • ただ、「小さくリリースしていく学習する」ことを掲げるだけではだめで、そうすると「これ大変だから仕様削ろう」みたいな話になりがち
  • MVP(Minimum Viable Product)が考えられてないと、本当は優先度が高い機能が削られたり、サービスの立ち上げ時にはさして重要じゃないものに時間を掛けてしまったりする。
  • そんで、MVPをチームで考えるときには「解決する課題の仮説」をもっていないといけない。これがないとMVPがふわっとして、結局「競合はやってるからやった方がいい」「過去サービスでこれをやって◯◯が向上した」「◯◯さんはこれやった方がいいと言ってる」みたいな、そりゃやったほうがいいとは思うけど…みたいなことでいっぱいになってしまう。

みたいなことを学んだのでした。

以下のスライドははてブtwitterで見かけたのですが、何かもう心当たりのあることしかなくてウッってなりました。 speakerdeck.com

Reactを沢山つかった

なんかもうReactを使うこと自体は特に珍しいことでも何でもないですが、技術的にはReactをかなり積極的に採用しました。以下の記事にも書いたんだけどrailsとの組み合わせでReactを使うとき、かつwebpackなどを使用してSprocketsを使わない場合にはreact-railsじゃなくて、react_on_railsを使った方が色々捗ると思う。というわけでreact_on_railsを使ったです。

github.com

suzan2go.hatenablog.com

Reactを使ったこと自体には後悔していないんだけど、使い方には後悔があったり。react_on_rails (react-railsでもほぼおなじ)では、以下のようにReactのコンポーネントをERBやSlimに埋め込めるので、普通のrailsのテンプレートとReactを共存させることができますが、これをあんまりやらないほうがよかった。

.hoge
  = react_component ‘HogeComponent’, props: { pico: ‘hello' } 
.user
  = @user.username

既存のサービスならともかく新規のプロダクトでReactを使うなら、全部SPAとまではいかないまでも(実際そこまでの工数は掛けられなかったが…)あるネームスペース配下のURLでは全てSPAにするとか、ヘッダー・フッター以外は全てReactでrenderするとかにするべきだったなと。ReactにしてもReduxにしてもやっぱりSPAを前提にして作られているものだと思うし、上記のような使い方はどうしてもエコシステムに乗り切れない感じがした。

設計について色々考えるようになった

サービス立ち上げとも絡む話ではありますが、設計について色々考えるようになりました。この冬色々話題になったサービスクラス、railsのconcernなど、プログラムのテクニック的な捉え方しかしてなくて設計観点でどうかということは正直意識が低かった。ビジネス要件が大きくなって実装が複雑になっていったときに、どうしてもアプリケーション側のテクニックで何とかしがちだったのですが、あるべきデータの形が何かとか、モデルの責務としてどうかとかそういうことを何となくではなく意識して考えるようになったのでした。その辺りの話は以下のアドベントカレンダーをどうぞ。

qiita.com

今年はDDDとかオブジェクト志向とか改めてちゃんと勉強していきたい。

キャリアについて考えるようになった

まだまだ若手枠のつもりでいたのですが来年30になるということで、気づいたら中堅になってた…そりゃ「どういう方向性に進んでいきます?」ということをよく聞かれるわけやw

良いプロダクトを生み出すには技術力だけでは駄目なんだということはよくわかったし、チームで良いパフォーマンスを出していくにはジャーマネ的な動きが大切なのだということがよくわかった一年ではあったものの、やっぱりまだ自分はエンジニアとしてコードを書くことを一番していきたいというのが正直なところ。

去年子供が生まれてライフスタイルが大きく変わった。自分に費やせる時間は圧倒的に減っているので今後の生存戦略を本気で考えないといけない。

2016年を振り返って

正直関わっていたプロジェクトは結構ハードで、良いことばかりではなくどちらかというと反省の方が多いのですが、それでもサービスの立ち上げというものを経験できてよかったと思います。 一昨年はSIerから転職してきて何とかWEBエンジニアとして頑張っていこうというところでしたが、去年はWEBエンジニアとして自分の価値をどう出していくか考えていた一年でした。自分の価値が出せたのかというと結構微妙なところな気はしているので、今年は明確に見える成果を出していきたい。

今年の抱負

雑ですがこんなことことを考えています。

社外の人に会う

去年は社外の勉強会にあまり参加できなかったので参加したいというのと、もっと社外のエンジニアの人と色々話してみたい。いろんな会社のRails Wayを知りたい。そして自分がどんな位置にいるのかを把握していきたい。

機械学習でなにか作る

アドベントカレンダーの以下の記事が割と衝撃的だった。WEBだけやっていても自分の市場価値はもう上がっていかない感が凄いので、色々手を出して行きたいと思います。 qiita.com