Slide 1

Slide 1 text

フロントエンド開発に役立つクライアントプログラム共通のノウハウ nrs

Slide 2

Slide 2 text

2 Profile nrs(成瀬 允宣) @nrslib コドモンのCTO 趣味:カンファレンス講演 学生支援 小学校支援 写真

Slide 3

Slide 3 text

3 ● フロントエンドカンファレンス北海道2024で喋ったりするぐらいは好き ○ カメラマンもしてました フロントエンドやってるの?

Slide 4

Slide 4 text

4 フロントエンド遍歴

Slide 5

Slide 5 text

5 フロントエンド遍歴

Slide 6

Slide 6 text

6 フロントエンド遍歴

Slide 7

Slide 7 text

7 フロントエンド遍歴

Slide 8

Slide 8 text

8 フロントエンド遍歴

Slide 9

Slide 9 text

9 フロントエンド遍歴 JavaScript

Slide 10

Slide 10 text

10 フロントエンド遍歴 JavaScript

Slide 11

Slide 11 text

11 フロントエンド遍歴 JavaScript

Slide 12

Slide 12 text

12 フロントエンド遍歴 JavaScript

Slide 13

Slide 13 text

13 フロントエンド遍歴 JavaScript 基本は一緒

Slide 14

Slide 14 text

14 フロントエンド遍歴 JavaScript つらみも一緒

Slide 15

Slide 15 text

たのしいゲーム開発

Slide 16

Slide 16 text

16 ディレクター「おはよう」 朝令暮改

Slide 17

Slide 17 text

17 ディレクター「おはよう」 ぼく「おはようございます、ここんところどうしましょう?」 朝令暮改

Slide 18

Slide 18 text

18 ディレクター「□□にしてくれる?」 朝令暮改

Slide 19

Slide 19 text

19 ディレクター「□□にしてくれる?」 ぼく「御意」 朝令暮改

Slide 20

Slide 20 text

20 朝令暮改 時はすぎて夕方……

Slide 21

Slide 21 text

21 ぼく「できました」 朝令暮改

Slide 22

Slide 22 text

22 ぼく「できました」 ディレクター「なんか思ったんと違うなー」 朝令暮改

Slide 23

Slide 23 text

23 ディレクター「やっぱ△△にしといて」 朝令暮改

Slide 24

Slide 24 text

24 ディレクター「やっぱ△△にしといて」 ぼく「御意」 朝令暮改

Slide 25

Slide 25 text

25 朝令暮改 時はすぎて翌日……

Slide 26

Slide 26 text

26 ディレクター「一晩考えたんだけどさー」 朝令暮改

Slide 27

Slide 27 text

27 ディレクター「〇〇にできる?」 朝令暮改

Slide 28

Slide 28 text

28 ディレクター「〇〇にできる?」 ぼく「御意」 朝令暮改

Slide 29

Slide 29 text

たのしいゲーム開発・その2

Slide 30

Slide 30 text

30 保守? ねぇよそんなもん

Slide 31

Slide 31 text

31 ● コンシューマゲームって更新できますか? 保守? ねぇよそんなもん

Slide 32

Slide 32 text

32 ● コンシューマゲームって更新できますか? ○ できないですよね 保守? ねぇよそんなもん

Slide 33

Slide 33 text

33 ● コンシューマゲームって更新できますか? ○ できないですよね ■ え? できます? 保守? ねぇよそんなもん

Slide 34

Slide 34 text

34 ● コンシューマゲームって更新できますか? ○ できないですよね ■ え? できます? ● それ最近のゲームですよね? 保守? ねぇよそんなもん

Slide 35

Slide 35 text

35 ● コンシューマゲームって更新できますか? ○ できないですよね ■ え? できます? ● それ最近のゲームですよね? ○ ファミコンとかスーファミ時代にあります? 保守? ねぇよそんなもん

Slide 36

Slide 36 text

36 ● ソシャゲ流行りましたよね 保守? ねぇよそんなもん

Slide 37

Slide 37 text

37 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? 保守? ねぇよそんなもん

Slide 38

Slide 38 text

38 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? ■ むしろ、更新しなきゃユーザー離れますよね? 保守? ねぇよそんなもん

Slide 39

Slide 39 text

39 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? ■ むしろ、更新しなきゃユーザー離れますよね? ● 流行りにのった会社の開発者ってどういう人達だと思いま す? 保守? ねぇよそんなもん

Slide 40

Slide 40 text

40 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? ■ むしろ、更新しなきゃユーザー離れますよね? ● 流行りにのった会社の開発者ってどういう人達だと思いま す? ○ コンシューマゲームを作ってた人たちです! 保守? ねぇよそんなもん

