個人事業主になったので真面目にアウトプットしてみるブログ

フリーで顧客の会社に潜り込んでAndroidアプリつくって、とりあえず食っていけるようにアウトプットを増やしていくブログです。

Clean Architectureについてメモ

Clean Architecture(以下CA)と
https://github.com/googlesamples/android-architecture
ここに書いてあるブランチのMVP-cleanの実装とはわりと別物。

前者はドメイン層とその外側の境界をちゃんと意識した実装を主張しているのに対して、後者は説明ではCAについてのリンクを貼っているけど、内容はMVPにUseCaseをつけてコマンダーパターンにしただけ。後者は設計の知見が少ないと、簡単にドメイン層に外側の事情が持ち込まれるし、複雑なアプリではかえって冗長性が度を過ぎる場合が多い。UseCaseをつかってRepository(DataSource)にアクセスしてーってところについてはコードの一貫性が心地よい。 そこだけじゃ?

class GetItem extends UseCase<Param, Response> {
    private final ItemRepository repos;
    GetItem(ItemRepository repos) { this.repos = repos; }
    @Override void execute(Callback callback, Param param) {
      Item item = repos.find(param.id);
      item.update(param.value);
      repos.save(item);
      callback.onSuccess(new Response());
    }
}

Googleのサンプルだけを見てうまくできるのはまずCAもちゃんと知っているけど、CAだとファイルが多くなりすぎるから、MVPとDIPを取り入れてみるだけでとどめたいって感じの人なんじゃないかなーと思うと、チームでこれをうまくやるには割とハードルが高い。
あとそのまま低機能なUseCaseHandlerを使うなら、多少学習コストがあがっても枯れているRxJava使った方がいい。 (自分はUseCaseHandlerをキャンセルしこめるようにしたり、Handlerの制御を変えたりと、低機能なやつを改造する方をやったw) ガチでやりたいならCAをちゃんと理解してレイヤーごとにModule化して強制的にDIPなコードにする勇気が必要。
その上でファイルがーって話ならKotlinでやればなんとなく気楽に書けそう。

CAとDDD

DDDの本質はドメインのロジックが、リーダブルでありストラテジックに組みあがっていることを目指すもの。
けどGUIなアプリでは単純にコレクション(DataSource)の出し入れのコードになるので、DDDは結局のところ、Bounded Contextとか戦略的なDDDを適用するで終わってあとはひたすら似たようなことを繰り返すことになる。
特に何かお金や時間みたいな抽象性を利用したライブラリをつくるってわけでもなければ、コード自体は期待したストラテジックには組みあがらない。
CAはドメイン層とその外側との境界を守る方法でDDDとは相性は悪くない。

DDDのストラテジックな表現ってあんまりやるケースがないけど、単純にファイルをクラウドに上げるって感じだと

Content content = MyFileSystem.of(path);
StoreResponse res = Cloud.store(content);
println("rest:" + withByteStr(res.restSize) + " amount:" + withByteStr(res.total))
//とか
ContentList list = MyFileSystem.getNews();
StoreResponse res = Cloud.store(list);
//さすがにフィードバックがないとあれなので
ContentList list = MyFileSystem.getNews();
Cloud.store(list, callBack);

クラウドに上げたファイルをダウンロードって感じだと

Content content = Cloud.getContent(id);
/*
 * パスが指定されていないのは、限定されたパスの直下に配置するという意味で。
 * さらにたとえばキャッシュパスを指定するならMyFileSystem.saveAsCache(content)になる。
 * staticである必要はない。DIをするならなおさらのことstaticではだめだ。ここではあえてDDDとして簡潔なスタイルをとった例として書いている。
 */ 
MyFileSystem.save(content); 
// とか
ContentList list = Cloud.getContentList(groupId, callBack);
MyFileSystem.saveAll(list, callBack2);

GUI関係ない感じだとこんな感じでもいいのかなって。

命名がアレなのはデフォルト。

これをストラテジックな実装の参考にするくらいなら、たしかエリック・エバンス氏が取り上げていた

Eric Evans氏の基調講演より - ドメイン駆動設計を実践するには

ライブラリとしてJoda-Timeや

Joda-Time - Home

氏の書いたライブラリのTimeAndMoneyを参考にした方がいい。

GitHub - neuhalje/TimeAndMoney: Time and Money Code Library

こっちは氏のライブラリ。SourceForgeにあったコードを有志のかたがサルベージしたもの。

プログラミングについて

プログラマーか人間か

僕はプログラマーである自分を人間だと忘れてしまいがちである。 しかし常に僕は人間であることを毎日思い知らされるている。 物理的な制約が、僕をこの社会に縛り続ける。

