chigichan24のお気持ち表明

イケてるエンジニアになりたい.

2017年夏技術的知見集

きっかけ

どうもみなさんこんばんは.ちぎちゃんです.

刺激的で知見の連続だった夏休みだったので,備忘録的に書いておきます.

こうして振り返ると,無知だったなぁとよく分かるしまだまだ知らないことが世の中たくさんあるなぁ.

ちょっと一記事に様々な情報が載りすぎなのでそのうち,気が向いたら記事分けよう...

気をつけて記事を書いたつもりですが,多くがインターンシップで学んだことなので,これはまずいですよ...というのがあったら連絡ください.速攻で該当箇所を消します.

設計とかのこと

DDDについて

DDD (Domain Driven Design) (ドメイン駆動設計)とは エリック・エヴァンスが考えた設計手法.

関心の分離ユビキタス言語の2つがすっごく大きな鍵になる.しなやかな設計というワードもたまに耳にする.

特に,自分的にハマった部分は,ドメインの様々な要素(Entity,ValueObject,Factory,Service,Repository...)等にはそれぞれ責務があり,あまったからここに割り当てようという考えではない.なんとなくEntityとかにすると痛い目にあう.さらにServiceはDomainServiceなのか,はたまた,ApplicationLogicServiceなのかというのも非常に迷うことが多い.

加えて,ドメインの世界では実装の都合など考えてはいけない.例えばRepositoryにはEntityのライフサイクルの管理や,永続化などの役割があるが,ここでDBの都合なんか考えてはいけない.これが自称学生エンジニア ( ) には辛かった.実装ありきで設計を考えていたのがすごくわかった.

まだ,理解が足りない点として,DDDに基づいたリファクタリングのことが一番大きい.

これは引き続き勉強したいし,以下の二冊を買わないとなぁ.

これはあるあるだけども,和訳のせいで理解が逆に難しくなることがあるので洋書でもいいなぁ.

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

実践ドメイン駆動設計

実践ドメイン駆動設計

Clean Architecture について

Clean Architectureは名前から分かる通り,アーキテクチャの1つ.「あれ?DDDとはどんな関係なんだ?」と思った方.私もまずそこでつまづきかけましたが,DDDにおいてはどんなアーキテクチャを採用するかなんて縛りは無いんですよ.

だから,「関係は?」と聞かれたら「DDDの方が広い概念で,いろんなアーキテクチャにDDDの考えを取り入れることは可能」と答えれば3点くらいもらえるんじゃないでしょうか(ちょっと自信がない).

少々話がそれましたが,Clean Architecture の目的は レイヤ間での関心の分離変更に強い というのがあるかなと思います.やりたいことってシンプルに,

8thlight.com

なんだけど,これ最初読んだときはわかった気になるけど,10回くらい読むとわからなくなって100回目くらいになるほどだんだん分かってきたぞってなりました.まあアーキテクチャなので,特に実装しようとするとつまることが多々ある.

そのなかでも一番ビッグで,個人的にすげぇ解決策だなと思ったのは,先のサイトでも触れられているDIP(Dependency Inversion Principle) (依存関係逆転の原則).

関心の分離・変更に強いを実現しているのは依存の方向を中心に向かって作っている点.これをすれば,中心をきちんと作っておけば,外側で変更を施すだけなので変更に強い(多分)し,レイヤーで区切っているので関心の分離もできている.やったね.

Hexagonal Architecture について

基本的にはClean Architectureと同じで 関心の分離 を目指している.それはそうで,歴史的に見たらこっちのほうが古いし,この思想を引き継いでCAができている感があるので,まあ.

このアーキテクチャでは特に外部との関わり方みたいな部分にフォーカスを当てています.外部ってなんだっけ?というのは,アプリケーションロジックが依存したらまずい部分で,Adapterを介してアクセスしようね.その役割でポートを切ろうねという感じかな.

Alistair.Cockburn.us | Hexagonal architecture

