Deveroper メモ

記事内容に絶対の保証はなく..どちらかというと自分用のノウハウ蓄積ページ。 それでも良ければ見ていってください。

Gunma.web #38

gunmaweb.connpass.com

初のオンライン開催という事で色々とドキドキしながらも無事開催できたという感じです。

オンライン

ビデオチャットは zoom を使いました。 比較的、ここはスムーズに出来たかな?と。 ただ、人数と料金のバランスを見ると google meet でもよかったような...という反省点です。 (google meet の方が安い)

発表中の盛り上げは comment screen を使いました。 こちらも比較的盛り上げることに成功したのですが...これをやると twitter で盛り上げる手が追いつかないというオチが.. みんなどうやってたんだろう?

他の人の発表

gunmaweb.connpass.com 今回も色々な話が聞けてうれしかったです。

とりわけ、slack app開発のフレームワークの話は自分でやる時の参考になりそうですし
web管理画面から伝票を出す仕組みは驚きでした。(youtubeの動画)

自分の発表

自分はPWAの今さら聞けない話を発表しました。 正直、応用的な技術は発表できませんでしたが、基本はやり切った感があります。 また、解りづらい点などツッコミ下さい要望にも忌憚なく意見を言っていただいたので、参考になりました。 ありがとうございます。

speakerdeck.com

では、みなさんまた次回にお会いしましょう!

devsumi 2020

久々に devsumi 2020 に参加しました。

  • 前提として...刺激になる講演が多く、ほとんどが為になりそうなものでした。
  • 自分が聞きたかったものがそういうベクトル? になっていたのか、解りませんが、登壇者は違うのですが発表されてる内容がフラッシュバックしまくってました。
  • その中でも特に印象に残ったものを ブログに残します。

世界最高の靴売場をシューカウンセラーとともにデジタル変革してみた

発表者

  • 鈴木 雄介
  • 河村 明彦

三越伊勢丹グループにおけるDX推進

三越伊勢丹 の靴売り場とは?

  • 世界的に有名なお買い場
    • 売上: 62億円/年
  • 三越伊勢丹用語
    • お買い場 = 売場
    • スタイリスト = 販売スタッフ

yourfit 365 を作った時の話

道のり

2年間、模索期間

  • シューカウンセラー
    • 三越伊勢丹が独自に整備した資格制度
    • そもそも足に合う靴を提供したいという文化があった
  • スキルさを埋めるために 3D計測が使えるのでは?という仮説があった
  • 2年間、計測し続けて...
    • 計測精度が高い
    • トライヤル期間を得て「勝てる」と確信
    • ここまですべて現場(お買い場)の予算でやった。
  • アジャイルの開発手法でやる事に...
    • 企画からのTOPダウンではない
    • 現場と やりとりすべき
    • 現場(お買い場)の担当者を情報システムに異動
      • この人が PO を兼ねる
      • システム開発の経験がないためPOを支援するメンバーを入れる
  • お買い場 <-> PO <-> 開発チーム

立ち上げ

  • ワークショップを開催
    • 関係者全員が参加
    • バイヤー、マネージャー、シューカウンセラーなど
    • ビジョンと優先度を共有
  • データを入手
    • 木型を集める
      • レコメンドには木型が必須
        • 足形と比較するよう
      • 来門外不出
        • 靴の設計書と同意義のためコピーが作られてしまう
          • メーカが渡さない
        • 過去からの信頼もあって貰えた
  • 現場(お買い場)とともに
    • スタッフ全員がやる気になる
    • サービス名、デザインなどスタイリストが選定
    • 頻繁にデモしていく
      • 実際に使いながら意見をもらう
      • 不必要なものがなくなった
  • 業務とITを同時に検証
    • システム側の都合で業務が変わる部分が明確になる
    • その逆もある
  • 実質3ヶ月で初期リリース
  • 8/28 にリリース
    • メディアにも取り上げられる
      • 数十件/日
      • 接客には 1.0h-2.0h
    • 継続的な機能改善
      • 最小機能でリリースしたため日々のフィードバックを毎週リリース
      • 小さく出して大きく育てる