Slide 41

Slide 41 text

41 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? ■ むしろ、更新しなきゃユーザー離れますよね? ● 流行りにのった会社の開発者ってどういう人達だと思いま す? ○ コンシューマゲームを作ってた人たちです! ■ つまり、保守性は… 保守? ねぇよそんなもん

Slide 42

Slide 42 text

42 ● ソシャゲ流行りましたよね ○ ソシャゲは更新しますよね? ■ むしろ、更新しなきゃユーザー離れますよね? ● 流行りにのった会社の開発者ってどういう人達だと思いま す? ○ コンシューマゲームを作ってた人たちです! ■ つまり、保守性は…… ● 後ほど語ります 保守? ねぇよそんなもん

Slide 43

Slide 43 text

たのしいゲーム開発・その3

Slide 44

Slide 44 text

44 テスト? ねぇよそんなもん

Slide 45

Slide 45 text

45 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) テスト? ねぇよそんなもん

Slide 46

Slide 46 text

46 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました テスト? ねぇよそんなもん

Slide 47

Slide 47 text

47 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です テスト? ねぇよそんなもん

Slide 48

Slide 48 text

48 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です ● ちなみに私も得意でした テスト? ねぇよそんなもん

Slide 49

Slide 49 text

49 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です ● ちなみに私も得意でした ○ 「なんかこのボタンぷるってすんなぁ!?」 テスト? ねぇよそんなもん

Slide 50

Slide 50 text

50 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です ● ちなみに私も得意でした ○ 「なんかこのボタンぷるってすんなぁ!?」 ○ 「どうせここを連打されるのが嫌なんだろ!?」 テスト? ねぇよそんなもん

Slide 51

Slide 51 text

51 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です ● ちなみに私も得意でした ○ 「なんかこのボタンぷるってすんなぁ!?」 ○ 「どうせここを連打されるのが嫌なんだろ!?」 ○ 「なんか1Fおかしいぞここ」 テスト? ねぇよそんなもん

Slide 52

Slide 52 text

52 ● テストなんて書いても見た目が伴わなければ何の意味もないんだよ!(暴 論) ○ 結果的にデバッガーという職種が発達してました ■ デバッグ得意な人は開発者が嫌なところをよく知ってる人です ● ちなみに私も得意でした ○ 「なんかこのボタンぷるってすんなぁ!?」 ○ 「どうせここを連打されるのが嫌なんだろ!?」 ○ 「なんか1Fおかしいぞここ」 ○ 最近は自動テストをやってるケースも増えてきたようだ テスト? ねぇよそんなもん

Slide 53

Slide 53 text

そんな楽しい現場経験から得られたもの

Slide 54

Slide 54 text

54 ● データを操作するのは一箇所のみ ● コンポーネントはめんどくさいと使われない ● コンポーネントは気づかれないと使われない ● StateMachine実装 ● Mediatorパターン ● イベントヘル ● グローバルやめよ ● : 今でも役立つゲーム開発で得たノウハウ

Slide 55

Slide 55 text

55 ● データを操作するのは一箇所のみ ● コンポーネントはめんどくさいと使われない ● コンポーネントは気づかれないと使われない ● StateMachine実装 ● Mediatorパターン ● イベントヘル ● グローバルやめよ ● : 今でも役立つゲーム開発で得たノウハウ フロントエンド開発でも 役立った!

Slide 56

Slide 56 text

データを操作するのは一箇所のみ

Slide 57

Slide 57 text

57 ● Single Source of Truth SSOT

Slide 58

Slide 58 text

58 ● Single Source of Truth ○ 信頼できる唯一の情報源 ○ すべてのデータが一箇所のみで作成、あるいは編集できるようにする SSOT

Slide 59

Slide 59 text

59 ● Single Source of Truth ○ 信頼できる唯一の情報源 ○ すべてのデータが一箇所のみで作成、あるいは編集できるようにする ○ フロントエンドのための格言ではない ■ が、意識するととってもいいぞ! SSOT

Slide 60

Slide 60 text

60 更新し忘れる Component A Component B Component C Component D Component F Name:nrs Name:nrs Name:nrs Name:nrs Name:nrs

Slide 61

Slide 61 text

61 更新し忘れる Component A Component B Component C Component D Component F Name:nrslib Name:nrs Name:nrs Name:nrs Name:nrs

Slide 62

Slide 62 text

62 更新し忘れる Component A Component B Component C Component D Component F Name:nrslib Name:nrslib Name:nrs Name:nrslib Name:nrslib

Slide 63

Slide 63 text