これ読めばだいたい分かるから....(責任転嫁)

awsのこと

そもそも

awsは趣味として嗜む程度にしか触ったことがなかった.そもそも,一学生が恩恵を受けられるほどの大量のデータを処理する機会なんて好きなイケメン俳優の画像をクローリングしてほげほげするくらいしかないでしょ.というわけでめちゃくちゃ知見を得られたよ.

Redshift Spectrum

RedshiftからS3に蓄積されているデータに対して直接クエリが投げられます(!) そりゃあもちろん,Redshiftに格納してそれに対しておいたほうが処理は早いのは自明なんですけど,S3に対して,外部スキーマ外部テーブルさえ作っておけば,Redshiftにクエリを投げる感じと同じ感じで扱えます.RedshiftにあるテーブルとJOINとかもできます.

うまく,使い分けをできれば学生には優しいお値段で運用できるかもしれませんね.

Parquet

Redshiftは(多分BigQueryも)列指向型です.列指向はレコード単位でのクエリより,カラムを指定する感じのクエリを高速にさばけるという利点があります.で,これにParquetという保存形式がすごく相性がいいんですよ.なぜならCSVJSONとは違って,保存のときに列を意識して圧縮されます.つまりこれS3に保存するときに,(バイナリなのでそのままでは読めないというデメリットはあるが)Parquetにして,上述のSpectrumで叩けばいい感じに高速に捌いてくれそうですね.まあ別にRedshit使わなくてもAthenaとかで見てもらっても全然いいんですけど.

ちなみに,Parquetはさっき書いたけれども,バイナリなのでそのままでは私は読めません.なので,

github.com

こういうのを使ってスキーマとか確認できます. というかよくよく考えると別にaws絡んでなくても良いので,ここに書くべきじゃなかったかなぁ.

Glue

GlueはサーバレスなETLです.スキーマ情報をいじいじしたり,ジョブを作ったり,それを定期的に実行したりいろんなことができます.複数の昨日の集合体という感じなのでGlue - HOGEみたいなのが幾つかあります.

まずは私が一番感動したGlue Crawlerについて書きたいかなぁと思います.これはサーバレスにS3等のデータを見て自動的にスキーマを吐き出してくれて,それをデータカタログとして保存してくれます.それだけでなく,不必要なカラムを落としたり,型を変えたり,ディレクトリ構造からパーティションを切ってくれたりといろいろしてくれる凄いやつです.私がまだ知らない(使っていない)機能として, classifierというのがあるので,非常に気になりますね.凄いけどクセも強いのでなれるまで数日かかります.

あとはjobです,今までは多分Sparkとかでやってた部分がこれに移り変わるのかな?適当にやりたいことをGUIでポチポチしてるといつの間にか自動でPythonコードが出力されています.なにか凝ったことをしたいときはこれをさらに書き換えたりする必要があるのですが,CSVをParquetに変換するくらいの軽いjobならそのままjobを実行できます.凄いですね.

Kinesis

Kinesisデータをリアルタイムで加工して分析につなげよう!という感じのあれです.いちいちデータレイクに行ってから分析してたらデータの規模がやばくなったらつらいですよね?そういうのを解決してくれます.

基本的に

  • Kinesis Stream (データを引っ張ってきたり,どっかに運んだりする.)
  • Kinesis Firehose (保存先(S3 や Redshift等)を決めて流す.)
  • Kinesis Analytics ( 強化版クエリてきなやつを使って流れてくるデータを加工する. )

の3つから成り立っていてこれらを組み合わせながらやる感じです.実はあんまりさわれてないんですよね....

プログラミングそのものに近いこと

Android Architecture Components について

突然,Androidが出て来る感じの構成になってしまって申し訳無さがあります.これ自体は今年のgoogle I/O で発表されたものだからみんな知ってると思います.

まだ alpha ver ですがこれ来るんじゃね?感がすごいです.

