のんラボ

@storybook/addon-actionsを利用したときのTips

2020/08/10 2020/08/13

@storybook/addon-actionsを利用したときのTips こんにちは。Nonです。 最近、フロントのこともガッツリと関わるようになってきました。デザインのセンスはあまりありませんが、デザインシステムがどれだけ有効なのかは、UIデザインについて少し調べてみた。の記事ですでに記述しています。 そのデザインシステムをまとめ、管理するためにstorybookを採用したのですが、そのaddonである@storybook/addon-actionsを導入したときにハマったtipsを記載しようと思います。 actionが起動しない問題 これは私がjavascriptの理解が浅いせいなのですが、下記のように書くとactionが起動されず、 storiesOf('Button', module) .add('default', () => ({ components: {Buttons}, template: '<Buttons @click="action"></Buttons>', methods: { action() { // 起動しない action('clicked'); } } })); 下記の様に書くと、起動します。 storiesOf('Button', module) .add('default', () => ({ components: {Buttons}, template: '<Buttons @click="action"></Buttons>', methods: { action: action('clicked') /* 起動する*/ } })); これ全然わからない。 誰か知っている人いたら教えて下さい。 storybookって便利 お試しに作成しただけですが、https://storybook.nozomi.bike/に自分のデザインストーリーを作って公開してます。 storybookで何ができるかを知るにはちょうどいいし、それをどのように使っているのかをしれていいと思います。 公開されているstorybookでもっといいものはたくさんあるので、それを探すのも面白いですよ。 最後に 今回はとても短い記事ですが、内容はかなりハマったことでしたので、許してください。 なぜこれが駄目だったのかわかったときは、この記事を更新します。 その時はよしなに。 .

laravel-mixでjavascriptのコンパイルをするときのTips

2020/08/05 2020/08/05

laravel-mixでjavascriptのコンパイルをするときのTips こんにちは。Nonです。 今回は正直Laravelのドキュメント読めば分かる内容なので、みんなの力になれるかどうかわからないです。 私の備忘録ついでという感じになると思います。 laravel-mixでVueを作成するときapp.jsが作成されます。 このとき、app.jsをbladeで読み込むとき、おそらくこう書くと思います。 <script src="{{ asset('js/app.js') }}"></script> しかし、上記のように読み込んでしまうと、リリースされるたびにapp.jsの中身は違うのに、ブラウザのキャッシュのせいで以前のバージョンを読み込んでしまいます。 そこで利用するのはmix()です。 <script src="{{ mix('js/app.js') }}"></script> このようにすると、Laravelのpublic/mix-manifest.jsonの中身を使用してapp.jsなどを読み込もうとします。 { "/js/app.js": "/js/app.js", "/css/app.css": "/css/app.css" } しかし、このままだと変わらずキャッシュが効いてしまうことになるので、javascriptのコンパイルをするときに、public/mix-manifest.jsonの内容が一意になるようにします。 具体的にはwebpack.mix.jsを中身を修正します。 一番最後の行に下記を追加します。 if (mix.inProduction()) { mix.version(); } このようにすると、npm run prodなどの本番環境にデプロイするCIで一意なキーを持ったpublic/mix-manifest.jsonを作成することができます。 作成したpublic/mix-manifest.jsonはこちら。 { "/js/app.js": "/js/app.js?id=d2353c498302a1106cf8", "/css/app.css": "/css/app.css?id=0ec4c3ecb9972406f852" } こうすることで <script src="{{ mix('js/app.js') }}"></script> <script src="{{ mix('css/app.css') }}"></script> 上記のコードは?id="d2353c498302a1106cf8"を含むリンクとなります。 idは一意なキーなので、npm run prodを利用してデプロイするたびに新しいファイルをサーバーへリクエストします。 開発環境でも同様のことが行いたい場合は、 if (mix.inProduction()) { mix.version(); } からif文を削除すれば大丈夫です。 mix.version(); (adsbygoogle = window.adsbygoogle || []).push({}); 最後に 今回は備忘録ついてでに記事を書いてみました。 これを知るまではServiceWorkerを利用して遠回りに更新してました。。。 ブラウザのキャッシュをServiceWorkerでクリアする処理を書いてました。これを知ったときには何故こんなに初歩的なことを知らなかったのか恥ずかしかったです。 ということで今回はここまで。 次回はStorybookの記事を書いてみようと思います。 その時はよしなに。 .

リリース内容を小さくしたらいろんなメリットがあった話

2020/07/26 2020/07/29

リリース内容を小さくしたらいろんなメリットがあった話 こんにちは。Nonです。今回はリリースする内容を小さくしたら色々なメリットがあった話をしようと思います。 とは言っても、すでにdevsOpsやマイクロサービスが浸透してきているので、リリース内容が小さい方が良いというのは知っているかもしれません。 ここでは、やっぱりやってよかったよねという話にしていきたいと思っています。 1. リリースを小さくしたらバグが減った リリースを小さくするということは実装する機能の数が減るということです。ということは、制限時間内に(納期までに)開発者が向けるべき関心事が減るということですね。 正直、この内容をシェアしたくてこの記事を書いたまであります。 リリースが小さくなったので、リリースまでの納期は短くなります。しかし、自分が注力すべき内容が小さいので、その全てに全力を注ぐ事ができます。そのおかげで、明らかに今までのコードより品質が高くなりました。QAチームからのフィードバックも減り、実装コストだけではなくて全体のコストも減りました。 やはりバグ原因での手戻りが少ないとストレスも減って進捗がいい方向に向いていくことを実感することができました。 2. リリースを小さくしたらマネジメントしやすくなった 1と同様に、関心事が減るので、把握すべき進捗の内容が減りました。おかげで今までおざなりになっていたプロジェクトの進捗の把握もかなりしっかりできて、ほぼ計画どおりのプロセスを踏むことができました。 (この案件では私が実装兼PMみたいな感じ) こうなると、マネジメントする側にもかなりのメリットがアルのではないでしょうか?進捗管理という事務作業が一気に減ることになりますんので、本来PMがすべき真の意味のプロジェクトマネジメントを遂行することができます。 追記するとPMはプロジェクトの進捗管理をするだけの役職ではないと個人的に思っています。 このことに関しては賛否あるかもしれません。 私もPMについてしっかりと勉強できているわけではないので、おかしな点があるかもしれません。簡単に書くとPMは POから欲しいと言われた機能を吟味し、取捨選択する 機能についてメンバーに割り当てる 機能から更に分割されるであろうタスクはメンバーが決めるもの 機能について終了日のあたりをつけ、QAとの連携をとる リリースにあたって他のプロダクトとの影響について調査する この辺ではないかと思っています。 何やら一般的にはスケジュールばかりに目が行っていますが、どう考えてもそれは副産物で、メンバーとの折衝、他のチームとの折衝こそがPMの本来の仕事のはずです。(だからコミュ力が求められるのだと思います。) 上述した内容を遂行した結果、たまたま進捗管理をしていたというだけだと思います。 逆に言えば、他の影響範囲との摩擦がなければリリース日なんて「完成した日」になると思ってます。 3. リリースを小さくしたらスピードが上がった(たくさんのピリオドを打てる) マラソンを走るスタイルで、ダラダラと開発をしていたのが、パッと開発してストップ、パッと開発してストップ、の連続になりました。メリハリが効いてピリオドも明確に打てる。何かあったときのトラブルにも強い印象になりました。 ピリオドを打てるというのはとても大きくて、終わったら前回の反省をすることができます。対して、長ーいスパンで開発すると、その途中で反省会をしてもあまり意味がないように思えます(経験)。 長ーいこと開発を続けるよりも、キチンとピリオドを打って、終わったよということを表明できるのはメンタル的にも優しい気がしました。 最後に リリース内容が大砲の弾のように大きくて必死こいて弾を運んで、外したらOUT。みたいなのより、リリース内容は小さくして気軽にパパパパっと打てるサブマシンガン的な手法の方が手軽でいいです。 小さい分、何回も繰り返してリリースすればいいですし。 この取り組みは今後も続けていきたいです。 今回は私の主観が多めでした。 次回は何書こうかまだ決めてないです。でも記事にはします。 その時はよしなに。 .

車輪の再発明は悪なのか?

2020/07/24 2020/07/24

プログラマが知るべき97のこと こんにちは。Nonです。本日はプログラマが知るべき97のことを読んでいてこれ「いいな」と思った箇所について書いてみようと思います。 こちらの書籍はとても有名なので、既読の方もいらっしゃるかもしれません。 そういう方は復習というか、内容を思い出したり、私の意見と違うところや共感できるところを探していただければ幸いです。 プログラミング業界では車輪の再発明は悪と見られがち? 一度作成されたコードを再作成することはしばしば嫌がられる傾向にあるのがプログラミング業界です。例えば、Bootstrapを導入しているプロダクトでモーダルを表示する処理を自作する意味はあまりないでしょう。 もしあるとすれば、 Bootstrap依存(jQuery依存)をしたくない すでにある機能のテストを再度したくない などでしょうか? もちろん、その中にはDry原則もあるでしょうが、Dry原則とはそもそも Don't Repeat Yourself なので、自分自身のコードの中で同じような処理を作成することはアンチパターンだよってことを示していると思います。 あとはOSSにあるツールなどを知っているパターンでしょうか。 OSSに実装したい機能とほぼ同じものがある場合、そちらを利用したほうが遥かに効率がいいからです。 では車輪の再発明にメリットがあるときはどのようなとき? しかし、実は私は車輪発明は大好きです。何故かというと車輪の再発明はとても勉強になるからです。 車輪の再発明で得られるものは多いです。 たとえば、モーダルを表示するために必要な技術は何か?表示するときにアニメーションを入れるにはどうすれば良いのか?このようなことを勉強するにはうってつけです。 更にその機能の構造や動きを理解することで、その機能を利用するときに気をつけるべきことやどのように利用すれば気持ちよく動作するかがわかります。 独自フレームワークは嫌われやすい 似たような話に独自フレームワークがあります。 今大抵のプログラミング言語にはフレームワークがあります。 黎明期の頃はフレームワークが充実していなかったので独自フレームワークを作成することがはやっていましたが、今では特殊な案件以外ではありえません。 しかし、独自フレームワークを作った人はフレームワークの構造を理解しています。 例えばWEB用のフレームワークを作成した人はリクエストとレスポンスを捌く部分についてよく知っているので、どう捌けば良いのか、どのように作れば良いのかを(作ったことがない人より)知っていることでしょう。 もしかしたら、独自フレームワークを作ったことがある人こそ、人気のフレームワークの便利さを一番理解しているのかもしれません。 最後に 実際のプロジェクトで何も考えずにパッケージが導入されていることはよくありますし、用途が重複したパッケージが導入されているものも見たことがあります。 これは、パッケージの特性を理解しないまま「ただできるから」、それだけの理由で導入したのでしょう。 そういうことが無いように、すでにできている車輪を使うだけでなく、その構造と使用方法を理解した上で使えるようになりたいですね。そしてそのためには車輪を自分でも作れる必要があるのではないでしょうか? ここまで書いておいてなんですが、私個人の意見です。 次回もプログラマが知るべき97のことを読んで記事にしようかなと思っています。 その時はよしなに。 .

ユビキタス言語を重視する

2020/07/13 2020/07/13

プログラマが知るべき97のこと こんにちは。Nonです。本日はプログラマが知るべき97のことを読んでいてこれ「いいな」と思った箇所について書いてみようと思います。 こちらの書籍はとても有名なので、既読の方もいらっしゃるかもしれません。 そういう方は復習というか、内容を思い出したり、私の意見と違うところや共感できるところを探していただければ幸いです。 ドメインの言葉を使ったコード 突然ですが、DDDではユビキタス言語という業務上の言語を反映することが大事だよ。ということが言われています。 ユビキタス言語ってなに? ユビキタス言語というのは、プログラミング設計をする上で、開発者だけでなくその他のステークホルダーとの共有言語のことを指します。 例えば、荷物の運送管理システムを使用する時、開発者はよくユーザーという言葉を利用しますが、ステークホルダーは運転手という言葉を利用するとき、やはりシステムでも運転手という言葉を利用する方がいいでしょう。 そして、開発者が運転手という言葉を利用するというのはコードにも反映するということになります。 例えばユーザーが荷物を運ぶ処理を持っていたとすると、 <?php class Driver { /** * @var int */ private $id; /** * @var string */ private $name; public function __construct(int $id, string $name) { $this->id = $id; $this->name = $name; } /** * @param Luggage $luggage * @return void */ public function transferLuggage(Luggage $luggage) { // 荷物を運ぶ処理 } } となります。クラス名はUserではなくDriverとなりますね。 ではログイン処理ではどうなるでしょうか。 境界付けられたコンテキストの観点からみると、ログイン処理は業務知識とはまた違うドメインになりますので、この場合はDriver->login()ではなく、User->login()の方がいいでしょう。 このように、業務知識内の言葉を利用することで、プログラムコードと実際にミーティングなどで利用される言葉の乖離を防ぐことで、ユースケースの齟齬、つまりユーザーとの誤解を避けるために作成され、使用する言葉のことを指します。 プログラムコードに仕様を書き込むとは? こちらもしばしば見かける内容です。 仕様書を作成しないという意味ではありませんが、できるだけプログラムコードに仕様を反映するということは結構前から言われていたように思います。 キーワードは私の知る限り3点。 ビジネスロジック 抽象クラス ユビキタス言語 でしょうか。 ビジネスロジックで仕様をコードに表す ビジネスロジックで仕様をコードに表すとは何か?2020年に突入した今なら、すでにご存知の方もたくさんいらっしゃるでしょう。 私はこれまで色々なプロジェクトを経験してきましたが、とにかく、コントローラーだけで実装を終了していたり、プログラムコードの示す目的がコードに反映されていないコードをたくさん見ました。 だから、「コードの仕様を先輩に聞いたり」、「なぜ、このコードが必要なのかを議論する」必要があったのです。 試しに例を作成してみました。 class TransactionController { public function store(Request $request) { // バリデーション処理など $user = Auth::user(); Transaction::create([ 'user_id' => $user->id(), 'product_name' => $request->get('name'), 'product_price' => $request->get('price'), ]); // 処理 } } これが示す仕様、ユースケースをこのコードから読み取れるでしょうか?簡単な例なので、もしやわかる方もいらっしゃるかもしれません。しかし、なんとなくTransaction、取引を作成する処理だとわかるくらいでしょうか? このコードは改善が必要に思います。 class TransactionController { /** * @var BuyProductInterface */ private $useCase; public function __construct(BuyProductInterface $useCase) { $this->useCase = $useCase; } public function create(Request $request) { $this->useCase->process(); } } class BuyProduct { /** * @var CustomerService */ private $customerService; public function __construct(CustomerService $customerService) { $this->customerService = $customerService; } public function process() { // $customer, $productの定義 $this->customerService->buy($customer, $product); } } class CustomerService { /** * @var TransactionRepositoryInterface */ private $transaction; public function __construct(TransactionRepositoryInterface $transaction) { $this->transaction = $transaction; } /** * @param Product $luggage * @return void */ public function buy(Customer $customer, Product $product) { // 商品を購入する処理 } } ここまで書けば先程より伝わるでしょうか? このプロジェクトの示す取引を作成するというのはお客様が商品を購入することを示していたのです。 このようにビジネスロジックそのものをコントローラーに直接記述してはいけません。とても無機質なコードになり、コードを業務に置き換える作業がとても大変で開発者にとってストレスがかかります。 このような現象をプログラムコードを業務へ翻訳するとか言ったりしますね。 その翻訳作業を無くすために、翻訳してある状態でコードにしておくことが重要です。業務に関する知識をビジネスロジックとして別に切り出し、そこでは業務に関する言葉などを利用することで、コードに仕様を表す事ができます。 抽象クラス 以前、ドメイン駆動設計の読書会についての記事で、「抽象に依存せよ」といった旨について記事にしたことがありますが、抽象クラスの役割は依存関係の解消だけではありません。仕様をコードに表すという観点からも有用です。 もしかしたら誤解を生んでしまうかもしれませんが、抽象クラスはそのオブジェクト(つまり業務での登場人物)のできることリストと言い換えることも出来ます。 1番はじめに使用した運転手の例で作成してみましょう。 interface Driver { public function transferLuggage(Luggage $luggage): void; public function startRest(DateTimeInterface $from): void; public function endRest(DateTimeInterface $to): void; public function moveBase(Base $base): self; } (実際の業務を無視して、)とにかく運転手ができそうなことをリストにしてみました。 運転手ができそうなことがこの抽象クラスからわかるかと思います。 開発者はこのクラスから、「このドメイン内の運転手はこのようなことができるのか」と大まかな仕様を理解することができるはずです。また、今後のミーティングなどで運転手にできることが増えたなら、この抽象クラスに処理を追加すればいいこともわかります。 入力値と出力値もわかるので、コーディングレベルでも伝えられることは多そうです。 ユビキタス言語 最後にユビキタス言語でコードに仕様を表してみましょう。 実はここまでのサンプルコードで出てきているのですが、プログラム処理的な言葉を排除し、業務的な言葉でコードを書くことを示します。(大体) class CustomerService { // 省略 /** * @param Product $luggage * @return void */ public function createTransaction(Customer $customer, Product $product) { // 取引を作成する処理 } } このようなコードだとcreateTransactionがどのような業務フローを示すのかがよくわかりません。 コードの内容をそのまま受け取るとお客様が取引を作成する? うーんちょっとわかりません。 class CustomerService { // 省略 /** * @param Product $luggage * @return void */ public function buy(Customer $customer, Product $product) { // 取引を作成する処理 } } このようにすればわかりますね。関数名がbuyですし、Product型の変数を渡していることから商品を購入する処理ということは想像できそうです。 このように変数名 / 関数名を少し業務に寄せるだけでも全然違います。 とても簡単に見えますが、結構難しいです。プログラミングをしているときは頭がプログラムの味方をしてしまうのです。 もう少し極端にしてみる 商品登録をする処理を作成してみましょう。 class Staff { public function createProduct(Product $product) { // 商品登録処理 } } あっているようにも見えます。createはデータストアにデータを登録する処理として名付けられることもしばしばあります。 でもこれで満足してはいけません。本来ならこうなるはずです。 class Staff { public function registerProduct(Product $product) { // 商品登録処理 } } 登録なのですからregisterですよね。 商品更新ならどうでしょうか?updateProductが正解っぽいです。でもミーティングでは商品編集という言葉で進んでいました。ではeditProductが正解でしょう。 いやいや、ウチのミーティングでは商品保存で統一されているんだよ。 ならば、saveProductでUPSERT的な処理を記述するべきでしょう。 このように細かいところまで使用する言葉に気をつける必要があります。 こうすることでコードに仕様を表すことができるのです。 最後に コードに仕様を書くことの大切さはプログラマが知るべき97のことでも書かれていましたね。 ここまでするの面倒だからしないという方もいるかも知れませんが、どうせコメントに仕様書くならコードに書きませんか? 次回もプログラマが知るべき97のことを読んで記事にしようかなと思っています。 その時はよしなに。 .

ボーイスカウト・ルールを現実的に実現するためには?

2020/07/06 2020/07/06

プログラマが知るべき97のこと こんにちは。のんです。 本日はプログラマが知るべき97のことを読んでいてこれ「いいな」と思った箇所について書いてみようと思います。 こちらの書籍はとても有名なので、既読の方もいらっしゃるかもしれません。 そういう方は復習というか、内容を思い出したり、私の意見と違うところや共感できるところを探していただければ幸いです。 ボーイスカウト・ルールってなに? プログラマが知るべき97のことにはこう書いています。 ボーイスカウトには大切なルールがあります。それは、「来た時よりも美しく」です。たとえ自分が来た時にキャンプ場が汚くなっていたとしても、そしてたとえ汚したのが自分でなかったとしても、綺麗にしてからその場を去る、というルールです。 最近、私の町ではボーイスカウトの姿を見なくなってしまいました。私が子供の頃は友達がボーイスカウトしていたこともあって結構身近な存在だったのですが、現在はどうなんでしょうか? しかし、これまでの人生このような光景は見たことあるかもしれません。ボーイスカウトに限らず、小学校で美化活動として昼過ぎくらいに町内清掃している姿くらいは見かけているはずです。 「この考えをプログラミングにも取り入れようよ」という考えがボーイスカウト・ルールです。 結構簡単そうじゃない?いえいえ、かなり難しいはずです。 コードに散々しているゴミコードをただ修正変更するのは結構簡単と思えるかもしれませんが、私は難しいと感じます。その理由を1つずつ挙げると、 バグ修正は気軽にできない すでに正常動作しているコードを修正することへの心理的ハードルが高い 納期に追われているなど、時間的余裕が無い コミットをきれいに保ちたい。(ブランチ作成や切り替え作業が面倒くさい) すぐに思いつくのは以上のような理由でしょうか?他にも色々あるかもしれませんが、多分共感していただけると思います。 バグ修正は気軽にできない バグ修正は気軽にできません。影響範囲の調査や、バグを修正したことによるデグレーションを考慮しなければならなくて、とても工数がかかります。ゴミ拾いと同じ感覚で修正していたらいつの間にかscrap & buildしていたとかなりかねません。(時間的余裕と、影響範囲潰しができればとてもGJ👍ですが!!) すでに動作しているコードを修正することへの心理的ハードルが高い 四則演算の効率化や簡単化など、ちょっとした処理の修正に対して変更を行うことを想定しましょう。すでに正常に動作しているコードを修正すると考えるだけで不安になります。心の中で、(うーん……次のマイナーバージョンでするか)みたいになるのは火を見るより明らかです。 納期に追われているなど、時間的余裕が無い。 これは簡単ですね。そもそもその程度の修正をする時間すら存在しない時です。 コミットをきれいに保ちたい 一般的にGitを用いて開発をする場合、ブランチは機能単位に切られ、マージできるレベルでコミットされるはずです。あるAという機能を作成しているときに、ボーイスカウト・ルールに則って修正を行うと、A機能のためのブランチにBの修正が混じることになります。これを嫌がる人や、是としないチームはたくさんあるはず(というか、そういうルールが推奨されているはず)です。 そういうルールがある中でボーイスカウト・ルールを適用しようと思うと、(Aという機能を作るという別の仕事をしているにも関わらず、)ブランチを新しく作成したり、マネージャーへ連絡したりしなければなりません。 それが面倒臭いという人は必ずいるはずです。(私もそうでした。) こういった「課題をクリアする」というより、ボーイスカウト・ルールを適用しやすい環境を作る方がとても簡単です。上記の課題を例にボーイスカウト・ルールを適用しやすい環境を考えてみました。 (adsbygoogle = window.adsbygoogle || []).push({}); ボーイスカウト・ルールのハードルを下げる 見かけたバグはすぐ直す。このルールをそう受け取る方もいるかも知れませんし、そう思っていない方も、義務感から修正への執念を持っているかもしれません。私の知り合いには、あまりにひどいコードに遭遇し、もはやこの考えが強迫観念となっている方がいました。 もっと気軽に考えましょう。以下のポイントを押さえ、継続すればうまくいくはずです。 変数名や関数名本当に軽微なポイントにのみ注目する ノルマなどは当然設けない 修正というより整頓と考える(後述) 関連して、一気に修正 / 整頓しない 修正というより整頓と考える 例えば、引き継いだプロジェクトで下記のようなコードに出会ったとしましょう。自分はある程度経験を積んで、よくわからない処理を調査していました。数十分ほどかけて、そのロジックを解き明かしたとしましょう。 <?php class DustSample { /** * @var string */ private $dust; /** * @param string $dust */ public function __construct(string $dust) { $this->dust = $dust; } public function unknown() { // 難解なコードで自分が頑張って読み解いた重要な処理 } } この時、unknowメソッドをボーイスカウト・ルールに則り修正するのではなく、コメントを書くなどして、わかりやすくしたり、一部privateメソッドなどで切り分けられそうなものを切っておきましょう。だから修正より整頓と考えるわけです。 <?php class DustSample { /** * @var string */ private $dust; /** * @param string $dust */ public function __construct(string $dust) { $this->dust = $dust; } /** * 〇〇を✕✕して△する処理 */ public function unknown() { // 難解なコードで自分が頑張って読み解いた重要な処理 } /** * 〇〇を✕✕する処理 */ private function unknown_parts() { // 難解なコードの一部、でも、処理を切り分けることでどんな処理をするのかが少しわかりやすくなっている } } 少しはハードルが下がるはずです。少なくともコメントの追加で動作が変わるというのは早々ないでしょう。 これまでの慣習をできるだけ無視し、オブジェクト単位で、特に依存を無くす実装にする PHPだとよくあるのは、全部Controllerに書かれていて、しかもそれが他の処理に密結合を起こしている場合です。 そうなってくると、ボーイスカウト・ルールどころではありません。 ちょっとした改修タスクを作成し、その部分だけでもオブジェクト化しておきましょう。 クリーンアーキテクチャに基づいたDDDがオススメではありますが、そうでなくても、振る舞いを閉じ込めたEntityのみを採用するだけにとどめたり、ValueObjectだけでも採用したりすることで、ボーイスカウト・ルールをしやすいコードへと変身させるのです! わかりやすい、あるいは依存していないコードに対してはとても修正をかけやすいです。心理的ハードルが下がるはずです。Interfaceで抽象クラスを作成したり、ControllerではなくActionでリクエストを捌いてみたり、とにかく小さく処理を作成するように心がけると、みんなは自然とゴミを拾ってくれます。 ここでも大事なのはストレスのかからないレベルで導入することです。隅っこの方のディレクトリにModels/Entityとディレクトリを切り、その中に必要な振る舞いと値を入れるだけとかでもいいです👍 テストコードを整備する ここまでで気づいている方は多いでしょう。 テストコード、これがあればストレスとはおさらばですね👍 なんちゃってリファクタリングではなく、本格的なリファクタリングができるようになります。 https://www.amazon.co.jp/Java言語で学ぶリファクタリング入門-結城-浩/dp/4797337990 その時はこちらの書籍を読むといいかもしれません。 TDD(テスト駆動開発)と勘違いする方がいますがここでは関係ありません。 リファクタリングについては、また違う記事でしましょう。 やはり一番の処方箋は開発者の心理的ハードル下げることでしょうか。 修正してくれたことを褒めたり、感謝する文化を作ったり その修正を勤務評価にフィードバックしたり ポジティブな理由ですすめることができたら間違い探しをしているみたいに楽しいかもしれません ボーイスカウト・ルールを適用するにあたっての注意点 一応デメリットとしてあげられるのは、計画的 / 継続的にやりましょうとういことです。 計画的に進めなければ、プロジェクトの方針と食い違う可能性が出てきます。継続的に進めなければ、中途半端になってしまいます。 見かけたら100%の修正をする必要はありませんが、その分続けなければならないことは感覚的にわかりますね。 最後に ボーイスカウト・ルール。この考えとても好きです。年末に大掃除するとき、慌てない家庭はこのルールをキチンと守っているのでしょう。あるいは夏休み宿題で苦労することはないでしょう。 継続的インテグレーションが完全に普及した今、コードを作成したらそれで終わりという文化もなくなりました。 コードのメンテナンスをしっかりすることで、バグの早期発見や仕様の理解もできるでしょう。 私も完全に出来ているわけではないので、今後も頑張りたいです。 プログラマが知るべき97のことについての記事はまた書くかもしれません。 そのときはよしなに。 .

Z250で三方五湖レインボーラインへツーリング!

2020/06/25 2020/06/25

Z250で三方五湖レインボーラインへツーリング! こんにちは。Nonです。 今回は技術記事ではなくバイク記事です。 三方五湖レインボーラインへ行って来たよ 前日が雨でツーリング行けるかどうか不安でしたが、無事いい天気で当日を迎えることができました☀️ 行きは大津周辺で集合。琵琶湖の西側、367号線を北上するルートで向かいました。 この道路もめちゃめちゃいいですね👍 10時から大津を出発して、12時に到着。2時間くらいで行けるものなんですね。 実はレインボーラインへ行くの2回目なんですが、そのときは舞鶴若狭道で向かったものですから、少し遠回りだったんですよ。 レインボーラインの入り口でパシャリ レインボーラインの道中でパシャリ レインボーラインで昼飯食って13時くらいから帰路に着きました。 レインボーライン降りて少し北の216号線走る 北の方には良いワインディングがあるものの、道路の状態と、視界が悪くて少し怖かったかも。。 北の最頂には特に何もありませんでした。でも港はキレイでしたね。 162号線で帰る 162号線いいですよ👍 あの辺で走ってる黒いZ250は僕かもしれません🏍 最後に コロナ禍でなかなかツーリング行けなかったので、久々のツーリングでした。 一番いい時期を奪われてほんまに。。。 やっぱりツーリングはいいものですね。 ちょいちょいですが、こういったバイク記事を投稿しています。よかったらこちらも見てみてください。 Z250で伊勢志摩ツーリング!! | のんラボ Z250で伊勢志摩ツーリングに行ってきました!!こんにちは。Nonです。今回は久々にツーリングの記事を更新します🏍正確には上図のマップどおりではありませんが、スケールはコレより大きい範囲回ってきました... Z250で初!キャンプツーリング! | のんラボ 洞川キャンプ場へツーリングしてきましたこんにちは。Nonです。今回は久々に技術とは全く関係ない記事を投稿します。週1ペースで技術系の記事を投稿していますが、月1でこういうのもいいと思っています。毎回技... Z250での冒険日記 | のんラボ 定期的にこんな感じの記事も追加して行くと思う。4月27日〜29日 西日本一周ツーリングこれはお友達と弾丸ツーリングに行きましたZXR1200のパワーを見せつけられましたね。鳥取砂丘写真は撮影してないけ... また記事書きます!動画もアップロードできるようにこのブログもバージョンアップしようかな。 最後に!バイクはいいぞ!! .

フロントに処理を書くとき、フレームワーク内で処理は書かない方がいい気がする

2020/06/17 2020/06/17

フロントに処理を書くとき、フレームワーク内で処理は書かない方がいい気がする こんにちはNonです。 今回はこれまでと変わってフロントに着目したいと思います。 前提 (laravel-mixでの)Vue フレームワーク内で処理を書くとこうなる export default { name: 'ApplicationComponent', data() { return { food: { name: '', price: 0, num: 0, }, drink: { name: '', price: 0, num: 0, }, sum: { price: 0, num: 0, }, tax: 0.08, }; }, created() { this.food.name = 'おにぎり'; this.food.price = 100; this.food.num = 3; this.drink.name = 'お茶'; this.drink.price = 150; this.drink.num = 1; }, computed: { sum() { return { price: this.calcTax(this.food.price, this.food.num) + this.calcTax(this.drink.price * this.drink.num), num: this.food.num + this.drink.num, }; } }, methods: { calcTax(price, num) { return price * (1 + this.tax) * num; }, } }; コンポーネント単位でこのような処理を書くと、違うコンポーネントのロジックを書くときに、計算方法を間違えそうになるかもしれません。 そこで、計算処理、つまりビジネスロジックを持つモデルを外部のjsで持つことでロジックの重複を防ぎます。 フレームワーク内はレンダリングに注力し、処理は他のパッケージで持つ フレームワーク内はレンダリング、つまり値の監視や、コンポーネントの管理などはフレームワーク(ここではVue)で行い、フロントで行うべき処理であるビジネスロジックはモデルとして外部に持つようにします。すると下記のようになります。 export default { name: 'ApplicationComponent', data() { return { food: { name: '', price: 0, num: 0, }, drink: { name: '', price: 0, num: 0, }, sum: { price: 0, num: 0, }, tax: 0.08, }; }, created() { this.food.name = 'おにぎり'; this.food.price = 100; this.food.num = 3; this.drink.name = 'お茶'; this.drink.price = 150; this.drink.num = 1; }, computed: { sum() { const productCollection = new ProductCollection([ new Product(this.food.name, this.food.price, this.food.num), new Product(this.drink.name, this.drink.price, this.drink.num), ]); return { price: productCollection.sumPrice(), num: productCollection.sumNum(), }; } } }; export class ProductCollection { constructor(items = []) { this.items = items; } sumPrice() { return this.items.reduce((previous, current) => { return previous.sumPrice() + current.sumPrice(); }); } sumNum() { return this.items.reduce((previous, current) => { return previous.num + current.num; }); } } export class Product { static get TAX() { return 0.08; } constructor(name, price, num) { this.name = name; this.price = price; this.num = num; } calcTax() { return this.price * (1 + this.TAX); } sumPrice() { return this.calcTax() * this.num; } } このように、商品のビジネスロジックをクラスの中に封じ込め、更にフレームワーク依存しない箇所に集めることで、使い回すことを可能にしています。 さらに、フレームワーク依存しないので、他のフレームワークに移行するときにも重宝します。 Vueの場合、mixinに書けばいいじゃん? もちろん、Vueに依存することを前提にしている場合はそれでもいいですが、HelperやUtilのような役回りが多いmixinにビジネスロジックを書くのはいかがなものでしょうか? 〇〇mixinが多くなってしまうのが、目に見えます。 クラス(オブジェクト)のパワーを借りることができる。 例えば、バリデーターを自作したとして、このようなクラス作成します。 export class StringValidator { constructor(value) { this.value = value; this.result = []; this.messages = []; } max(length) { this.result.push(this.value.length > length); this.messages.push(length + '文字以下で入力してください。'); return this; } min(length) { this.result = this.value.length < length; this.messages.push(length + '文字以上で入力してください。'); return this; } number() { this.result = Number.isInteger(this.value); this.messages.push('半角数字のみで入力してください。'); return this; } invalid() { return this.result.filter((item) => { return item === true; }).length > 0; } } このようにすれば、jQueryだろうがReactだろうが使用できるようになるでしょう。 今回の場合はVueで書いてみます。 export default { name: 'ApplicationComponent', data() { return { name: '', errors: [], }; }, methods: { submit() { const validator = new StringValidator(this.name); const invalid = validator .max(10) .min(1) .invalid(); if (invalid) { this.errors = validator.messages; return false; } // 処理 } } }; これならバリデーションの内容を外部に任せることができます。 もちろん、入力中のバリデーションやVueで行いたい基本的なバリデーションをmixinなどに書いてリアルタイムにエラーを出力することなどもできますので、そちらはVue側に記述して、ビジネスロジックに関するバリデーションは外部に持つというのが、いい気がします。 最後に 今回はフロントにロジックを記載するときについて書いてみました。 PHPでWebアプリを作成するときは少し前まではフロントを書くときjQueryを採用することが多かったです。 こうなるとどうしてもロジックをスクリプトにチョチョイと書いてしまう実装は多いのではないでしょうか? フロント言語がしっかりとしてきた今、フロントのコードもしっかりと設計していきたいものです。 今は社内でスクラムの勉強会をしているので、その記事も書くかもしれません。 そのときはよしなに。 .

社内でドメイン駆動設計入門の読書会 #15

2020/06/08 2020/06/08

社内でドメイン駆動設計入門の読書会 #15 こんにちは。Nonです。 今回も会社で読書会をしている話をしようと思います。 内容は控えめに、ディスカッションの内容重視で書いていきたいと思います。 より具体的なコードや内容がみたい!という方は購入しましょう! 前回:会社でドメイン駆動設計入門の読書会 #14 読んでいる本 読んでいる本はこちらのドメイン駆動設計です。 ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本 以前の記事でも言っていたように、業務でDDDを利用して開発することが多くなったのですが、DDDに精通している人が少ないという問題がありました。 そこで、その精通している人が読書会をしようかと誘ってくださいまして、是非にと参加させていただきました。 進行方法 読書会の進行方法は 今回読書の対象にする章を決める。 10〜20分間その章を読む 読み終わってしまった人は、もう一周読み直すか、次の章に進んでもらう その後40分間で、その章に対する疑問や考え方をディスカッションする 1〜3を毎週定期的に行う という進行方向となっています。 社内で読書会をするのはこれが初めてなので、進行方法はもっといいのあったら教えて下さい。 今回読んだ内容 ドメイン駆動設計のとびらを開こう 軽量DDDに陥らないために ドメインエキスパートとモデリングする 本当に解決すべきものを見つけよう ドメインとコードを結びつけるモデル ユビキタス言語 深い洞察を得るために ユビキタス言語がコードの表現として使われる 境界づけられたコンテキスト コンテキストマップ テストがチームの架け橋に ボトムアップドメイン駆動設計 まとめ ディスカッション ディスカッションではコードの話のほうが多かった でも、ドメイン駆動はドメインに注目して開発していく設計なので、コードは実はあまり関係ないのかもしれません。もちろん、コードが二の次というわけではなく、コードはドメインを反映させるためのふさわしい構造になっていないといけません。 ユビキタス言語 この記事を読んでいる皆さんにはすでに周知のとおりですが、変数名は重要です。 変数名はその処理を追うための手かがりになるからです。 ドメイン駆動設計でもこの点に触れていて、create, make, registerや、update, saveなど、普段何気なく使っている変数名や関数名について触れています。 ドメインで頻出する単語はそのドメインにとって重要なので、それもコードに反映しなければなりません。 例えば、あるドメインで、ユーザー登録ではなくエージェント登録という内容であれば、userではなくagentという名前になりますし、ユーザー更新ではなくユーザー保存と慣ればsaveUserとなります。 この微妙な命名でコードとドメインが乖離してしまう原因になってしまうのです。 境界づけられたコンテキスト これはまだ完全に理解できていないので、今後の課題とします。 最後に 実は結構前に、ドメイン駆動設計の全ての章を読み終えて、業務のコードに実装まで始めていました。実際にコードにするとなると非常に難しく、軽量DDDになってしまっている感が否めません。今後も精進していきたいです。 常時、自社プロダクトにコミットしているので、自分の作成したプロダクトくらい自分の支配下においていきたいものです。ということはドメインに一番詳しいのは、自分たちということになります。 そういう意味でも、ドメイン駆動設計を用いて、自分たちが実現したいことをコードで表すことは義務であるのかなと思います。 読書会は引き続き進めているので、機会があればまた連載記事として、掲載していこうと思います。 その時はよしなに。 .

社内でドメイン駆動設計入門の読書会 #14

2020/06/01 2020/06/01

社内でドメイン駆動設計入門の読書会 #14 こんにちは。Nonです。 今回も会社で読書会をしている話をしようと思います。 内容は控えめに、ディスカッションの内容重視で書いていきたいと思います。 より具体的なコードや内容がみたい!という方は購入しましょう! 前回:会社でドメイン駆動設計入門の読書会 #13 読んでいる本 読んでいる本はこちらのドメイン駆動設計です。 ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本 以前の記事でも言っていたように、業務でDDDを利用して開発することが多くなったのですが、DDDに精通している人が少ないという問題がありました。 そこで、その精通している人が読書会をしようかと誘ってくださいまして、是非にと参加させていただきました。 進行方法 読書会の進行方法は 今回読書の対象にする章を決める。 10〜20分間その章を読む 読み終わってしまった人は、もう一周読み直すか、次の章に進んでもらう その後40分間で、その章に対する疑問や考え方をディスカッションする 1〜3を毎週定期的に行う という進行方向となっています。 社内で読書会をするのはこれが初めてなので、進行方法はもっといいのあったら教えて下さい。 今回読んだ内容 アーキテクチャ アーキテクチャの役目 アンチパターン:利口なUI ドメイン駆動設計がアーキテクチャに求めること アーキテクチャの解説 レイヤードアーキテクチャとは ヘキサゴナルアーキテクチャとは クリーンアーキテクチャとは まとめ ディスカッション 今回はアーキテクチャについて これまでのドメインオブジェクトをどうやって実装していくか、それにあったアーキテクチャを紹介してくれている章でした。 抽象に依存せよ これまでの章で何度も登場してきたのが、この文言です。 抽象に依存しておけば、実装クラスの内容をある程度縛ることができますし、抽象クラスを見るだけどんな内容が実装されるべきなのかわかります。 クリーンアーキテクチャ The Clean Code Blogより抜粋 https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html 徹底的に依存を嫌うので、値を返さない用な処理が多いです。 前回試しにかいたコードを見てみましょう。 class CreateCircle { private $userService; public function __construct(UserService $userService) { $this->userService = $userService; } public function process(CreateCircleInputPort $inputPort, CreateCircleOutputPort $outputPort) { $circleName = new CircleName($inputPort->circleName()); $circle = $this->userService->createCircle($circleName); $outputPort->output($circle); } } interface CreateCircleInputPort { public function circleName(): string; } interface CreateCircleOutputPort { public function output(Circle $circle): void; } このprocess関数は何も返却されていません。 Actionからこのアプリケーションサービスを呼び出すイメージなので、アクションには何も帰らないことになります。 こうすることで、Actionはこのアプリケーションサービスに依存しないようにできています。 ではActionは何をレスポンスとして返せばいいのかというと、上図にあるようにUse Case Output Portに返したいものを注入しておきます。 class CreateCircleAction extends Controller { private $useCase; public function __construct(CreateCircle $useCase) { $this->useCase = $useCase; } public function __invoke(Request $request) { $response = new CreateCircleResponse(); $this->useCase->process($request, $response); return response()->json($response); } } returnするのは同一のドメイン内だけで行うことのようです。 アーキテクチャの勉強にもなった 正直この読書会をするまでは、MVCすら危うい感じでしたが、このように具体的に書いてくれる本があったので、設計にも少しは明るく慣れたと思います。 抽象に依存せよ。(interfaceを利用せよ) ドメイン内以外でreturnするな(オブジェクトを渡して、結果はそこに注入せよ) 強いてあげるなら、フレームワークに依存するな。 これくらいを守れればコードの可読性と保守性は飛躍的に向上すると思います。 最後に どうやって設計すれば。。。という壁にぶち当たっていたので、今回の章(今回の読書会)でこの壁は壊せたと思います。 このアーキテクチャはドメイン駆動だけでなく他のモデルにも通じますし、PHPだけじゃなくてjavascriptにも通用しますので、フロントのコードも多少はきれいになると思います。 次回はドメイン駆動設計のとびらを開こうです。 また記事にしますので、その時はよしなに。 .