63 更新し忘れる Component A Component B Component C Component D Component F Name:nrslib Name:nrslib Name:nrs Name:nrslib Name:nrslib

Slide 64

Slide 64 text

64 実はもうちょっと深刻なんだ Component A Component B Component C Component D Component F Ptr: 1 Name:nrs Ptr: 1 Name:nrs Ptr: 2 Name:nrs Ptr: 1 Name:nrs Ptr: 1 Name:nrs

Slide 65

Slide 65 text

65 実はもうちょっと深刻なんだ Component A Component B Component C Component D Component F Ptr: 1 Name:nrslib Ptr: 1 Name:nrs Ptr: 2 Name:nrs Ptr: 3 Name:nrs Ptr: 1 Name:nrs

Slide 66

Slide 66 text

66 実はもうちょっと深刻なんだ Component A Component B Component C Component D Component F Ptr: 1 Name:nrslib Ptr: 1 Name:nrslib Ptr: 2 Name:nrs Ptr: 1 Name:nrslib Ptr: 3 Name:nrs

Slide 67

Slide 67 text

67 実はもうちょっと深刻なんだ Component A Component B Component C Component D Component F Ptr: 1 Name:nrslib Ptr: 1 Name:nrslib Ptr: 2 Name:nrs Ptr: 1 Name:nrslib Ptr: 3 Name:nrs

Slide 68

Slide 68 text

68 どうするかというと Component A Component B Component C Component D Component F Name:nrs Name:nrs Name:nrs Name:nrs Name:nrs

Slide 69

Slide 69 text

69 どうするかというと Component A Component B Component C Component D Component F Name:nrs Name:nrs Name:nrs Name:nrs Name:nrs 更新したい!

Slide 70

Slide 70 text

70 どうするかというと Component A Component B Component C Component D Component F Name:nrs Name:nrs Name:nrs Name:nrs Name:nrs 更新したい

Slide 71

Slide 71 text

71 どうするかというと Component A Component B Component C Component D Component F Name:nrslib Name:nrs Name:nrs Name:nrs Name:nrs

Slide 72

Slide 72 text

72 どうするかというと Component A Component B Component C Component D Component F Name:nrslib Name:nrs Name:nrs Name:nrs Name:nrs Name:nrslib Name:nrslib

Slide 73

Slide 73 text

73 どうするかというと Component A Component B Component C Component D Component F Name:nrslib Name:nrslib Name:nrslib Name:nrs Name:nrs Name:nrslib Name:nrslib

Slide 74

Slide 74 text

74 どうするかというと Component A Component B Component C Component D Component F Name:nrslib Name:nrslib Name:nrslib Name:nrs Name:nrs Name:nrslib Name:nrslib

Slide 75

Slide 75 text

75 どうするかというと Component A Component B Component C Component D Component F Name:nrslib Name:nrslib Name:nrslib Name:nrslib Name:nrslib

Slide 76

Slide 76 text

76 ARVだと

Slide 77

Slide 77 text

77 ARVだと

Slide 78

Slide 78 text

78 ● 子コンポーネントへの伝搬はプロパティバインディングで実現 ARVだと Component C Component D Component F Name:nrslib Name:nrs Name:nrs Name:nrslib Name:nrslib

Slide 79

Slide 79 text

79 ● React ○ https://react.dev/learn/passing-props-to-a-component ARVの説明にもあるよね

Slide 80

Slide 80 text

80 ● Vue ○ https://vuejs.org/guide/components/props.html ARVの説明にもあるよね

Slide 81

Slide 81 text

81 ● https://v2.vuejs.org/v2/style-guide props down, events up

Slide 82

Slide 82 text

コンポーネントはめんどくさいと使われない

Slide 83

Slide 83 text

83 悲しみの物語 みんな使えそうなコンポーネントを たくさん作ったぞ! これでみんな楽になるぞ!!

Slide 84

Slide 84 text

84 悲しみの物語 ……あれ? 使ってない?

Slide 85

Slide 85 text

85 悲しみの物語 WindowYesNoと YesNoWindowがある……

Slide 86

Slide 86 text

86 悲しみの物語 あの…… なんでコンポーネントを 作ってるんです?

Slide 87

Slide 87 text

87 悲しみの物語 めんどくさかったから

Slide 88

Slide 88 text

type MyButtonProps = { text: string; primary: boolean; size: 'small' | 'medium' | 'large'; icon: string; iconPosition: 'left' | 'right'; borderRadius: string; padding: string; margin: string; fontFamily: string; fontSize: string; fontWeight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 'normal' | 'bold'; textTransform: 'none' | 'uppercase' | 'lowercase' | 'capitalize'; letterSpacing: string; lineHeight: string | number; shadow: boolean; shadowColor: string; shadowBlur: number; onClick: (event: React.MouseEvent) => void; } これは極端な例だが……

