【現場で役立つシステム設計の原則】データとドメインモデル

最近、現場で役立つシステム設計の原則をよみ直している

データベースにはコトを、ドメインモデルには業務ロジックを記述していく

このことを考えるとデータベースをアップデートすることは、マスターデータ以外はそうはなさそう

例えば、商品名は変更することはあるけども、購入データを変更することはない

購入したという事実をデータとして登録するだけだからね

わかりやすい例を書いてくれていた

年齢という関心事があると、年齢というクラスが必要になる

でも、データはコトなので生年月日が登録されている

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のスピーカーを見た瞬間にチケット購入したイベントに参加してきました!

jsconf.jp

チケットを買ったときに聞きたかったセッション は以下

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) => 明神岳にチャレンジしてきました!

入り口はこんな感じ f:id:murajun1978:20190929092336j:plain

第1印象はけっこう激坂!

心拍数はあがりましたが、筋トレの成果もあり足は余裕でした!

だた、40分ほど登ってるとやっぱり心臓が悲鳴をあげてきます、、

それでも、Max 165でした

心拍数が振り切れなくなったのは、ジムに通っている成果なのでしょうか? (きっとそうです

休憩しながら登りきると明神平に到着

f:id:murajun1978:20190929111411j:plain

まわりに自分がいるとこより高い山があって、あんま登頂感はないですww

お昼ゴハン食べて、いざ明神岳へ!

僕が先導したのですが、ルート間違えたみたいで前山へ向かってましたw

10分ほどで制覇!w

そこから明神岳へ向かいました

明神岳 (1,432m)

途中、川を渡ったりして楽しかったなー

予報では雨だったせいか、登山者は少なめでしたねー

下りは相変わらず膝にきます、、(ダイエットせねば\

登った印象は、ひたすら登りが続く感じでした

ただ、絶壁みたいなのはないので、楽しく登れるはずです(はずです

あと、川を渡らないとダメなので、雨とかで増水してるとキビシそうですね

ちがうルートもあるみたいなので、また登ってみたいと思います

Enjoy Climbing ヘ(^o^)ノ

GitHub Registryが使えるようになったので、Next.jsのDocker imageをPushしてみたヘ(^o^)ノ

GitHubからWelcome to the beta of GitHub Package Registryメールが来たので試してみた

GitHub Package Registryにpushできるものは ↓ リンクを参照してください

help.github.com

今回はNext.jsのDocker imageをGitHub Package Registryにpushしてみました

サンプルコードはこちら

github.com

/packages にアクセスすると、パッケージ一覧が確認できます!

Next Actionとしては、GitHub Actionsを使ってAuto Deployできるようにしようかなー

ちょっと気になるのが、Betaだからなのか、僕のネットワークがクソなのかわかりませんが、no such hostなるエラーがちらほら出ました、、

サンプルコードはPublicですが、もちろんPrivateリポジトリでも利用できます!(これはめっちゃいい!!!!

Privateリポジトリの場合は、writeはもちろんread時もaccess tokenが必要になるのでお気をつけを

この辺 ↓ を参考に設定すれば大丈夫かと思います

help.github.com

Enjoy GitHub Package Registry ヘ(^o^)ノ

Docker Container上のNext.js with TypeScriptなAppをVSCodeでDebugする

Docker containerで動作しているNext.jsをVSCodeでDebugしてみました

サンプルコード

github.com

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"
  },
  ...
}

nodejs.org

↑ ここのドキュメントにも書いてますが、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

.vscode/launch.json

{
  // 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 に審査員として参加した

connpass.com

GR-CITRUS ミニハッカソン in OSAKA に審査員として参加してきました

IFTTTを使ったIoTなものから、アイディア満載の作品などどれもレベルが高かったです!

個人的にもいい刺激をいただきました!

でもね、スタッフとか審査員とかで参加した場合、みなさんが楽しそうに作業してるのみてムズムズするわけで、、

てなわけで、僕もLチカにチャレンジしました

GR-CITRUSのLEDをチカチカさせてみます

@kimu_shu さんが作られた Rubic を使っていざ!

サポートしてくれたのは @ogomr さんと @kimu_shu さん(豪華!

Rubicはよくできていて、ボードやファームウェアなんかをポチポチ選択していくと実行環境ができちゃいます!

以下、個人的なメモ

Rubicを追加する

  • vscodeCtrl + P
  • ext install kimushu.rubic を入力してEnter
  • インストールが終了したら reload する

Rubicの設定

  • vscodeF1
  • rubic で検索
  • Show Rubic board catalog を選択

ボードを選択

f:id:murajun1978:20180211062152p:plain

  • GR-CITRUS を選択

ファームウェアリポジトリを選択

f:id:murajun1978:20180211062510p:plain

Wakayama.rbのリポジトリですね

ファームウェアを選択

f:id:murajun1978:20180211062757p:plain

Configuration

f:id:murajun1978:20180211063215p:plain

LチカなんでミニマムでOK

ファームウェアの書き込み

ここでデバイスが表示されるはずが、、されてない

@kimu_shu さんに聞いてみると、パーミッションじゃないかなとのこと!

僕の環境はLinuxだったので、デバイスファイルに read, write 権限が必要みたいです

なので以下はLinux環境のみ作業が必要

GR-CITRUSttyACM0 ってなファイル名らしいので

$ 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"

ってしておくと抜き差ししても大丈夫!

でわ、ファームウェアを書き込みます

f:id:murajun1978:20180211064951p:plain

  • Write firmware to boad をクリック
  • 確認ポップアップがでてくるので yes を選択
  • Push reset button on GR-CITRUS ってポップアップがでたら GR-CITRUS のリセットボタンを押す
  • OK pushed をクリック
  • LEDのチカチカ(ファームウェアの書き込み中)が終わると OK, confirmed をクリック

コネクションテスト

f:id:murajun1978:20180211064951p:plain

  • 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

実行する

僕のサンプルだと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/hosts127.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 ٩( ‘ω’ )و