次にむけて

  • 開発をストップして考えるフェーズにする

    • どうすれば価値が上がるか?
      • どう利用されて、何があれば便利か?
      • 何をすれば満足度を下げずに効率化できるか?
    • ユーザビリティ調査
      • 閉店後にお客様を招いて行動観察
        • 改めて検証する事で意見が多数
  • 再来店を促す

    • 夏に買ったお客様が秋冬の靴を買いに来る
    • 同じ木型は安心して買える
    • 明らかにコンバージョン率が高いため自動化を実施中
  • 足形から靴を作る
    • 市販靴の領域でカバー出来てないものが明らかに
    • その靴に合う人むけにプロモーションを予定

ともにつくるとは?

  • 当事者意識を持って行動する
  • 当事者にならない人は不要
    • 企画部門問題
    • 「それAIで」問題
      • 定義がないのに、何がAIか!?
  • お客様から学んで改善する
  • 当たり前だけど難しかった
  • アナログと、ともにつくる
    • デジタルが中心ではない
    • 両方がいい方向に成長するよう
  • 既存組織とともに作る
    • 適度な自治権
    • 距離感が重要
      • 既存に影響されてスピードがでない
      • 既存と切り離しすぎてもスピードが出ない

「ともにつくる」を実践するドメイン駆動設計

発表者

DDD(ドメイン駆動設計) の必要性

こんな経験ありませんか?

  • 新しいシステム使いづらい
  • 大金かけたのに使えない
  • 経営グループと開発者と利用者で情報が断絶
  • 大した修正じゃないのに時間かけすぎ
  • あの人バグ多いよね

どうして起きるのか?

  • 詳しい人がいない
  • 仕様書がない
    • 仕様を探す旅に出ます
    • つまりコードを追っていきます
  • コードを見ても解らないと旅が長くなります

ドメインって何?(よくDDDの本に出てくる用語の解説)

  • URLに出ているあのドメインじゃないよw
  • この領域、このエリア
    • 配達の仕組みで言うと
      • 荷物
      • 集荷センター
      • 輸送トラック
  • 何が重要か?は企業によって異なる -> 知識
  • 知識をモデルに落とし込む = モデリング
  • モデルをコードに落とし込む = ドメインオブジェクト
  • ドメインを知るのは誰? = 実際に運用してる人
  • 実際に運用してる人 = ドメインエキスパート
  • 実際に運用している人と共通言語を決める
  • 共通言語 = ユビキダス言語

ドメインエキスパートであってもドメインはぼやける

  • 厳密に定義されてない場合がある
    • 企画: お客さんに荷物がどうなってるか?知ってもらいたい
    • ドメインエキスパート: 解りました。from と to をcommit してlogに残すようにします。
    • 企画: ??? うん。とりあえず、それで...
    • 結果: 中継地点を通ったという記録しかないので、配送全体のステータスが解らない
    • 本当に必要なもの: 発送(xx:xx) -> 集荷センター(xx:xx) -> xxに配送中(xx:xx)いまここ -> お客様
  • 行き違いが起きやすい
  • 共通言語は作る側が主体となってやるべき
    • ドメインがぼやけていると自覚出来るのは誰なのか?

構成要素

  • 分け方(例)
    • backend と front や ビジネスロジック と データレイヤ
    • 開発チームが別れる
    • コンテキストマップが補助になるはず

経験談

  • ドメインの把握は難しい
    • 一人じゃ出来ない
    • 開発チームだけでも出来ない

受注開発時代...

  • 製鉄所システム
  • 鉄の焼き方, 冷やし方
  • ただワンパターンに焼いて冷やせばいいというものではなかった
  • しかも長年勤めている人にじっくりヒアリングしてようやく出てきた
    • 冷やし方に複数のパターンがある
    • 相手の受付窓口の人だけじゃ出てこなかった