Slide 89

Slide 89 text

89 どうしたら使ってくれるんだ

Slide 90

Slide 90 text

HTMLを信じろ ボタン

Slide 91

Slide 91 text

91 ● Progressive Disclosure ○ ユーザーが必要な時に必要な情報や機能にアクセスできるようにする ● 成功のポイント ○ 80/20ルール ■ 80%のケースで使われる機能を20%の労力で使えるよう ○ 段階的な複雑性 ■ 簡単なことは簡単に、複雑なことも可能に ○ Sensible Defaults ■ 殆どの場合でそのまま使える めんどくさいと使われない

Slide 92

Slide 92 text

コンポーネントは気づかれないと使われない

Slide 93

Slide 93 text

93 悲しみの物語2 みんな使えそうなコンポーネントを たくさん作ったぞ! これでみんな楽になるぞ!!

Slide 94

Slide 94 text

94 悲しみの物語2 ……あれ? 使ってない?

Slide 95

Slide 95 text

95 悲しみの物語2 あの…… なんでコンポーネントを 作ってるんです?

Slide 96

Slide 96 text

96 悲しみの物語2 え? あったの?

Slide 97

Slide 97 text

97 今どきはStorybook

Slide 98

Slide 98 text

98

Play Ground

Dropdown Table Modal Tab Password Button Text FormElement & Validator datepicker L@@ding ProgressTracker Progress Checkbox Panel VariableInput RadioGroup Clipboard InnerWizard Tooltip ConfigurationTips Pager Anchor Capacity EmptyPanel Carousel Graph import { Component } from 'vue-property-decorator'; import { BasePage } from '@lib/vue/BasePage'; import NormalTemplate from 'front/atomic/Templates/Layer/NormalTemplate.vue'; import LinkButton from 'front/atomic/Atoms/Button/LinkButton.vue'; @Component({ components: { LinkButton, NormalTemplate }, }) export default class ModulePlayGroundRootPage extends Vue {}

Slide 99

Slide 99 text

99 気づかれないと使われない

Slide 100

Slide 100 text

100 ● Discoverability(発見可能性)を考慮しよう 気づかれないと使われない

Slide 101

Slide 101 text

101 ● Discoverability(発見可能性)を考慮しよう ○ メンバーに「ここにあるよ!」といっても聞き流される 気づかれないと使われない

Slide 102

Slide 102 text

102 ● Discoverability(発見可能性)を考慮しよう ○ メンバーに「ここにあるよ!」といっても聞き流される ○ 開発プロセスの中で「とりあえず見てみるか」の流れを作る ■ ただあるだけじゃなくて触れる状況もセット 気づかれないと使われない

Slide 103

Slide 103 text

103 ● Discoverability(発見可能性)を考慮しよう ○ メンバーに「ここにあるよ!」といっても聞き流される ○ 開発プロセスの中で「とりあえず見てみるか」の流れを作る ■ ただあるだけじゃなくて触れる状況もセット ○ 最近は AI エージェントに聞くというアプローチも効果的 気づかれないと使われない

Slide 104

Slide 104 text

StateMachine 実装

Slide 105

Slide 105 text

105 ● オブジェクトごとに主行動はひとつである ゲームオブジェクト制御

Slide 106

Slide 106 text

106 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ゲームオブジェクト制御

Slide 107

Slide 107 text

107 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ゲームオブジェクト制御

Slide 108

Slide 108 text

108 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ■ 走るボタンとガードボタンとポーズボタンが同時に押されたら? ゲームオブジェクト制御

Slide 109

Slide 109 text

109 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ■ 走るボタンとガードボタンとポーズボタンが同時に押されたら? ● 優先度が高いものだけを実行する! ゲームオブジェクト制御

Slide 110

Slide 110 text

110 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ■ 走るボタンとガードボタンとポーズボタンが同時に押されたら? ● 優先度が高いものだけを実行する! ○ 純粋なイベントドリブンにすると ゲームオブジェクト制御

Slide 111

Slide 111 text

111 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ■ 走るボタンとガードボタンとポーズボタンが同時に押されたら? ● 優先度が高いものだけを実行する! ○ 純粋なイベントドリブンにすると ■ 優先順位を制御しづらい ゲームオブジェクト制御

Slide 112

Slide 112 text

