【DDD本読書メモ】ドメイン駆動設計とは
最近「ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本」という本を読んでいます。2週目です。
1週目は1人で黙々と読んでいたのですが、理解が不十分だと感じていました。読み返してより理解を深めたいと思っていたところ、社内で輪読会をする話が出たので参加し、2週目を読み進めています。
せっかくなので、理解を深めるために自分なりのまとめをブログに書いておこうと思います。これは自分の理解を深めること、自分がさっと見返すことを目的としています。 より正確な解釈や詳しい話は上記の本を読んでいただければと思います。
また、認識違いがあった場合はご教示いただければ幸いです。
ドメイン駆動設計とは
この記事ではCapter1の「ドメイン駆動設計とは」を読んだまとめを書いています。
ドメインとは
ドメインは「領域」という意味を持った言葉です。ソフトウェア開発におけるドメインは、「プログラムを適用する対象となる領域」のことです。
例えば会計システムの場合、金銭や帳票といった概念が登場します。これらは会計システムのドメインに含まれます。物流システムだと貨物や倉庫、運送手段などの概念が存在し、それらは物流システムのドメインに含まれます。そういった関心事が「ドメイン」に該当します。問題領域、業務領域と捉えるとわかりやすいかもしれません。
ドメイン駆動設計とは
ドメイン駆動設計とは「ドメインの知識に焦点を当てた設計手法」のことです。
「ドメインの知識に焦点を当てる」とはドメインに向き合い、その概念・事象をしっかり理解した上で、問題や問題解決に必要なことを導き出し、それをシステムに反映させることです。
「当たり前では?」と思いますが、当たり前のことを実践することは意外に難しかったりします。「作ったものがユーザーが求めるものではなかった...」というようなことは実際に起こり得ます。
そうした悲劇を生まないための道標としてドメイン駆動設計は有効な手段となります。
ドメインモデルとは
現実世界の複雑なドメインの概念から全てをソフトウェアに持ち込む必要はありません。ソフトウェアではソフトウェアが担う責務に必要な情報を抽出して扱うべきです。こうした抽象化する作業を「モデリング」、抽象化された概念を「モデル」と呼びます。ドメイン駆動設計では、ドメインの概念をモデリングして得られたモデルを「ドメインモデル」と呼びます。
モデリング - 現実の事象・概念を抽象化する作業 モデル - 現実の事象あるいは概念を抽象化した概念 ドメインモデル - ドメインの概念をモデリングして得られたモデル
ドメインオブジェクトとは
ドメインオブジェクトとは、ドメインモデルをソフトウェアで動作するモジュールとして表現したものです。
ドメインモデルは概念を抽象化した知識にとどまります。開発者はドメインモデルから真に問題解決に必要なものを選択し、ドメインオブジェクトとして実装します。
ドメインの概念 <=> ドメインモデル <=> ドメインオブジェクト
ドメインの概念に変化があれば、まずドメインモデルに反映させ、必要に応じてドメインオブジェクトを変更します。また、プログラムは曖昧な表現を受け入れられないため、ドメインオブジェクトを実装する過程でドメインの捉え方の見直しに繋がることもあります。
こうしてドメインの概念とドメインオブジェクトはドメインモデルを媒介に繋がり、お互いに影響し合う反復的な開発が実現されます。
ドメイン駆動設計のパターン
Capter1の終わりには、この本で学ぶドメイン駆動設計のパターンが挙げられていました。こうして俯瞰して見ると理解もしやすく助かります。見返したいのでメモしておきます。
- 知識を表現するパターン
- 値オブジェクト
- エンティティ
- ドメインサービス
- アプリケーションを実現するためのパターン
- リポジトリ
- アプリケーションサービス
- ファクトリ
- 知識を表現する、より発展的なパターン
- 集約
- 仕様
感想
「ドメイン駆動設計」を説明するだけでもいくつかワードが出てきました。1つ1つわかりやすく解説されており、理解しやすかったです。
また、これまで、DDDのメリットといえば
- ドメインの変更をプログラムに反映させやすいこと
- プログラムがドキュメントになること
などと捉えていましたが、「ドメインに向き合い、その概念・事象をしっかり理解した上で、問題や問題解決に必要なことを導き出し、それをシステムに反映させる」 という当たり前なことを当たり前にやるための補助
という認識は薄かったような気がしたので、改めて意義を確認できてよかったです。
英語学習計画 2020年7月時点
(これは自分のための英語学習の記録です。)
5月末くらいにAtsuさんを教えてもらって、そこからAtsuさんの動画やサイトをみた。
サイト
atsueigo.com
すごく納得できる考え方だったので、Atsuさんの助言に沿って勉強してみようと思い、勉強法を見直してみた。
それで改めた計画が以下。
- 6、7月:ひたすら英文法
- キク英文法をやる
- 8、9月:ひたすら英単語と発音
- Distinction2000をやる
- 10〜:英会話
- レアジョブをやる予定
現在は7月で今もキク英文法をやってる。 本当は英会話も同時に並行してやることをおすすめされているが、まだできていない。 何事も早く実践していった方が良いことは常々感じるので、レアジョブ開始を早めようかなと検討している。仕事関連のインプット、アウトプットもやりたいのでちょっと英語の優先順位は2番目になっていて躊躇しているところもあるが、8月から始めたいなと思っている。進展があったらまた書く。
Webの Dark Mode 対応について考えてみた
はじめに
Webの Dark Mode 対応のデファクトを知りたくて少し調べてみました。デファクトはこうだ!と提示するというより、個人的な考察を記載したものになります。デファクトはこうやで、というのがあるなら知りたいなぁという感じです。
Dark Mode とは
(たぶん)みんな大好き、黒を基調とした画面表示モードのことです。Windows OS、Mac OS、iOS、Android OS など主要OSがDarkModeに対応してきています。OSの設定を変更すると、デスクトップやOS標準アプリ、サードパーティアプリも Dark Mode に切り替わる対応がされてきているようです。ユーザーに身近な機能になりつつあると言われています。
私は、ターミナルやIDEはエンジニアっぽくてかっこいい
という理由で黒ベースのテーマを設定していますが、一般的にも人気なんですかね?よくわからん。そういうのどっか調査してるんでしょうか。どうやって調べたらいんやーという気持ちです。
Dark Mode のメリット
Dark Mode のメリットは以下2点が挙げられているのをよく見かけました。
あと、個人的には カッコイイ
ってのもあるよね、と思っています。
Webの現状は?
Dark Mode に対応しているサイト、サービスは少ない印象を受けますが、どうなんでしょう?Dark Mode 対応していると言われるサービス(Twitter、YouTubeなど)でも、OSの設定に応じて変更するものではなく、サービス内で Mode を切り替えられるような設定を設けているというのが現状のようでした。
Blogだと、OSの設定に対応しているものもいくつか見かけました。いずれにせよ、網羅的に調査できているわけではないので、みんなどういう認識なんだろうってのが気になっています。
Webはどうしていくべきなのか?
Webはどうしていくべきなのか?OSの設定によってテーマを切り替える実装を入れるべきなのか?という話ですが、 OSやネイティブアプリは Dark Modeに対応しているのに、Webだけ対応していないとDark Modeのメリットが弱まる為、やはり対応していくのがBetterだろうと私は思います。
Chromeでは強制的に Dark Mode にする設定が試験的に実装されているようで、そういったことからもWebサイトやWebサービスが未対応なことが課題となっており、これから対応していくべきだという声が一定数挙がっていることが伺えるなと感じました。(ちなみに、Chromeで chrome://flags を開き、「Force Dark Mode for Web Contents」 を 「Enabled」 にすると強制的にDarkModeになります。)
Webでの対応方法
さて、Webでの対応方法の話ですが、OSの設定に応じてスタイルを変更する為のCSS のメディア特性があるので簡単に対応できます。prefers-color-scheme
を使います。仕様はこちら。
Can I useをみたところ、モダンなブラウザでは使えると思って良さそうです。
以下、サンプルです。(少し前のMDNのサンプルベースに書きましたが、今は変わったみたい。)
サンプル
html
<div class="themed">Theme</div>
.themed { display: block; width: 10em; height: 10em; background: black; color: white; } @media (prefers-color-scheme: light) { .themed { background: white; color: black; } }
これをさらにCSS変数(カスタムプロパティ)を使って管理しやすくすると以下のようになります。
* { --background: black; --color: white; } @media (prefers-color-scheme: light) { *{ --background: white; --color: black; } } .themed { display: block; width: 10em; height: 10em; background: var(--background); color: var(--color); }
疑問
ここでいくつか疑問が浮かびました。
疑問その1:サイト、サービス、アプリによっては OSの設定と違うMode にしたいものもあるのでは?
OSの設定によって、一律 Light Mode、Dark Mode に切り替えられると不都合な場面もあるのではないか、と思いました。私の場合、アプリによってはこれは Dark Mode で使いたい、これは Light Mode の方がみやすいから Light Mode で使いたいと思うことが実際にあったからです。その観点から考えると、OSの設定によって切り替えるように対応されたとしても、サイト、サービス、アプリごとにユーザーが設定できる機能は残した方が良いように思いました。
今の所、YouTube や Twitter は OS の設定は見ておらず、ユーザーに設定させたMode (テーマ) を適用しているのはこの辺を考慮してのことなのかな?という気もしました。(真相は知らない。。)
Macのアプリだとアプリ側の設定も設けているものもあるようです。やはり同じようなことを思う人いるよな、やっぱり必要だよな、というのが個人的な結論です。
疑問その2:暗いところで見るときに Dark Mode にしたいなら、明るいところで見るときは Linte Mode にしたいのではないか?
暗いところで見るときに Dark Mode にしたいなら、明るいところで見るときは Linte Mode にし たいのではないか?というのも自然と浮かぶ疑問だと思います。
その度にOSの設定を切り替えるのか?というとそれは現実的ではない印象を受けます。それよりディスプレイの明るさを調整した方が操作のステップも少なくて手軽なので私ならそうします。
OSによっては、時間帯によって明るさを自動調整できる設定や、Lite Mode or Dark Mode を切り替える設定があるのでそれを使うのもよさそうですね。
でもここでまた疑問が出てきます。この機能って 時間帯
で切り替えているので、そもそも日中は明るい
、夜は暗い
が前提になっていますよね。でもそうではないときって日常的にあります。それだとニーズに合わない。本当の理想を考えると、ユーザーの利用環境の明るさによって自動で切り替わるとういうのがユーザー体験として一番ベストなのでは...?
AmbientLightSensor
ユーザーの利用環境の明るさによって自動で切り替わるとういうのがユーザー体験として一番ベストなのでは...?
この視点で、ユーザーの利用環境の明るさをWebで取得し、Dark Mode 対応をするという記事を先日のng-japan OnAirを視聴している中で知りました。
その記事がこちら↓です。
dev.to
ここでは、 AmbientLightSensor が紹介されています。 まだちゃんと触れていなくてざっくりになりますが、簡単に紹介します。
できること
- デバイスの環境光センサーのデータにアクセスし、照度を取得できるらしい
- 照度の基準に応じてアプリケーション側でよしなに実装すると良さそう
(参考:https://en.wikipedia.org/wiki/Lux#Illuminance)
- 照度の基準に応じてアプリケーション側でよしなに実装すると良さそう
制約
- 現状の対応ブラウザが限られている
- 環境光センサーをもつデバイスでしか使用できない
- 他にもユーザーが使用を許可していなければ使えないなどの制約もあるみたい
まとめ
実は今回、この記事を知って、そこからWebの Dark Mode 対応事情を調べてみようと思ったのでした。
今のところ、prefers-color-scheme を使った対応
+ 各サイト、サービスで Mode 切り替え設定実装
とういうのがベストな落としどころなんじゃないかなーというのが個人的な感想です。 (これはかなり凝った場合だと思うので、どこまでそこにこだわるのか?という話はあると思います。)
AmbientLightSensor に関しては触ってもうちょっと理解したいなという気持ちがあるので、触ったらまたブログを書く予定です。
【Angular】<form action="url" type="post">でリクエストを送りたいときの方法
はじめに
この記事は、自分の振り返りのためのメモです。 小ネタです。
やりたかったこと
ログアウト処理の実装で、ログアウトボタンをクリックするとログアウトされ、ログイン画面に遷移させたい場面がありました。フロントではログアアウトAPIにリクエストを送ればよく、API側で諸々のログアウト処理を行った後にリダイレクトするというものでした。 それには以下制約がありました。
- セキュリティの都合上postでリクエストしたい
- HttpClientは使えない(HttpClientを使うと非同期通信のため、レスポンスの内容がリダイレクト先ページのhtmlとなってしまい、期待した動作にならない)
やってみたこと
そこでその部分の処理だけ<form>
タグでpostすることにしました。
しかし、componentのhtmlに以下のようなタグを書いてみてもリクエストできませんでした。
<form action="APIのurl" method="post"> <input type="hidden" name="hoge" [value]="hoge"> <input type="hidden" name="fuga" [value]="fuga"> <button type="submit"> ログアウト </button> </form>
これはこのタグを記載したcomponentで FormsModule
importsしていることにより、標準仕様の通りに動作せず、FormsModule
の仕組みのっかってしまうことによるものでした。
以下ドキュメントより引用
In template driven forms, all
上記の内容をgoogle翻訳した内容が以下
テンプレート駆動型フォームでは、すべての
ドキュメントにある通り、テンプレート駆動フォームの場合、明示的に ngNoForm
を指定することにより、FormModuleの適用対象から除外されます。このアプリケーションではテンプレート駆動フォームを採用しているため、以下のようにすることで無事、submitすることができました。
<form action="APIのurl" method="post" ngNoForm> <input type="hidden" name="hoge" [value]="hoge"> <input type="hidden" name="fuga" [value]="fuga"> <button type="submit"> ログアウト </button> </form>
また、ngNoForm
を使用せずにsubmitする方法もありました。
以下のようにts側でsubmitする方法です。
<button (click)="onClick()" type="button" > ログアウト </button> <form #logoutForm method="post" [action]="APIのurl" > <input type="hidden" name="hoge" [value]="hoge" /> <input type="hidden" name="fuga" [value]="fuga" /> </form>
import { Component, ElementRef, ViewChild } from '@angular/core'; @Component({ selector: 'app-hoge', templateUrl: './hoge.component.html', styleUrls: ['./hoge.component.scss'], }) export class HogeComponent { @ViewChild('logoutForm') logoutForm!: ElementRef<HTMLFormElement>; onClickLogout() { this.logoutForm.nativeElement.submit(); } }
スタイルの都合上、formタグの外にbuttunタグを起きたかったので、結局後者の方が良さそうでした。
ただ、tipsとして ngNoForm
を知れたことはよかったです。これを機会にフォームのドキュメントをもっと読んで理解を深めたいと思います。
まとめ
<form action="url" type="post">
でリクエストを送りたいときの方法
ngNoForm
を指定する(テンプレート駆動型フォームの場合)- formGroupディレクティブの使用を控える(リアクティブフォームの場合)<=これは試してないけど、ドキュメントに記載あり
- ts側でsubmitする
この方法がベストかどうかはわかりません。現時点でのやったこと、理解したことを書き留めています。より良い方法があったら知りたいです(^_^)
気になること
ざっとフォームのドキュメントを読んだところ、リアクティブフォーム推しに見えますが、実際使うならテンプレート駆動フォームの方が良いと聞いたりするので、その辺の理解を深めていきたいと思いました。ドキュメントを読んだ印象だと、テストのしやすさでいうとリアクティブフォームの方が良さそうではありますが、比較するにはまだ十分理解が足りていないなという状態です。何かわかったらまた書きます。(みんなフォームのテスト書いてるの?というのも気になる)
TypeScriptメモ(1)
日頃使っているTypeScript。体系的に復習しようと思い、Udemyの講座を見ているのでメモを残します。見ている講座はこちら。
TypeScriptをやってない人に簡単に教えられるレベルの知識をすぐ引っ張り出せる、くらいを目標にしたメモです。Udemyの内容と個人的な理解の内容が混じったメモになっています。
TypeScriptとは
- ES6にさらに機能が追加されたもの。
- JavaScriptの弱点である型の扱いを厳格にしたもの。
- 開発専用言語。ファイル拡張子は「ts」。
- ブラウザでは実行できない。コンパイルしてJavaScriptに変換する必要がある。
TypeScriptのインストール
以下をターミナルで実行
$ (sudo) npm -g install typeScript
- npmがない場合はnodeをインストールする(公式サイトから)
- tsc -v でバージョンが表示されればOK
TypeScriptのコンパイル
以下をターミナルで実行
tsc [ファイル名]
tsc --init
ファイル名を個別指定してコンパイルするのがめんどくさいので一括でコンパイルする方法がある
- 以下をターミナルで実行
tsc --init
[memo] 後日別記事で補足予定
型の指定
型エラーがあった場合
- コンパイル時エラーが出る
- jsファイルへの変換は行われる(jsとしては問題ないコードのため)
[memo] 後日別記事で補足予定
型指定
変数宣言時、変数名の後に: 型
という形式で型指定できる。
let num: number; let str: string; let bool: boolean;
any
型を柔軟に扱いたいときに使う。明示的に指定することが可能。
let num: any;
以下のように型を明示的に指定しなかった場合、
let num;
内部的には以下のように解釈される。
let num: any;
[memo] anyを使うことは可能だが、新規実装等であれば使わない方針にした方が良い。理由は、せっかくTypeScriptを使用しているのに、anyを使うメリットがないはずだから。一方、jsで書かれている既存コードをtsに変えていくような場合は、一時的にanyにしておいて段階的に型を指定していくという方法が現実的な場合もあると思う。何れにせよ、安易にanyを多用することはお勧めではないが、止むを得ない場合は使用を検討すると良い、という理解。
配列
Object型になる。以下の場合、string型の要素しか代入できない。
let strings: string[] = ["あああ", "いいい"];
どんな型でも代入できるようにしたい場合anyを使えるが、前述した通り推奨ではない。
let any: any[] = ["あああ", 123];
タプル
異なる型を配列に代入したい場合、以下のように指定できる。代入時、順番を守る必要がある。型指定と代入する値の型の順番が異なる場合、エラーになる。
let olympic: [string, number] = ["東京", 2020];
enum
- 先頭に「enum」
- 型名の先頭は大文字
- 0から順に自動的に数字が割り当てられる
enum Colors { red, // 0 Green, // 1 Blue // 2 } console.log(Colors.Green); //1
- 割り当てられる数字を意図的に変えることも可能
enum Colors { red, // 0 Green = 100, // 100 Blue // 101 } console.log(Colors.Green); // 100 console.log(Colors.Blue); // 101
関数の戻り値に型指定
- 戻り値の型にstringを指定
function methodA(): string { return “Hello!”; }
- 戻り値がない場合
function methodB(): void { console.log("Hello!"); }
never
- 関数の戻り値型に指定した場合、コンパイル時エラーが出ない
function error(): never { throw new Error("error!"); }
- 変数の型に指定した場合、neverしか受け付けない
let something: never;
[memo] いつ使うの?後日別記事で補足予定。
引数の型を指定する
function methodC(num1: number, num2: number):numbler { return value1 * value2; }
型としての関数
- 変数に関数を代入する
function methodB(): void { console.log("Hello!"); } let myFunctionType; myFunctionType = methodB; myFunctionType()
- 変数に代入する関数の型を指定することで代入できる関数を制限することができる
let myFunctionType: (val1: number, val2: number) => number;
オブジェクト
- オブジェクトの定義例
let userDate = { name: "太郎", age: 30, }
- 内部的な解釈
let userData: { name: string, age: number, } = { name: 太郎, age: 30, }
- 指定したプロパティ名しか使えない
- 指定したプロパティ名に指定した型のデータしかセットできない
- プロパティを増やせない
userData["place"] = "東京" // エラーになる
エイリアス
- 同じ条件を繰り返し使いたいときに使える
type Complex = { data: number[], output: (all: boolean) => number[] } let complex2: Complex = { data: [100, 200, 1.2], output: function(flag: boolean) => number[] { return this.data; } }
union
- 共同体型、合併型
- 複数の型を許可すべきときに使う
let thisYear: number | string;
- nullと組み合わせることが多いかも
2020年英語学習計画
はじめに
今年の目標に「英語を聴ける・話せるようになる」ってのがありまして、今年はどういうアプローチで学習を進めようかなーと思ってる。今日本屋に行ったので吟味して、結局挿絵が好みな「[超初心者向け]英会話は最初の2、3語でなんとかなる!」でインプット」って本を買ってみた。(挿絵描いてるイラストレーターさんをTwitterでフォローしてるのだけど、とても好きな絵柄。しかも柴犬が出てくる!!!最高!!!私にターゲティングしているとしか思えない。)あと、著者の方がアメリカ生活を経験しているというのも説得力あるなと思って買ってみた。内容は去年のはじめに買った「純ジャパの僕が10カ国語を話せた 世界一シンプルな外国語勉強法」と近い考え方だなとは思ったけど、読みやすい構成になっているし、柴犬は私のモチベーション維持に重要な存在なので、勢いで買うことにした。本を買ったついでに、去年の振り返りと今年の学習計画を書いてみたいと思う。
2019年にやったこと
- 「純ジャパの僕が10カ国語を話せた 世界一シンプルな外国語勉強法」を読んで実践(2019/1月〜)
- 読んで理屈に納得し、やる気満々に。3ヶ月後にはペラペラになっている!と意気込んでいたのが去年の1月はじめ。
- 単語帳を作成して、実践したけど続かなかった...
- EnCube(2019/2月〜)
- たまたま見つけて良さそうだったので、申し込んだ。サブスクリプションのサービスで毎日朝晩1つずつ、1日2つコンテンツが見られるようになる。1つ15分程度で、1日分のコンテンツは30分ほど。
- 内容はとてもよかった。特にイムラン先生のコンテンツはとても好みでわかりやすかった。
- ちゃんとやろうと思うと、動画30分+復習30分必要。(私の場合だと)
- コンテンツを消化できていなくても毎日コンテンツが増え、毎月費用が発生する。毎日続けられず、消費できないコンテンツが溜まっていくことがストレスになってしまい、ちょうどその時、i-smileを見つけたので切り替えることにした。
i-smile(2019/7下旬〜)
- 2ヶ月と期間が決まっており、料金も一括で払いきり。しかもその後もコンテンツを見返せる。その上、一方的ではなく、双方向にLINEなどでコミュニケーションを取れるため、続けられそうだと感じ、始めることに。
- 以下理由で自分に向いており、毎日英語学習をする習慣がついた
- 強化して行きたいと感じたこと
- i-smileで得たこと
- 英語学習を毎日続ける習慣がついた。しないと気持ち悪く感じるくらい。続けられる自信がついた。
- Skypeレッスンで発音を褒められることが多く、発音に対する苦手意識がなくなった。身につけていける手応えを感じた。自信がついた。
- 自分はどういうスタイルだと学習を続けていけるか、という傾向がわかった。
瞬間英作文(アプリ)
2020年やること
できるようになりたいこと
- 聴けるようになること
- 技術カンファレンスの英語セッションが聴けるようになること
- 外国人に話しかけられた時に、何を言っているかわかるようになること
- 話せるようになること
- 言いたいことが言えるようになること
やっていくこと
- 聴く
- TEDを聴く(いきなりカンファレンス動画や映画だと長いので短いものから)
- 優先度:高
- いつ:隙間時間
- フォニックス動画で発音を学ぶ
- 優先度:高
- いつ:隙間時間
- 去年やったi-smileの教材(2ヶ月分)を復習する
- 優先度:低
- いつ:未定
- TEDを聴く(いきなりカンファレンス動画や映画だと長いので短いものから)
- 話す
- 必要最低限単語を覚える
- 「[超初心者向け]英会話は最初の2、3語でなんとかなる!」でインプット
- 優先度:高
- いつ:隙間時間
- 必要最低限フレーズを覚える
- 「[超初心者向け]英会話は最初の2、3語でなんとかなる!」でインプット
- 優先度:高
- いつ:隙間時間
- 日常的に使う、口に出すようにする
- 独り言、ツイート
- 優先度:高
- いつ:隙間時間
- レアジョブを始める
- 優先度:中
- いつ:未定
- 必要最低限単語を覚える
続けるために、身に着けるために
- 楽しいを優勢する、楽しくなる方法で学習する
- 楽しくないと身につかない、続けられないから
- 集中して取り組むこと
- だらだらと長くなんとなく毎日続けるのではなく、短時間でも集中してやること
- 他者を巻き込むこと
- 何か締め切りみたいなものがないとサボっちゃうのですぐレアジョブを始めちゃうとかして、何かしらの強制力を持たせる
意気込み
去年、外国人の方に話しかけられたけど何と言っているかわからず、何も返せないことがあった。また、別の外国人の方に「英語を話せないとダメだよ」と直接言われることもあった。その出来事はかなり強烈で情けないと思った。英語を話せるようになりたいとずっと思っていたけど、今度こそ絶対に身に着けるぞという決意が一段階上がる出来事だった。そう思うとその出来事にはとても感謝している。2020年はオリンピックもあるし、ひとまず今から半年、リスニングとスピーキングに注力して鍛えていくぞ。
RxJSメモ(1)
はじめに
これは自分用メモです。時間がたつと忘れたりするので、すぐ見返すことができるようにするためのものです。カジュアルに書いて更新していく方針です。
今日はUdemyの動画をみて、内容を簡単にまとめました。自分が見返して思い出せるレベルのメモです。見た講座は こちら。
動画を作っていらっしゃる方の表現がわかりやすく、個人的におすすめです。(少し前に公開されたもので、Angularのバージョンは5ですが)
それでも初めて見たときはあんまりピントきていませんでした。実際にコードを読んだり書いたりするようになって、また見返してみるとわかりやすい!理解深まってる!と感じたので、やっぱりドキュメント読んだり動画見たりってのと併せて書いてみるのが一番だなって思いました。
特にサンプルコードだけだと自分の場合、どこで使うんだ?ってとこまでぴんと来なかったりするので、何かしら自分で作ってみるなりするのが良さそう。(RxJSの場合、Rxなんちゃらに馴染みがあればすぐピンとくるんだろうなとは思います。)実務で使えたら一番すっと入ってくると思います。今は使っているので各オペレーターとかあーなるほどーとなります。以下、キーワードと説明です。自分用なので超簡潔です。
RxJS
リアクティブプログラミングを簡単に実装するためのライブラリ。JavaScript用。
リアクティブプログラミング
通知されてくるデータを受け取るたびに関連したプログラムが反応して処理を行うようにするプログラミングの考え方。非同期処理を直感的に書ける。
Observable
非同期データソース(ストリーム)を表すクラス。Observe(観察)する何か。
Stream
データが流れる仕組み。1本の川にイベントやデータを流すイメージ。
オペレータ
流れてくるデータを中間で操作するメソッド群。
以下、オペレータ一部抜粋
map
流れてきたデータを使って加工したデータを流すことができる。
debounceTime
連続するデータの間引き処理をする。具体的には、最後にデータが流れたタイミングから指定したミリ秒の間は流れないようにするという制御ができる。
throttleTime
指定したミリ秒ごとに処理が実行されるように制御できる。
distinctUntilChanged
前回と異なる値が流れた場合のみストリームを流す。変更があった場合だけなんらかの処理をしたい場合等に使える。
merge
複数のObservableを1本にまとめたものをストリームに流す。
switchMap
ストリームAに流れてくるデータをもとに別のストリームBを流す。別のストリームBが終わる前に元のストリームAが流れた場合、Bは途中でキャンセル・破棄され、初めから再び実行される。
skip
引数で指定した回数分のストリームを流さず、スキップする。
take
引数で指定した回数分のみストリームにデータを流す。
Subscribe
下流で流れてくるデータを受け取って処理する(toPromise.thenでもできる)
Subscribe([受け取った時のコールバック]、[エラー時のコールバック]、[処理完了時のコールバック])
asyncパイプ
Subscribeを明示的に受け取らなくてもテンプレート側でストリームに流れてきたデータを受け取ることができる。コードがシンプルになる。
Subject
ObservableだとSubscribeしたタイミングで流れる。また、1度しか流れない。 SubjectはObservableを継承している。任意のタイミングでデータを流せる。 Sbscribeするときのcallbackなど(Observer)を保持している。
主な使われ方
1.Servise側でSubjectを初期化
2.公開コンポーネントでSubjectを監視する
参考
メモ
いい感じに図で表現したい気持ちはある。おいおいできたらな。