言うは易し、行うは...

  • 開発作業をやりながら出来るの?
  • でも、やりたいよね?
  • どうやるか?
    • 色んな人を巻き込みながら
    • DDD の必要性を説きながら

プリンシプル・オブ・“ともにつくる”~ Web Performerを支えるドクトリン ~

はじめ延々と 前座を語られる..前座がメインかってくらい(心理学系)

我と汝、我とそれ

  • 我と汝
    • 相手を人間として扱う
    • 相手も自分を人間として扱う
  • 我とそれ
    • 相手を人間として扱わない
      • 例: 自分がお金を払う側の場合
      • 人を使って当たり前と接する
      • 相手もお金を払うマシーンとして扱ってくる

シニフィアンシニフィエ

  • シニフィアン
    • 「海」という文字や、「うみ」という音声
      • free = 自由 と 無料 という曖昧さをもつ(一つの意味ではない)
  • シニフィエ
    • 海のイメージや、海という概念、ないしその意味内容

無知の知

  • 無知にも大きく二つに別れる
    • 既知の無知
      • 自覚がある部分
      • 知らない事を知っている
    • 未知の無知
      • 自覚がない領域
  • 自分が無知である事を知る
    • 謙虚な姿勢

Web Performer(ほんのちょっと)

  • canon の開発ツールの話
  • GUI からDBのモデルを自動生成 -> java?

プロダクトを10年運用するチームをつくる

発表者

  • 粕谷 大輔さん
    • はてな
    • Mackerelチームディレクター

Mackerelの話

変化し続ける周辺環境とシステム

  • 格言: 動いているシステムは触るな
    • NG
    • 触らざるを得なくなる
      • os update
      • security
      • 他社と通信する系
        • 他社が新しいものを作ってくる
      • ブラウザのupdate
  • CI/CD
    • テストの自動化, デプロイの自動化
  • 監視の整備
  • devops の構築
    • 開発と運用は表裏一体

人の入れ替わりへの対処

  • 異動や退職、新陳代謝
  • プロダクト固有のスキル, ドメイン知識
  • スキルマップ
    • 誰がいなくなると、どこのスキルが失われるか?が解る
      • 人によっては、複数のスキルが一気に失われるので回らなくなる事に気付ける
    • 学習目標の指針になる
    • 運用のコツ
      • 評価には使わない
      • 正直に答えてもらう事が重要
      • 項目の粒度を気にしない
        • 粒度を気にすると決まらない
        • 一旦は慣れている粒度でやる
      • 定期的なメンテナンス
  • 障害対応
    • 属人化しがち
      • 古参メンバーの独壇場
      • 新規メンバーはなかなか入り込めない
      • そもそも緊急事態なので丁寧に教育していく暇がない
    • なので演習を行う
      • ステージング環境をわざと落とす
      • 頻度
        • 半年に一回
        • 今まで障害対応してこなかった人を中心に参加させる
      • 何が出来ないか?が解る

式年遷宮

  • 元々は...
    • 神社などにおいて周期を定めて社殿を更新する
    • 新たな社殿に神体を移す
  • 定期的に社殿を建て替える
    • 隣にまったく同じものを建てる
    • 宮大工の技術継承
    • 社殿の姿が恒久的に維持される
  • ソフトウェアの場合
    • アーキテクチャフレームワークなどシステム根幹部分に手を入れるようなプロジェクトを一定間隔で行う
    • モダンなソフトウェア環境への適応
    • エンジニアの技術継承
      • 前パートの「人の入れ替わり対処」も兼ねる
  • 現実の式年遷宮と異なりフルスクラッチではない。
  • スケールアップへの対処。
  • エンジニアの技術継承

apng を python で見つける

python でバイナリーを解析する勉強がてらに書いてみました。

qiita.com

crc32 の使い方など、中々いいトレーニングになったかな?

オチとしては 既にきちんとした ライブラリ が出回っていた点かな苦笑