112 ● オブジェクトごとに主行動はひとつである ○ 毎フレーム更新される(俗に言うゲームループ) ○ イメージ:フレームごとにオブジェクトは1処理を行う ■ 走るボタンとガードボタンとポーズボタンが同時に押されたら? ● 優先度が高いものだけを実行する! ○ 純粋なイベントドリブンにすると ■ 優先順位を制御しづらい ■ その行動が可能かの確認処理が散在する ゲームオブジェクト制御

Slide 113

Slide 113 text

113 StateMachine

Slide 114

Slide 114 text

type GamePhase = "mainMenu" | "gamePlay" | "pause" | "gameOver" | "victory"; class GameCoordinator { private phase: GamePhase = "mainMenu"; constructor() { // 初期化処理 } start(): void { this.step("mainMenu"); } private step(phase: GamePhase): void { switch (phase) { case "mainMenu": this.stepMainMenu(); break; case "gamePlay": this.stepGamePlay(); break; case "pause": this.stepPause(); break; case "gameOver": this.stepGameOver(); break; case "victory": this.stepVictory(); break; } this._phase = phase; } private stepMainMenu(): void { // Main Menu を開始 } private handleStartButtonClick(): void { this.step("gamePlay"); }

Slide 115

Slide 115 text

Mediator パターン

Slide 116

Slide 116 text

116 ● 選択中と未選択をどうやって制御する? たとえばこんな画面

Slide 117

Slide 117 text

const TabButton = forwardRef) => void; }>(({ id, label, onRegister }, ref) => { const [isActive, setIsActive] = useState(false); const otherButtons = useRef>>(new Map()); const selfRef = useRef(null); ... const handleClick = () => { otherButtons.current.forEach(buttonRef => { buttonRef.current?.deactivate(); }); setIsActive(true); }; return (...); });

Slide 118

Slide 118 text

const TabButton = forwardRef) => void; }>(({ id, label, onRegister }, ref) => { const [isActive, setIsActive] = useState(false); const otherButtons = useRef>>(new Map()); const selfRef = useRef(null); ... const handleClick = () => { otherButtons.current.forEach(buttonRef => { buttonRef.current?.deactivate(); }); setIsActive(true); }; return (...); });

Slide 119

Slide 119 text

119 動作イメージ

Slide 120

Slide 120 text

120 動作イメージ

Slide 121

Slide 121 text

121 動作イメージ

Slide 122

Slide 122 text

const TabButton: React.FC<{ id: string; label: string; isActive: boolean; onClick: (id: string) => void; }> = ({ id, label, isActive, onClick }) => { return ( onClick(id)}> {label} ); };

Slide 123

Slide 123 text

const TabButtonGroup: React.FC<{ tabs: Array<{ id: string; label: string }>; activeTab: string; onTabChange: (id: string) => void; }> = ({ tabs, activeTab, onTabChange }) => { return (
{tabs.map(tab => ( ))}
); };

Slide 124

Slide 124 text

124 動作イメージ

Slide 125

Slide 125 text

125 動作イメージ

Slide 126

Slide 126 text

126 動作イメージ

Slide 127

Slide 127 text

127 動作イメージ

Slide 128

Slide 128 text

128 ● 相互参照 ○ 5個のボタンなら 5*4 = 20 の参照 ○ O(n^2) の複雑度 動作イメージ

Slide 129

Slide 129 text

129 ● 相互参照 ○ 5個のボタンなら 5*4 = 20 の参照 ○ O(n^2) の複雑度 ● Mediator ○ 5個のボタンなら 5 = 5 の参照 ○ O(n) の複雑度 動作イメージ

Slide 130

Slide 130 text

130 ● 相互参照 ○ 5個のボタンなら 5*4 = 20 の参照 ○ O(n^2) の複雑度 ● Mediator ○ 5個のボタンなら 5 = 5 の参照 ○ O(n) の複雑度 ● どういう違い? ○ どのボタンがどのボタンを変更したか追跡困難 動作イメージ

Slide 131

Slide 131 text

イベントヘル

Slide 132

Slide 132 text

132 Action Script って知ってますか? ● Adobe ○ Flash

Slide 133

Slide 133 text

133 Event Driven ● Event Dispatcher

Slide 134

Slide 134 text

134 Event Driven ● Event Dispatcher ○ すごいぞ!

Slide 135

Slide 135 text

135 Event Driven ● Event Dispatcher ○ すごいぞ! ■ dipatchEvent

Slide 136

Slide 136 text

136 Event Driven ● Event Dispatcher ○ すごいぞ! ■ dipatchEvent ■ どのオブジェクトもイベント送出できるぞ!

Slide 137

Slide 137 text