シンプルになる

人は最適化されるなかで生きていく。 最適化されていなければ、最適化するようにふるまう。 パターンを認識し、不必要な情報はそぎ落とす。 そぎ落とすことで余分なキャッシュをなくし、シンプルになろうとする。

人は同じではない

物事の事象に対する意味の見つけ方は様々で、どう反応するか、反応しないかは、本当に人のいる数だけ違うといっても過言ではない。 これをよく知らないでいると、とんでもない出来事に出くわす。 人は最適化の、シンプルになろうとする上で思い込みを利用する。 過去のパターンにこじつけ、まるで同じものであるかのように、反応する。 しかし、ほとんどの場合そのパターンに当てはまるというのは錯覚であることがすぐにわかる。 しかしシンプルにならなければ人は失敗をする。 このジレンマはいつまでも我々の中で誤解を生み続け、最悪の場合相手を消し去ろうとする。 (最悪は誰のものか?という問題はさておき)

コミュニケーション

人は同じではない、それゆえコミュニケーションが必要になる。 コミュニケーションには、似たようなプロトコルが必要で 地形的な制約による偏在性はそれを可能にした。 長い年月で培ったコミュニケーションのための知恵、知識の伝達は親から子へ受け継がれ。 それゆえの制約も受け入れなくてはならない。 その葛藤のなかで、他者を認識し、他者と同様のプロトコルらしいものがあることを確認する。

言葉

人がシンプルであるために、コミュニケーションという手段をとった。 他者と情報伝達手段の一つのプロトコルとして、形(文字)と声を利用し、言葉という概念を会得する。 言葉を発明した人は、言葉による概念の共有をはじめ、神をつくった。

論理

人は言葉を発展させ論理を獲得した。 論理には人を従えさせる力があった。そして法をつくり、邦あるいは国をつくった。 人はより多くの人のなかで生活をすることが、生きていく上でシンプルさを獲得するには重要であると知った。 人はそれぞれが違うので、より多くの人が集まれば、より多くの人が違いをもたらした。 その結果、論理がより多くの人のシンプルさを保つためのツールとしてつかわれた。 論理はもてはやされ、論理によって文化という概念の上で、論理と文化と文明を発展させていった。

電子制御された機械

論理は測定、記録、発見、発明の効率を上げた。そして科学の進歩を促し、論理自らもさらに発展し、機械が電子制御されるようにした。 機械は複雑な計算をより高速に演算し、情報の持つ価値を飛躍的に向上させるようになった。 電子機械はより小型化されるようになり、より多くの人にとって情報の価値がより上乗せされるようになった。 制御をつど組み替えられるように改造された。 電子機械をプログラムをつかって、より柔軟な演算が可能なように作り替えられていった。

つかれた・・・時系列や因果なんてよくわかんないや・・・何となくそうでしょって感じ

プログラミング

いい加減さっさとプログラミングの説明しろって? イイからもう寝て

フリーランスのエンジニアが2017年に読んでためになった本5冊

@okuzawats さんのツイートを見て、マイナー?な本の紹介もされていて刺激をもらったので、たいしたことないAndroiderな僕の去年勉強になったと思う本を5冊ほど紹介していきます。

逆説のスタートアップ思考

逆説のスタートアップ思考 (中公新書ラクレ 578)

別に、ハッキリしたホームランを狙うプロダクトがあるわけでもなくスタートアップを興そうとかは考えていないのですが、ここに書いてある事がSF界隈での当たり前なのだという事をしるためには良い本です。

この書籍に書いてある大まかなことは下のスライドをみるとわかります。

www.slideshare.net

これだけでもかなり面白い内容ですが、書籍の方には(情報が多少古かったりするのかもしれませんが)米国のスタートアップ界隈どのようなことが起きているのかを垣間見る事ができ、日本でフリーランスとして活動したり、就職が必要になったときにどういう企業を選ぶかの参考にもなります。日本のプログラマ等のエンジニアがSO狙いの糞しか集まらないような筋の悪いスタートアップに遭遇する確率を減らすためにもどうでしょうか?

