【現場で役立つシステム設計の原則】データとドメインモデル
最近、現場で役立つシステム設計の原則をよみ直している
データベースにはコトを、ドメインモデルには業務ロジックを記述していく
このことを考えるとデータベースをアップデートすることは、マスターデータ以外はそうはなさそう
例えば、商品名は変更することはあるけども、購入データを変更することはない
購入したという事実をデータとして登録するだけだからね
わかりやすい例を書いてくれていた
年齢という関心事があると、年齢というクラスが必要になる
でも、データはコトなので生年月日が登録されている
Rubyだとこんな感じでしょうか
require 'date' class Age def initialize(birthday) @birthday = DateFormatter.new(birthday) end def calculation difference / 10000 end private def difference today.to_yyyymmdd - @birthday.to_yyyymmdd end def today @today ||= DateFormatter.new(Date.today) end end class DateFormatter FORMAT = '%Y%m%d'.freeze def initialize(date) @date = date end def to_yyyymmdd @date.strftime(FORMAT).to_i end end birthday = Date.new(1978, 5, 18) age = Age.new(birthday) puts age.calculation #=> 41
でわ、なぜドメインオブジェクトにロジックを書いたほうがいいのでしょうか?
例えば、人間とペットにはそれぞれ誕生日があります
人間クラスとペットクラスにそれぞれ年齢というロジックを実装してしまうと、同じロジックが重複してしまいます
そして、年齢計算ロジックが変更したい!とすると人間クラス、ペットクラスそれぞれを修正しないといけません
さらに、テストも重複してしまいます、、悲しいですね
そこに、ドメインモデルである年齢というクラスがあると、年齢の計算は一箇所に集約されて、テストも1つでOKですよね
担保する箇所が1つになるので、品質も向上します
そう、いいこと尽くめなのです!
コントローラやビューにロジックが書いてあるのを見つけたら、それに名前をつけてモデルに業務ロジックを移動させてみましょう
そうすると、年齢の仕様を確認するときは、年齢クラスを見ると明らかになります
明日はドメインオブジェクトの見つけ方を書いてみます
JSConfJP 2019に参加してきたヘ(^o^)ノ
JSConfJP 2019のスピーカーを見た瞬間にチケット購入したイベントに参加してきました!
チケットを買ったときに聞きたかったセッション は以下
Day 1
- THE STATE OF JAVASCRIPT by Sacha Greif
- BUILDING SECURE AND SEAMLESS SIGN-IN EXPERIENCE USING WEBAUTHN by えーじ
- DEFINING OPEN SOURCE by Henry Zhu
- BUILDING AND DEPLOYING FOR THE MODERN WEB WITH JAMSTACK by Guillermo Rauch
- WRITE WHAT NOT HOW by Jorge Bucaran
- DENO - A NEW WAY TO JAVASCRIPT by Kitson Kelly
- MAKE IT DECLARATIVE WITH REACT by Toru Kobayashi
- あとは体育館
ほぼ、予定通り聞いたけど、一つだけ予定を変更したのがある
それは、TECHNICAL SEO FOR JAVASCRIPT DEVELOPER 3つ目かな
ZEITのCEOのセッションは魅力的だけど、いまのお仕事がらSEOってワード入ってたらちょっと無視できないので、
変更して話を聞いてきた!
結果、とてもおもしろい話で、英語も聞きやすく最高だった!けど、寒かった、、
そう、JSConfJP 2019の会場は、2F体育館でこの変更したセッションは屋上だった、、
寒さを忘れるほど楽しいセッションだったけど、寒かった、、いや、まじで、、
最近、Pixel4を購入してろくに使いこなしてなかったけど、JSConfJP 2019で録音 & 文字起こしを試してみた
最初はもたつきます。推測ですが、最初は声を認識してるのかなと思います
司会の方とスピーカーがワイワイしてるときは、うーんって考えてますw
ところが、スピーカーが話し出すと、スラスラと文字に起こしていくではないですか!
しかも、制度はちょーいい感じです!
音声は取れてるので、あとで確認してみるとネイティブな英語であれば95%くらいは文字に起こせてると思います!
まじですごい!
ちなみに英語以外の文字起こしは未対応なので、アップデートを待ちましょう
1Dayのセッションを終えて思ったことは、どれもすばらしいセッションでした!
あと、話にメリハリというか、感情がこもっているほうが聞きやすかったですねー
セッションが30分という短いこともあり、みなさん早口になりがちでした
そんななか、Martin Splittさんのセッションは、言いたいことと感情(これは、、クソだ!(実際は言ってないけどそれっぽく言っての一番ウケたw
がこもっていて、ホントに英語が聞きやすかった
僕も英語のセッションとかやってみたいから、すごく参考になりました
聞いてる方も、あー、ここ嫌なんだなーとかここめっちゃ気に入ってるんだなーがわかりやすいので、自然と英語も入ってくるのかなと思いました
Day 2
予定はしてたけど、あんまり参加できなかったです (寒かった)
予定東リ午後から参加でしたw
- PASSWORDS ARE SO 1990 by Sam Bellen
- MIGRATION FROM REACT NATIVE TO PWA by ohbarye
- PERFORMANCE TUNING IN EC SITE WITH GRAPHQL by 澤井宣彦
- ANALYSIS OF AN EXPLOITED NPM PACKAGE by Jarrod Overson
- DISCOVERING ANIMALS WITH AI AND JAVASCRIPT by Jonny Kalambay
- PIKA: REIMAGINING THE REGISTRY by Fred K. Schott
- あとは体育館
こんな感じです
2Daysはほんとに楽しかったけど、土日で新幹線人多い問題とか、会場寒い問題とかいろいろありました
東京は寒いですね、、
新大阪に帰ってきて、551の豚まんで温まりました
スタッフのみなさま、海外、国内からのスピーカーのみなさま、ほんとにお疲れ様でした
来年も是非参加したいと思います!温かい会場がいいです、、
Happy JavaScript ヘ(^o^)ノ
明神岳を登ってきたヘ(^o^)ノ
最近、登山いってます!
今回は明神谷ルートで、明神平 => 前山 (ルート間違いww) => 明神岳にチャレンジしてきました!
入り口はこんな感じ
第1印象はけっこう激坂!
心拍数はあがりましたが、筋トレの成果もあり足は余裕でした!
だた、40分ほど登ってるとやっぱり心臓が悲鳴をあげてきます、、
それでも、Max 165でした
心拍数が振り切れなくなったのは、ジムに通っている成果なのでしょうか? (きっとそうです
休憩しながら登りきると明神平に到着
まわりに自分がいるとこより高い山があって、あんま登頂感はないですww
僕が先導したのですが、ルート間違えたみたいで前山へ向かってましたw
10分ほどで制覇!w
そこから明神岳へ向かいました
明神岳 (1,432m)
やってやりました🏞️ pic.twitter.com/kbz7dHPjVt
— むらじゅん (@murajun1978) September 29, 2019
途中、川を渡ったりして楽しかったなー
予報では雨だったせいか、登山者は少なめでしたねー
下りは相変わらず膝にきます、、(ダイエットせねば\
登った印象は、ひたすら登りが続く感じでした
ただ、絶壁みたいなのはないので、楽しく登れるはずです(はずです
あと、川を渡らないとダメなので、雨とかで増水してるとキビシそうですね
ちがうルートもあるみたいなので、また登ってみたいと思います
Enjoy Climbing ヘ(^o^)ノ
GitHub Registryが使えるようになったので、Next.jsのDocker imageをPushしてみたヘ(^o^)ノ
GitHubからWelcome to the beta of GitHub Package Registryメールが来たので試してみた
GitHub Package Registryにpushできるものは ↓ リンクを参照してください
今回はNext.jsのDocker imageをGitHub Package Registryにpushしてみました
サンプルコードはこちら
/packages
にアクセスすると、パッケージ一覧が確認できます!
Next Actionとしては、GitHub Actionsを使ってAuto Deployできるようにしようかなー
ちょっと気になるのが、Betaだからなのか、僕のネットワークがクソなのかわかりませんが、no such hostなるエラーがちらほら出ました、、
サンプルコードはPublicですが、もちろんPrivateリポジトリでも利用できます!(これはめっちゃいい!!!!
Privateリポジトリの場合は、writeはもちろんread時もaccess tokenが必要になるのでお気をつけを
この辺 ↓ を参考に設定すれば大丈夫かと思います
Enjoy GitHub Package Registry ヘ(^o^)ノ
Docker Container上のNext.js with TypeScriptなAppをVSCodeでDebugする
Docker containerで動作しているNext.jsをVSCodeでDebugしてみました
サンプルコード
Requirements
- Docker
- Docker Compose
インストールはこの辺を参考に ↓
Docker
開発用のDockerfileを作成
Dockerfile
FROM node:12.10-alpine WORKDIR /home/app USER node EXPOSE 3000
Docker Compose
まずは、Node開発環境をととのえる
docker-compose.yml
version: '3.7' services: node: &node build: context: . volumes: - .:/home/app runner: <<: *node command: /bin/sh
Node.jsのベースと開発用のServiceを作成する
できたら、開発用のコンテナを起動しよう
$ docker-compose run --rm runner Creating network "example-next-typescript-with-vscode_default" with the default driver /home/app $
Next.js
起動できれば、Next.jsとTypeScriptをインストールしていく
$ npm install next react react-dom $ npm install -D typescript @types/react @types/node
package.json
{ ... "scripts": { "dev": "next", "test": "echo \"Error: no test specified\" && exit 1" }, ... }
Homeページを作る
pages/index.tsx
// pages/index.tsx function Home() { return <div>Welcome to Next.js!!!!</div>; } export default Home;
Next.jsを起動すると、tsconfigとか諸々作成されます
$ npm run dev
起動できました!本題のDebugいってみよう
Node.js Inspector
Node.jsは --inspect
オプションを追加すると、デバッグクライアントをリッスンしてくれます
環境変数でオプションを指定します
FYI: nodejs.org
Inspect用のnpm scriptを追加します
package.json
{ ... "scripts": { "dev": "next", "dev:inspect": "NODE_OPTIONS='--inspect=0.0.0.0' next dev", "test": "echo \"Error: no test specified\" && exit 1" }, ... }
↑ ここのドキュメントにも書いてますが、inspectのデフォルトは 127.0.0.1:9229
です
今回はNext.jsをDocker Containerで起動させて、ホスト側のVSCodeから接続したいので、ホストを 0.0.0.0
に変更してます
docker-composeの設定も変更します
docker-compose.yml
version: '3.7' services: node: &node build: context: . volumes: - .:/home/app runner: <<: *node command: /bin/sh server: <<: *node ports: - 3000:3000 - 9229:9229 command: npm run dev:inspect
Serverというサービスを追加しました
作業しているコンテナから抜けて、containerを起動します
$ docker-compose up
docker-composeの環境変数にセットしてみたけど、Node.jsでコンフリクトしてるのか起動できなかった
Starting example-next-typescript-with-vscode_node_1 ... done Recreating example-next-typescript-with-vscode_server_1 ... done Starting example-next-typescript-with-vscode_runner_1 ... done Attaching to example-next-typescript-with-vscode_runner_1, example-next-typescript-with-vscode_server_1, example-next-typescript-with-vscode_node_1 server_1 | Debugger listening on ws://0.0.0.0:9229/136aaa58-2624-4587-8f5f-45e7234c9610 server_1 | For help, see: https://nodejs.org/en/docs/inspector example-next-typescript-with-vscode_runner_1 exited with code 0 server_1 | server_1 | > app@1.0.0 dev /home/app server_1 | > next dev server_1 | example-next-typescript-with-vscode_node_1 exited with code 0 server_1 | Starting inspector on 0.0.0.0:9229 failed: address already in use server_1 | npm ERR! code ELIFECYCLE server_1 | npm ERR! errno 12 server_1 | npm ERR! app@1.0.0 dev: `next dev` server_1 | npm ERR! Exit status 12 server_1 | npm ERR! server_1 | npm ERR! Failed at the app@1.0.0 dev script. server_1 | npm ERR! This is probably not a problem with npm. There is likely additional logging output above. server_1 | server_1 | npm ERR! A complete log of this run can be found in: server_1 | npm ERR! /home/node/.npm/_logs/2019-09-08T14_07_48_368Z-debug.log example-next-typescript-with-vscode_server_1 exited with code 12
VSCode debugging
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Docker: Next.js", "type": "node", "request": "attach", "remoteRoot": "/home/app", "protocol": "inspector" } ] }
VSCodeのDebugから、Docker: Next.js
を実行します
pages/index.tsx
にブレイクポイントをおくと止まってくれるはずです
Enjoy Next.js ヘ(^o^)ノ
GR-CITRUS ミニハッカソン in OSAKA に審査員として参加した
GR-CITRUS ミニハッカソン in OSAKA に審査員として参加してきました
IFTTTを使ったIoTなものから、アイディア満載の作品などどれもレベルが高かったです!
個人的にもいい刺激をいただきました!
でもね、スタッフとか審査員とかで参加した場合、みなさんが楽しそうに作業してるのみてムズムズするわけで、、
てなわけで、僕もLチカにチャレンジしました
GR-CITRUSのLEDをチカチカさせてみます
@kimu_shu さんが作られた Rubic を使っていざ!
サポートしてくれたのは @ogomr さんと @kimu_shu さん(豪華!
Rubicはよくできていて、ボードやファームウェアなんかをポチポチ選択していくと実行環境ができちゃいます!
以下、個人的なメモ
Rubicを追加する
- vscodeで
Ctrl + P
ext install kimushu.rubic
を入力してEnter- インストールが終了したら
reload
する
Rubicの設定
- vscodeで
F1
rubic
で検索Show Rubic board catalog
を選択
ボードを選択
GR-CITRUS
を選択
ファームウェアのリポジトリを選択
Wakayama.rbのリポジトリですね
ファームウェアを選択
- 最新のv2.40を選択 (ハッカソン当日リリースされた!
Configuration
LチカなんでミニマムでOK
ファームウェアの書き込み
ここでデバイスが表示されるはずが、、されてない
@kimu_shu さんに聞いてみると、パーミッションじゃないかなとのこと!
僕の環境はLinuxだったので、デバイスファイルに read, write 権限が必要みたいです
なので以下はLinux環境のみ作業が必要
GR-CITRUSは ttyACM0
ってなファイル名らしいので
$ ls /dev/ttyACM* /dev/ttyACM0 $ sudo chmod 666 /dev/ttyACM0
でも、デバイスを外すとパーミッションが元にもどっちゃうのでめんどくさいから
# /etc/udev/rules.d/50-udev-default.rules ERNEL=="ttyACM[0-9]*", GROUP="murajun1978", MODE="0666"
ってしておくと抜き差ししても大丈夫!
でわ、ファームウェアを書き込みます
Write firmware to boad
をクリック- 確認ポップアップがでてくるので
yes
を選択 Push reset button on GR-CITRUS
ってポップアップがでたら GR-CITRUS のリセットボタンを押すOK pushed
をクリック- LEDのチカチカ(ファームウェアの書き込み中)が終わると
OK, confirmed
をクリック
コネクションテスト
Test connection
をクリック
テスト成功のポップアップが表示されたら終了
これで環境がととのいました!
コードを書く
僕は lchika
ってディレクトリ配下にmain.rbを作成しました
# lchika/main.rb class Lchika def initialize(lchika_count) @lchika_count = lchika_count end def run @lchika_count.times do led delay 1000 end end end lchika = Lchika.new(3) lchika.run
実行する
- vscodeで
F5
僕のサンプルだと3回チカチカがするはずです
楽しかった!個人的にはスマートスピーカーを自作してみたいなー
Google AssistantやAmazon Alexaなんかでね
みなさま、お疲れ様でしたー
Rails Follow-up Osaka #13 を開催したヘ(^o^)ノ
rails-follow-up-osaka.doorkeeper.jp
会場提供は株式会社エイチームさんでしたーヽ(´▽`)/
ありがとうございましたっ!
localhostでsubdomainのURLにアクセスしてデバックしたかったようなのでサポートできたかな?
e.g.
# config/routes Rails.application.routes.draw do constraints subdomain: 'admin' do resources :todos end end
/etc/hosts
に 127.0.0.1 admin.localhost.local
を追加してあげることで解決できた。
$ sudo vi /etc/hosts e.g. 127.0.0.1 localhost 127.0.0.1 admin.localhost.local 255.255.255.255 broadcasthost ::1 localhost
今回の場合とかはDockerを使って開発した方が良いのかもしれないです。
Enjoy Rails ٩( ‘ω’ )و