137 Event Driven ● Event Dispatcher ○ すごいぞ! ■ dipatchEvent ■ どのオブジェクトもイベント送出できるぞ! ○ すごいぞ!

Slide 138

Slide 138 text

138 Event Driven ● Event Dispatcher ○ すごいぞ! ■ dipatchEvent ■ どのオブジェクトもイベント送出できるぞ! ○ すごいぞ! ■ addEventListener

Slide 139

Slide 139 text

139 Event Driven ● Event Dispatcher ○ すごいぞ! ■ dipatchEvent ■ どのオブジェクトもイベント送出できるぞ! ○ すごいぞ! ■ addEventListener ■ どのオブジェクトもイベント受け取れるぞ!

Slide 140

Slide 140 text

140 とっても自由です!

Slide 141

Slide 141 text

141 とっても自由です!

Slide 142

Slide 142 text

142 とっても自由です!

Slide 143

Slide 143 text

143 とっても自由です!

Slide 144

Slide 144 text

144 とっても自由です!

Slide 145

Slide 145 text

145 とっても自由です!

Slide 146

Slide 146 text

146 とっても自由です!

Slide 147

Slide 147 text

147 とっても自由です! ● 限度があるやろ!!!

Slide 148

Slide 148 text

148 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う

Slide 149

Slide 149 text

149 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う ○ グローバルにイベントが送出されて

Slide 150

Slide 150 text

150 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う ○ グローバルにイベントが送出されて ○ イベントを受け取ったオブジェクトがイベントを送出して

Slide 151

Slide 151 text

151 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う ○ グローバルにイベントが送出されて ○ イベントを受け取ったオブジェクトがイベントを送出して ○ 同時に別のオブジェクトからイベントが送出されて

Slide 152

Slide 152 text

152 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う ○ グローバルにイベントが送出されて ○ イベントを受け取ったオブジェクトがイベントを送出して ○ 同時に別のオブジェクトからイベントが送出されて ○ 入り組みながらイベントが送出されつづけ

Slide 153

Slide 153 text

153 とっても自由です! ● 限度があるやろ!!! ○ 1F の間にイベントが飛び交う ○ グローバルにイベントが送出されて ○ イベントを受け取ったオブジェクトがイベントを送出して ○ 同時に別のオブジェクトからイベントが送出されて ○ 入り組みながらイベントが送出されつづけ ○ 「このイベントはどこからきてるねん!?」

Slide 154

Slide 154 text

154 イベントヘル

Slide 155

Slide 155 text

155 イベントヘル ● イベントからイベントを発火するな

Slide 156

Slide 156 text

156 イベントヘル ● イベントからイベントを発火するな ○ イベントを受け取ったオブジェクトからイベントが送出

Slide 157

Slide 157 text

157 イベントヘル ● イベントからイベントを発火するな ○ イベントを受け取ったオブジェクトからイベントが送出 ○ そのイベントを受け取ったオブジェクト複数からイベントが送出

Slide 158

Slide 158 text

158 イベントヘル ● イベントからイベントを発火するな ○ イベントを受け取ったオブジェクトからイベントが送出 ○ そのイベントを受け取ったオブジェクト複数からイベントが送出 ○ オブジェクトとオブジェクトがイベントで会話をしだす……

Slide 159

Slide 159 text

159 イベントヘル ● イベントからイベントを発火するな ○ イベントを受け取ったオブジェクトからイベントが送出 ○ そのイベントを受け取ったオブジェクト複数からイベントが送出 ○ オブジェクトとオブジェクトがイベントで会話をしだす…… ○ その間1F

Slide 160

Slide 160 text

160 イベントヘル ● イベントからイベントを発火するな ○ イベントを受け取ったオブジェクトからイベントが送出 ○ そのイベントを受け取ったオブジェクト複数からイベントが送出 ○ オブジェクトとオブジェクトがイベントで会話をしだす…… ○ その間1F ○ そもそもイベントをグローバルに送出するな

Slide 161

Slide 161 text

static やめよ

Slide 162

Slide 162 text

162 static やめろ

Slide 163

Slide 163 text

グローバルやめよ

Slide 164

Slide 164 text

164 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード

Slide 165

Slide 165 text

165 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」

Slide 166

Slide 166 text

166 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」 ■ 緻密に編み込まれたジェンガ

Slide 167

Slide 167 text

167 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」 ■ 緻密に編み込まれたジェンガ ○ 脳内メモリの容量が違いすぎる

Slide 168

Slide 168 text

168 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」 ■ 緻密に編み込まれたジェンガ ○ 脳内メモリの容量が違いすぎる ■ 1F内にこの static なフィールドが何回書き換わってるんだ!?