関数型リアクティブプログラミング(Programmer's SELECTION)

関数型リアクティブプログラミング (Programmer's SELECTION)

プログラミングが本業なので、自分のプログラミング観を一つ崩した本としてこの「関数型リアクティブプログラミング(書籍)」を紹介したいです。

RxJavaが日本のAndroider界隈で話題になったとき、RxJavaが何なのかを知るには情報がほとんどなくて全然理解できないで、しばらく使い方や利用例だけで何とか知識を増やしていったのですが、この本の序盤のラザニアの例やリアクティブプログラミングと関数型リアクティブプログラミングの違いの解説で腹落ちしたので、僕のように他人の説明ではまったく腹落ちできない僕のような人は序盤の部分を読むだけでもリアクティブプログラミングについて理解したい人には充分に価値があると思います。

僕のプログラミング観がどう崩れたのかって話をすると、やはり本書のラザニアの例が中心になります。FPRでのコードは「手順の説明(操作的定義)的なコードであるより概要的(概念的定義)であるように宣言的プログラミングを利用する」という感じの説明が序盤にあるんですが。まさに僕が日ごろからOOPで書いても「コードがぐちゃぐちゃになる人は、処理の粒度が混ざって見通しが悪いコードを書く、逆に粒度が整理されていて見通しが良いコードはぐちゃぐちゃになりにくい」ってところと、厳密的には違うのですが、リンクしたというかそれにさらに、昇華されたもののような知識を手に入れられたのが大きいです。

具体的にはこんな感じです。

ラザニアの作成を手順の説明(操作的定義)的な書き方で表した時の例
1. 大き目の鍋に油を熱する。
2. 玉ねぎをきつね色になるまで炒める。
3. 牛ひき肉とトマトを加える
4. …

ラザニアを概念的定義で表した例
* ラザニアとは、チーズソースの上に平打ちのパスタ、ボロネーゼ、チーズソース、平手打ちのパスタ、ボロネーゼを順番に重ねていき、その上にする下したチーズをかけてオーブンで45分焼いたものである。
* ボロネーゼとは・・・
* チーズソースとは・・・

とこんな感じです。これをコードで表す感じです。あまり厳密的ではないですがRxでいうならそれぞれボロネーゼ、チーズソースといった名前のついたObservableをつなげて合成していくとラザニアができあがって行くイメージでしょうか? 細かい点は購入するなりして本書にあるコードを見てくださればわかると思います。

FRPではそれがストリーム(シグナル?)の関数の合成として表現できるという事がわかったので、現在の自分が個人開発で書くViewとロジックをつなぐコードはRxBindingなどを使ってストリームの合成で書くようになってしまっていて、それ以外の書き方はなるべくしないようにしています。ちょっとしたハシカです。(この手法がプログラミングにおける書き方のベストというわけではなくあくまでも個人の趣向に依存していますが、対話的で複雑なリアクティブなコードが書きやすくなっていて非常に有益性を感じています)

RxJavaの記事を見ているとFRPについてネガティブに書かれている記事が見られたりするんですけど、まだ何がどう悪いのかについては彼らが言う事を理解するには至っていません。状態が隠れて見にくい。一度作りこんでしまうと変更しづらいという話を聞きますが、それは書き方の問題をFRPの問題と転嫁しているのか、FPR自身の問題なのかを確かめられFRPに未来がないと感じるまでは少なくとも続けるかもしれません。(賢者は歴史に学ぶという話がありますが、それが可能なのは限定的で、当人や伝達者の改竄、バイアスが発生している可能性が小さくない以上、学べることはそうは多くないと考えています。選択と集中はこういうところで発揮したらいいかと。)

本書で紹介されるのは主にSodiumというライブラリなのですがRxJSでFRPのやり方やRxの問題点なども開設されているので、RxJavaについて知見を得たい方にもおススメです。(それがRxであるはず)

github.com

本書はさらに実践的なFRPを段階的に学べる内容になっています。僕もここの3章までの内容などを実際にRxJava(Kotlin)で書き起こしてみました。

github.com

プログラミングClojure 第2版

プログラミングClojure 第2版

去年は、僕にとっての関数型プログラミング事始めでした。

関数型プログラミング自体は以前から気にはなっていましたが、Kotlin、ScalaやRxJavaを少し触る程度でおわっていたので、改めて本格的に関数型プログラミングを学んでみたいという事で、SchemeOCamlHaskellScala、Rustなどを選定しているうちに一番興味を持ったのがClojureでした。

まずなぜClojureを選んだかというポイントで言うなら、言語的にシンプルであるというポイントです。実は始めたときにはそのシンプルが何を指すのかわかっていなかったのですが、いろいろな関数型プログラミングが利用できる言語について知っていく上で他の言語は単純な関数型プログラミングを知る以上に多くの知識があふれており面倒に感じました。情報が多いことは良いのですが、関数型プログラミング初心者が選ぶにはたやすい言語ではない言語が多すぎ、少々辟易していたところにClojureという言語を知ることができたのが大きかったかもしれません。さらにRxやKotlinなどで勉強している関数型プログラミングが表現している延長に近いもの(厳密的ではないが並行処理としてのデータ不変やロック回りの話や関数ファーストみたいなところで、モナドがどうとかという部分ではない部分)を勉強したかったというのもあります。

本書ではClojureを知るという意味で全体像、文法の基礎を学ぶのに適しています。

書籍の話ではなくClojureの勉強の話全般になってしまうのですが、日本語書籍は限られていますがClojureのコミュニティは非常に活発的で多くの人が積極的に参加している感じで、Clojure言語の設計者であるRich Hickey氏のカンファレンスでの発言はとても本質的で、非常に刺激されるものがあり。ぜひ継続して学んでいきたい動機が多い言語です。

Clojureのサブ勉強本として仕えたのが「七つの言語 七つの世界」という書籍です。全部は読んでませんがいろいろな言語を知ることができます。この本の著者はモナド推しHaskell推しのようですがw

7つの言語 7つの世界

Clojureでリアクティブプログラミングやりたいと思ったので下記の書籍もKindle版を買ってみました。

手順の説明は非常にわかりやすい英語になっているので、英語が苦手でもそう怖くはない気がしています。

Clojure Reactive Programming - How to Develop Concurrent and Asynchronous Applications with Clojure

真面目な話はそろそろやめて、怪しい本系を紹介していきたいと思いますw

残酷すぎる成功法則

残酷すぎる成功法則  9割まちがえる「その常識」を科学する

これはAmazonで結構上位にあった本なので、有名どころすぎてアレかもしれませんが。

最近話題になったグリッドについても、それだけではだめだとかいろいろ気づかせてくれる内容が多かったし、エビデンス込みで解説してくれるので自己啓発に余念のない人は、一読しても損はないかなーという気がします。

2100年の科学ライフ

2100年の科学ライフ

この本は怪しい本ではないですがw

今後のテクノロジーが発展していっても、ハイテクはハイタッチ(他人との共感を示せる場)がないと決して成功しないという話があり。全部読んではいませんがとても興味深い内容になっています。

去年はKindleOasisを買ったので、積極的に利用して通期でぶっとい本2冊、MBAスマホ3台みたいな重装備をするケースを減らしていこうと思います。

難問!?:ロジカルな思考能力を試そう~


これ10分くらいで解けた。
難問ってほどではないけど。

これって

ログを読んで、そこに書いてあることから推測ができるエンジニアならわかる系の問題ですね。


なので問題解決が大得意なエンジニアさんにもやってみてもらいたいです!


問題が解けたら煽っていくすたいるw

DDDが難しいって話なんじゃけど...

DDDの入門でつまづくって話

  なんか思う事があったのだ書いた。

DIが前提で難しいん?

  ヘキサゴナルアーキテクチャみたいなものを使うとDIPの概念とDIの導入の検討が必要になるという話で、DDDの思想には関係ない。
  それでもDIが知りたい場合は次の項へ。DDDの話のみでいいなら飛ばしてね。

それでDIってなんなん?

  DI自体は単純に依存関係をJavaインターフェイスみたいなもので、実装と抽象を分離するって話。
  たとえばサーバー側がまだ用意できてないみたいな状況でもMockクラスで置き換え可能にしておいて、Stubなデータを返す実装で簡単な通信回りの単体テストができるようにしたいとか,Javaのクラスベースで実装の置き換えを可能にしておくとか、そんなイメージで良いと思う。

  実際にそれを使う事はテストコード書く時が一番使う。
  単体テスト時、サーバーが準備されていないけどJsonのフォーマットだけ決まっている時とか。new Foo(new BarMock())としているところがnew Foo(new BarImpl())みたいに簡単にスイッチできるのって楽だよねとかいうのはほとんど幻想だってこと。

続きを読む

ポエム・より良い未来を選んで滅亡する話

みなさんはナッシュ均衡とい言葉をご存じだろうか?
僕もついこないだ知って大変関心して以来
馬鹿の一つ覚えのようになってしまっている(実際はそうではないが




僕が今頭の中に残っている、ナッシュ均衡というのを要約すると

ゲーム理論上で考えられる、プレーヤー同士が協力関係にない時 プレーヤー同士が互いにベストの選択をしようとした結果 プレーヤーが選べる選択肢が狭まる
そんな話だったと記憶している。


うろ覚えで悪いが、今回重要なのはゲーム理論の話ではない。(よってここで僕の記憶力に関する問題がテーブルに並ぶことはない



まぁ題名と、ナッシュ均衡という言葉を知っているだいたいの人は
ここでブラウザバックをするのだろう。

まぁそれはそれでよいかな。



続きを読む