目的は達成したので結果オーライ。

require('vue') する時の注意点

目的

  • Vue.js を require して使う時のメモ書き(エラーになる時 ならない時)
  • webpack を使う時

エラーになるパターン

// src/main.js
const Vue = require('vue')

//...
// webpack.config.js
const path = require('path');

module.exports = {
  mode: 'production',
  entry: {
    main: './src/main.js',
  },
  output: {
    filename: '[name].js',
    path: path.join(__dirname, './dist')
  }
}

エラーにならないパターン

// src/main.js
const Vue = require('vue')

//...
// webpack.config.js
const path = require('path');

module.exports = {
  mode: 'production',
  entry: {
    main: './src/main.js',
  },
  output: {
    filename: '[name].js',
    path: path.join(__dirname, './dist')
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.common.js'
    }
  }
}

resolve 以降がミソ

参考元

vuejs.org

詳しくはここに書いてある。

  • Runtime + Compiler vs. Runtime-only の箇所

以前のbingoゲームを Vue.js で書き直す

以前書いた bingoゲーム

GitHub - kanayannet/bingo: bingo game helper

を Vue.js を使い 勉強がてらに書き直して見ました。

github.com

やってみての感想は 前回が データを整形するアルゴリズムの部分 と DOMにデータを反映するコードが一緒くたになってしまったのですが、今回は比較的分離する事に成功しました。

( そうする事で データを整形するアルゴリズムの部分だけにテストコードを適用できる )

なぜやり易かったのか、振り返って見ると..

変数の値を書き換えるだけで view(dom)の書き換えを自動的に行ってくれるポイントが大きかったように見えます。(双方向のデータバインド)

jquery だけの場合 変数の値を書き換える -> DOM にその情報を渡す という二つのコーディングが必要ですが( 非同期処理内で行うと 一緒くたになりやすい) Vueの事前に宣言しておくだけで双方向のデータバインドが可能になる方法だと 非同期処理内では データ書き換えだけを行えば良く上手くいきました。

言葉にすると解りづらいのですが(汗) コードを比較すると解ると思います。

 

おまけ: 非同期処理のテストコードを jest で書いたのですが、setInterval した後の値の評価を どうしたら良いか始め解らなかったのでついでにここに記します。

http://jestjs.io/docs/ja/timer-mocks.html

非同期処理が全て走った後, 非同期処理が何回繰り返した など 拾え(コントロールできる)て便利です。

Jest で Promise

そもそも Promise をきちんと理解してなかったのが原因なのですが..

このサンプルページを見てもイマイチ理解できなかったのでメモ。

doc.ebichu.cc

ここで表示されてるサンプルコードはコピってもそのまま実行できません(汗)

まあ、理解してやってくれということだろうね。

 

そこで他の Promise のページなどを見ながら自分なりに理解し..

テストが通るコードを作成したのが↓

let async = (data) => {
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve(data);
    }, 3000);
  })
};

test('the data is peanut butter', () => {
  expect.assertions(1);
  return async('peanut butter').then((data) => {
    expect(data).toBe('peanut butter');
  });
});

 

 出来た!

copy event 色々..

copy event が絡んだ実装を勉強がてらにして気がついた事をつらつらと...

 

通常

$(document).on('copy', function(event) {... 

しかしこれだと、IE8 が発火せず(汗)

ところが下記に変更したら動いた(何故だ)

$('body').on('copy',function(event){... 

また、選択中の文字も

通常

window.getSelection().getRangeAt(0); 

 で取得可能だがIE8では対応できないので下記に変更

try{

      data = window.getSelection().getRangeAt(0);

}catch(err){

      data = document.selection.createRange();

};

ユーザのコピーイベントをoverride したいので 

e.preventDefault したかったがこれもNGなので下記にする

try{
      e.preventDefault();
}catch(err){
      e.returnValue=false;
}; 

なんだが、当初より長いコード&サポート大変そうな感じ。

以上、ちょっとしたメモ書きでした。