Slide 169

Slide 169 text

169 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」 ■ 緻密に編み込まれたジェンガ ○ 脳内メモリの容量が違いすぎる ■ 1F内にこの static なフィールドが何回書き換わってるんだ!? ● データ更新したはずが書き換わってない!?

Slide 170

Slide 170 text

170 それはとても緻密な ● public static がふんだんに使われた奇跡のようなコード ○ 「このコードを書いた人間は天才に違いない」 ■ 緻密に編み込まれたジェンガ ○ 脳内メモリの容量が違いすぎる ■ 1F内にこの static なフィールドが何回書き換わってるんだ!? ● データ更新したはずが書き換わってない!? ○ (入念な更新をされているパターン)

Slide 171

Slide 171 text

171 グローバルやめたい ● プログラミング言語の歴史を紐解くとグローバル変数との戦いがある

Slide 172

Slide 172 text

172 グローバルやめたい ● プログラミング言語の歴史を紐解くとグローバル変数との戦いがある ○ 人類はかくしてスコープを手にした

Slide 173

Slide 173 text

173 グローバルやめたい ● プログラミング言語の歴史を紐解くとグローバル変数との戦いがある ○ 人類はかくしてスコープを手にした ● Fluxアーキテクチャのつらさに気づきましたか?

Slide 174

Slide 174 text

174 グローバルやめたい ● プログラミング言語の歴史を紐解くとグローバル変数との戦いがある ○ 人類はかくしてスコープを手にした ● Fluxアーキテクチャのつらさに気づきましたか? ○ やりたかったこと ■ グローバルな状態を扱いたい ■ グローバル変数制御の無秩序さをやめたい

Slide 175

Slide 175 text

175 グローバルやめたい ● プログラミング言語の歴史を紐解くとグローバル変数との戦いがある ○ 人類はかくしてスコープを手にした ● Fluxアーキテクチャのつらさに気づきましたか? ○ やりたかったこと ■ グローバルな状態を扱いたい ■ グローバル変数制御の無秩序さをやめたい ○ グローバルな状態以外で使うのはイマイチ

Slide 176

Slide 176 text

176 グローバル+イベント+static+並行並列はガチ

Slide 177

Slide 177 text

177 グローバル+イベント+static+並行並列はガチ ● ブレークポイント効かねぇ

Slide 178

Slide 178 text

178 グローバル+イベント+static+並行並列はガチ ● ブレークポイント効かねぇ ○ マルチスレッドのためタイミング依存のバグが再現できない

Slide 179

Slide 179 text

179 グローバル+イベント+static+並行並列はガチ ● ブレークポイント効かねぇ ○ マルチスレッドのためタイミング依存のバグが再現できない ○ 対策はログだが……

Slide 180

Slide 180 text

180 グローバル+イベント+static+並行並列はガチ ● ブレークポイント効かねぇ ○ マルチスレッドのためタイミング依存のバグが再現できない ○ 対策はログだが…… ■ 奇跡のコードなのでログを仕込んだせいでタイミングがズレる

Slide 181

Slide 181 text

ページ遷移はどこでする?

Slide 182

Slide 182 text

182 遷移の情報はどこに置く? Page Component Component B Component C Component D Component F Click!

Slide 183

Slide 183 text

export const OrderHistoryPage: React.FC = () => { const navigate = useNavigate(); const orders = [ { id: '1', productName: 'MacBook Pro', status: 'delivered' as const, total: 298000 }, { id: '2', productName: 'iPad Air', status: 'shipped' as const, total: 92800 } ]; const handleViewDetail = (orderId: string) => { navigate(`/orders/${orderId}`); }; const handleRequestInvoice = (orderId: string) => { navigate(`/orders/${orderId}/invoice`); }; return (
{/* 固定的な遷移は自己完結 */}

注文履歴

{orders.map(order => ( handleViewDetail(order.id)} {/* 文脈的な遷移は制御 */} onRequestInvoice={() => handleRequestInvoice(order.id)} /> ))}
); };

Slide 184

Slide 184 text

184 ● 個人的なルール ○ グローバルナビゲーション ■ コンポーネントに埋め込む ○ コンテキスト依存 ■ ページ相当のコンポーネントで制御する ● 結果として ○ ページ相当のコンポーネントを見れば、どう遷移するかわかる! 遷移の性質

Slide 185

Slide 185 text

185 遷移の情報はどこに置く? Page Component Component B Component C Component D Component F Click! Transition

Slide 186

Slide 186 text

186 遷移の情報はどこに置く? Page Component Component B Component C Component D Component F Transition Information Transition Information Transition Click!