今までそれっぽいMVVMとかアーキテクチャを作ろうと思うと,いろんなライブラリを大量に導入することで無理やり実現している感がありました. 有名所だと

  • Dagger
  • DataBinding
  • Butter Knife
  • Rx

ココらへんはだいたい使わないといけない.これはなんか流石につらい.ってことでココらへんを全部解決してくれるライブラリをgoogle先生が作ってるみたいです(神)

基本的にサンプルコードがJavaで書いてあることが多いのが悲しいですが,Kotlinで書いて近いうちにもう一本記事かこうかしら.

というかここで,詳細にこれに触れるとこの項だけで凄い行数になる気がするので(途中まで書いててヤバイことになることに気がついた),後日サンプルappを作って自分なりに解説しようかなと思います.

軽く触れるとイメージ的には下のような感じかな(ちょっと分かってない)?

f:id:chigichan24:20170930122940p:plain

依存は基本的に緑の矢印の方向に向かっていて,Rxのイベントを発行する感じ(observer pattern)で値を戻して,上に依存するという感じ. で,色んな所にAACが表れてくるので,という感じだね.まあもうちょっと深く勉強してから記事かくか.

あとこれ買ったので,早く製本されて届いてほしいなあ.

peaks.cc

Minimal Cake Pattern

Scalaにおいてdiを実現する最高で最強な方法の話.

ノリはこんな感じ.Repositoryって例として考えるとだいたいUserってなるよね()

//CAでいうと,DomainLayerとかに書いておく.実装はInfraStructureLayerで.
trait UsesUserRepository {
    val userRepository: UserRepository //UserRepositoryは下でtaritとして定義し,実際に外からつかときはこっちを見る.
}
trait UserRepository {
    //interfaceをひょひょいと書く.
}
//実装部分
trait MixInUserRepository extends UserRepository {
    val userRepository = UserRepositoryImpl
}
object UserRepositoryImpl extends UserRepository {
    //interfaceはDomainLayerにあるのでそれを実際に実装するところ
}
trait UserService extends UsesUserRepository {
  // ここにサービスつくる
}
object UserService extends UserService with MixInUserRepository // 注入

ここに全てが詳細に書いてあったので詳細は省略.というかドワンゴが考えだしたやつなのでね.これ最初に見たときに確実に静的解析が効く形で,かつ抽象に依存するというのを再現してて,コードが煩雑にならない感じがするので,すごくいいなぁと思いました.

特にCAをScalaでやったときに,あ〜綺麗ってなりました(小並感)

qiita.com

Scalaのfor式のこと

Scalaはこの夏初めて触りました.そのなかでもforに感動したので,これについてちょっとだけ書いてみようかなと思います.

Scalaはコップ本読みつつ,ブログ記事をあさりまくるというスタイルでこの言語はなにがしたいんだろうというのをちょっとずつ理解していった感じです. C言語からプログラミングを始めると,forってループを制御するやつという感覚が体に染み付いているのですが,Scalaを書いてると,だんだんOptionとかFeatureを引っ剥がすやつみたいな感覚になってきました.

例えば,Optionで包まれたStringを表示するメソッド

def show(value: Option[String]):Unit

を作るとします.Optionなので値が入ってるかもしれなし,入ってないかもしれないのでというのを考慮して

def show(value: Option[String]):Unit = {
    if (!value.isEmpty) {
        println(value.get)
    }
}

こんなコードを書くとうーんて気持ちになります.Scalaらしくないというか,なんというか... こういう問題設定だったら,

def show(value: Option[String]):Unit = {
    for ( v <- value ) { println(v) } 
}

のほうが綺麗に思います.なんでここで forって疑問に思うかもしれないですが,Option に対する forってシンタックスシュガーなんですよね.なので,IntelliJとかで書いてると,

f:id:chigichan24:20171001183050p:plain

が出てきます.で,これを押すとこんな感じに展開されます.

def show(value: Option[String]):Unit = {
    value.foreach(v => println(v))
}