Slide 187

Slide 187 text

GUIとオブザーバーパターン

Slide 188

Slide 188 text

188 MVC ● あなたの思う MVC パターンはどっち?

Slide 189

Slide 189 text

189 Classic MVC ● MVX兄弟の元祖 ○ あんまり最近はこう作らない ○ この前に遡ると ■ Document Viewとか

Slide 190

Slide 190 text

190 MVC2 ● WebフレームワークのMVC ○ MVCをHTTPベースに ○ Modelの変更 ■ サーバーから通知できない

Slide 191

Slide 191 text

191 MVP ● あなたの思うMVPパターンはどっち?

Slide 192

Slide 192 text

192 MVP (Supervising Controller) ● オブザーバーパターンを使う ○ タイミング調整がめんどい ■ ディレイかけたい…… ○ 個人的に名前がかっこよくて好き

Slide 193

Slide 193 text

193 MVP (Passive View) ● Viewは受け身でなにもしない ○ Presenterが仲介する ○ Humble View とも

Slide 194

Slide 194 text

194 MVVM ● MVP(Passive View)で双方向バインディングするとこれになる

Slide 195

Slide 195 text

195 ● データとViewを分離したい ● 複数のViewが同じデータを表示したい GUIとObserverパターンはなかよし

Slide 196

Slide 196 text

Observerパターンで朝令暮改に対応する話

Slide 197

Slide 197 text

197 よくある朝令暮改 Main Component A Component B Component C Component D Name:nrs Component E

Slide 198

Slide 198 text

198 よくある朝令暮改 Main Component A Component B Component C Component D Name:nrs Component E Name:nrs ここに表示 することになった Name:nrs ここに表示 することになった

Slide 199

Slide 199 text

199 よくある朝令暮改 Main Component A Component B Component C Component D Name:nrs Component E Name:nrs Name:nrs Name:nrs

Slide 200

Slide 200 text

200 これじゃそんなに早くなくて 驚かせられないなー よくある朝令暮改 Main Component A Component B Component C Component D Name:nrs Component E Name:nrs Name:nrs Name:nrs

Slide 201

Slide 201 text

201 爆速目指そう Main Component A Component B Component C Component D Name:nrs Component E

Slide 202

Slide 202 text

202 ● IObservavleを保持 爆速目指そう Main Component A Component B Component C Component D Name:nrs Component E Component C Component E

Slide 203

Slide 203 text

203 ● もし新たに必要になったら 爆速目指そう Main Component A Component B Component C Component D Name:nrs Component E Component C Component E Name:nrs ここに表示 することになった

Slide 204

Slide 204 text

204 爆速目指そう Main Component A Component B Component C Component D Name:nrs Component E Component C Component E IObservavle を実装継承

Slide 205

Slide 205 text

205 データを必要なオブジェクトが 表明するだけで使える! 爆速目指そう Main Component A Component B Component C Component D Name:nrs Component E Component C Component E Component A

Slide 206

Slide 206 text

206 ディレクター「おはよう」 ぼく「おはようございます、ここんところどうしましょう?」 朝令暮改

Slide 207

Slide 207 text

207 ディレクター「□□にしてくれる?」 ぼく「御意」 朝令暮改

Slide 208

Slide 208 text

208 朝令暮改 1時間後

Slide 209

Slide 209 text

209 ぼく「できました」 ディレクター「もう!?」 朝令暮改

Slide 210

Slide 210 text

まとめ

Slide 211

Slide 211 text

211 朝令暮改を 朝礼朝改で返して 怖がらせ ましょう!

Slide 212

Slide 212 text

212 エンジニアリングの醍醐味を知った ● 相手の予想を超える楽しさ ○ 相手の驚いた顔を見たくてやってる ● 人の心を知る ○ 水の低きに就くが如し

Slide 213

Slide 213 text

213 まとめ ● GUIのノウハウを活用すれば ○ 実装に困った時に基本に立ち返られる ○ ライブラリが滅んでも ■ ARV がなくても秩序をもたらすことができる ■ jQuery でも確実なコードを書ける ■ JavaScriptだけしか使えない状況も乗り越えられるぞ

Slide 214

Slide 214 text

214 仲間を探しています 子どもを取り巻く環境をテクノロジーの力でよりよいものにしていく仲間を大募集! ● 子育てしやすい環境です ○ 子育てにドメイン知識がありすぎるメンバー ○ フレックス/フルリモート可 ● 開発者体験が最高です ○ アジャイル(XP) ○ バーチャルオフィス(Gather) ○ コンフォートゾーンを抜け出せるような環境 ○ CTOが財布 #CTOは財布