なるほど,forforeachシンタックスシュガーなんだね.じゃあforeachはなにかのシンタックスシュガーなのかな?

Optionforeachがどういう定義になっているかを見ると,

@inline final def foreach[U](f: A => U) {
    if (!isEmpty) f(this.get)
}

ここに isEmptyあるじゃん!!!

だからこそ,はじめに書いたようなコードがScalaらしくないと言われる所以なんですね.言語として用意しているメソッドならそっち使ったほうが一般的な感じになるよね.という話でした.

ちなみにこのケースでは,

def show(value: Option[String]):Unit = {
    value.foreach(println)
}

こう書くのが一番きれいっぽい気がするなぁ.

Kotlinのこと

Android開発において主流はもうこの言語に移行したと思うんですけど,日本語のKotlinバイブル本みたいなのもはまだ無いような気がします.それゆえ,どうかくのが一般的なのかイマイチ分かってなかったです(実は今もあんまりわかっていない).けれど,これはアンチパターンだなみたいなのはちょっとずつ分かってきたつもりです.

Convert to Kotlinは万能ではない

AndroidStudioを使うことを前提に話します.理由は私がこれしか使ったことがないからです(EclipseAndroid開発していたのは遠い昔の話).JavaとKotlinは100%互換なはずなので,一応機械的に変換は可能です.ただし,そのコードってイケてない事が多いと思います.動作はしても,KotlinらしくなかったらKotlinを導入するうまみが小さい気がします.

特にstaticまわりが厳しくて,自動変換がうまく効かないことがあるので,注意したほうがいい.

scope functionがどれがどれなのかがわけわからんくなる

Kolinにはいくつかのscope functionがあります(余談だが,scope functionという命名が謎だと思っていたけど,最後に示すブログ記事見てなるほどってなった).

ScalaのmapとかflatMapとかそこら辺の奴らみたいないいやつです.

とこの記事を書いてる最中にもわからなくなったので,ぐぐったらいい感じのブログ記事を2つ見つけたので,先に貼っておきます.

qiita.com

nyanyoni.hateblo.jp

一つ目のはKotlinやってたら絶対に知ってる長澤さんの書かれた記事なのでめちゃくちゃわかりやすい!!!

let
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
with
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
run
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R = block()
apply
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
also
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

定義を見ればなにができるのか一目瞭然だ!!!

github.com

わからなくなったら,これ読み込もう(原点回帰).ちなみにIntelliJなら [command ⌘] + クリックで定義元みれますよ.

Androidっぽいこと

Recycler Viewのはなし

今までListViewで殴ってきたり,そもそもViewまわり嫌いだったのでそっとしてたりしてましたが,本腰を入れて触りました.こっちのほうが自由度が高い分,例えばAdapterを自前で書くなど記述量は増えますがやっぱりなんでもできるようになります.まあここらへんの記述は✝コンパイルエラー✝が出ることが多いので良いんですが,やっぱりxmlでlayout書くのがどうしても体が受け付けませんでした.こういうケースはwrap_contentでこういうときは,match_parentだけど,これは例外みたいなのが結構多いので疲れます...

Mainframerのこと

話には聞いたことがあったが,リモートビルド良い.といっても個人での開発では使うことはほとんどないか.

github.com

AAC

上にも書きましたが,別記事で書きます.

その他

  • 保守性,拡張性を意識したプログラミングがあまりできてないことが分かってきた(いままで好き勝手書いてきたからなぁ).
  • アーキテクチャにすごい興味が出てきた.
  • intelliJ IDEA,まじで全然使いこなせていない便利機能がたくさんあるので,もっと開発したいね.
  • 世の中,まだまだ楽しいことがたくさんだぞ😊

最後に

まだまだたくさん学んだことはある気がする...ほんとに一つ一つちまちまと書いていたら時間が溶ける一方なのでここらへんで...

こういう最高な体験をする機会を与えていただいた皆さまありがとうございました.