1
00:00:00,440 --> 00:00:02,600
こんにちは。
前回のセッションでは

2
00:00:02,760 --> 00:00:06,880
真偽値の not と or の
実装方法をみてきました。

3
00:00:07,040 --> 00:00:11,960
3つ目の問題が残っています。
一体なぜこれらの問題をやるのか？

4
00:00:12,120 --> 00:00:13,880
それを学びます。

5
00:00:14,760 --> 00:00:20,120
実装を振り返ってみましょう。
not について。2つのオブジェクトがありました。

6
00:00:20,280 --> 00:00:22,400
true と false です。

7
00:00:22,560 --> 00:00:25,440
True クラスと False クラスのインスタンスでした。

8
00:00:25,600 --> 00:00:27,200
not メッセージを送ると

9
00:00:27,360 --> 00:00:31,640
それぞれに対応するクラスに問い合わせて
メソッドを実行しました。

10
00:00:32,560 --> 00:00:34,080
問題ないですね。

11
00:00:35,120 --> 00:00:37,240
伝えたことは

12
00:00:37,400 --> 00:00:39,720
何かと言うと

13
00:00:39,880 --> 00:00:42,920
まず第一に、レシーバーに決めさせること。

14
00:00:43,080 --> 00:00:46,080
つまり、自分では何も決めないで

15
00:00:46,240 --> 00:00:49,320
メッセージを送ることで解決します。

16
00:00:49,480 --> 00:00:53,840
経験則が2つありました。
レシーバーに決めさせること。

17
00:00:54,000 --> 00:00:57,320
そして、「求めるな、命じよ」です。

18
00:00:57,480 --> 00:00:58,960
これについては、後でまた出てきます。

19
00:00:59,120 --> 00:01:02,480
では、練習問題自体を見てみましょう。

20
00:01:03,080 --> 00:01:04,720
さて、これは何なのでしょう？

21
00:01:04,880 --> 00:01:08,240
あなたが今後人生において
真偽値を実装することは決してないでしょう。

22
00:01:08,400 --> 00:01:10,080
少なくとも、私はそう願います。

23
00:01:10,240 --> 00:01:13,000
では全く使い道がないことでしょうか？

24
00:01:13,160 --> 00:01:15,920
背後にある教えは、何でしょうか？

25
00:01:16,080 --> 00:01:19,240
私はこの問題を問うことは
とても重要なことだと考えています。

26
00:01:19,400 --> 00:01:23,600
実装はあんな感じだとして
だからどうだというのでしょう？

27
00:01:24,560 --> 00:01:29,360
メッセージ送信をする時にはいつも

28
00:01:29,520 --> 00:01:33,640
case 文を実行しているということです。

29
00:01:35,000 --> 00:01:38,800
C プログラミング等によくあることです。

30
00:01:39,880 --> 00:01:42,840
メッセージを送ることは
複数の選択肢から選ぶということです。

31
00:01:44,160 --> 00:01:46,880
興味深いことは
メッセージを送ると

32
00:01:47,040 --> 00:01:50,720
単なる case 文ではないということです。
動的な case 文になっています。

33
00:01:50,880 --> 00:01:54,960
実際、メッセージ送信はロードされている
クラスや生成されたインスタンスに依存します。

34
00:01:55,720 --> 00:01:58,640
Java でプログラムを書く時にはよく

35
00:01:58,800 --> 00:02:02,040
x.f() を書くことで

36
00:02:02,200 --> 00:02:04,080
メソッド f を実行します。

37
00:02:04,240 --> 00:02:07,240
ここで説明していることは、つまり
このピリオド（.）は

38
00:02:08,000 --> 00:02:09,560
選択をおこなう演算子だということです。

39
00:02:10,840 --> 00:02:12,600
とても大事なことは

40
00:02:13,400 --> 00:02:15,360
この選択は動的だということです。

41
00:02:15,520 --> 00:02:17,800
これまであまり言ってきませんでしたが

42
00:02:17,960 --> 00:02:22,960
これこそが、例をもって示したかったことなのです。

43
00:02:23,120 --> 00:02:25,840
まとめると
メッセージを送ることは

44
00:02:26,000 --> 00:02:29,360
動的な case 文のような機能を果たします。

45
00:02:29,520 --> 00:02:33,120
動的というのは
ロードされているクラスに依存するという意味です。

46
00:02:33,280 --> 00:02:36,440
この真偽値の例題では
2つのインスタンスと2つのクラスを扱いました。

47
00:02:36,600 --> 00:02:39,600
たとえ50個だったとしても
同じように動きます。

48
00:02:40,320 --> 00:02:43,920
バーチャルマシンにメッセージを送ることで

49
00:02:44,080 --> 00:02:47,400
（Pharo は Java や C# のように
　バーチャルマシンを使います）


50
00:02:47,560 --> 00:02:50,520
バーチャルマシンの実行装置が

51
00:02:50,680 --> 00:02:54,400
レシーバーのクラスに応じて
正しいメソッドを選択します。

52
00:02:54,560 --> 00:02:58,160
したがって、メッセージ送信は
選択演算子なのです。

53
00:02:58,320 --> 00:03:00,520
条件分岐を使うたびに

54
00:03:00,680 --> 00:03:04,360
それを

55
00:03:04,520 --> 00:03:07,920
バーチャルマシンによる選択に
置き換えることができます。

56
00:03:08,800 --> 00:03:11,400
つまり、not についての解答は

57
00:03:11,560 --> 00:03:13,560
プログラムを実装する時には

58
00:03:13,720 --> 00:03:17,240
バーチャルマシンによる選択を
使うべきだということです。

59
00:03:17,400 --> 00:03:19,720
if 文を使う必要はありません。

60
00:03:19,880 --> 00:03:24,240
なぜなら、メッセージを送ることが
if や条件分岐と同じ意味になるのです。

61
00:03:24,400 --> 00:03:26,920
ここで疑問に思うかもしれません。

62
00:03:27,080 --> 00:03:31,160
最初の練習問題を全く別の方法で実装していたら
どうなのだろうか？と。

63
00:03:31,320 --> 00:03:35,160
もし練習問題が「Boolean クラスに

64
00:03:35,320 --> 00:03:37,000
not や or を実装しなさい」だったら
どうでしょう？

65
00:03:37,160 --> 00:03:39,400
今回の解答のやり方では
うまくいかないでしょう。

66
00:03:40,200 --> 00:03:42,720
おかしいですね。
どういうことでしょうか？

67
00:03:42,880 --> 00:03:45,680
クラスが1つあるか複数あるかは
アプリケーションの設計に

68
00:03:45,840 --> 00:03:48,400
とても大きな影響を与えます。

69
00:03:49,120 --> 00:03:50,120
まったくもって

70
00:03:51,440 --> 00:03:56,560
クラスは分岐や選択の役割を
担っているのです。

71
00:03:56,720 --> 00:03:59,080
ヨーグルトを選ぼうとしているとして

72
00:03:59,240 --> 00:04:03,200
店にヨーグルトのポットが1つしかなければ
そのヨーグルトを選ぶしかないのです。

73
00:04:03,360 --> 00:04:04,400
そういうことなのです。

74
00:04:04,560 --> 00:04:06,520
つまり、クラスは

75
00:04:07,520 --> 00:04:09,440
継承木の中での1つの case を表しています。

76
00:04:09,600 --> 00:04:10,880
それが意味することは

77
00:04:11,040 --> 00:04:14,040
1つの大きく太ったクラスに
メソッドが沢山あるような

78
00:04:14,200 --> 00:04:17,160
そんなデザインがあれば

79
00:04:17,320 --> 00:04:20,920
それと同じことを階層を使って表現できる
ということです。

80
00:04:21,080 --> 00:04:25,280
そのほうが良い設計です。
よりモジュール化されています。

81
00:04:25,440 --> 00:04:29,680
必要ならば別の選択肢を加えることも
簡単にできます。

82
00:04:29,840 --> 00:04:32,760
「これは悪くないが

83
00:04:32,920 --> 00:04:35,960
新しい選択肢を持てるように改良できるね」
と言って拡張するのです。

84
00:04:36,120 --> 00:04:38,880
さらに複雑度を減らすことができます。

85
00:04:39,040 --> 00:04:43,840
1つのクラスに集中することができます。
あまりにも多くの条件を抱えたものではなく。

86
00:04:44,800 --> 00:04:49,000
片方の手には選択演算子があり

87
00:04:49,160 --> 00:04:52,640
もう一方の手には選択肢を表したものを持っています。

88
00:04:52,800 --> 00:04:57,640
それらをくっつけると
良い品質の OOP になります。

89
00:04:57,800 --> 00:05:00,040
さらに良いことに

90
00:05:00,200 --> 00:05:03,520
階層による解決を使うと

91
00:05:03,680 --> 00:05:07,120
それをパッケージ化することができます。

92
00:05:07,280 --> 00:05:11,480
つまり、ある部分はコアとしてパッケージして
別の部分をプラグインとしてパッケージできます。

93
00:05:11,640 --> 00:05:14,640
そして顧客に言うのです。
「この機能が必要であれば

94
00:05:14,800 --> 00:05:17,720
この有償プラグインをダウンロードしてください」

95
00:05:17,880 --> 00:05:20,360
そしてそのコードを動的にロードします。

96
00:05:20,520 --> 00:05:23,760
このクラスのインスタンスを生成すると

97
00:05:25,400 --> 00:05:27,840
オペレーションメッセージを送れば

98
00:05:28,520 --> 00:05:31,840
プラグインのコードがシステムの中で
実行されます。

99
00:05:32,000 --> 00:05:36,440
それが OOP のエッセンスです。

100
00:05:36,600 --> 00:05:40,120
メッセージを送ると
正しいメソッドが選択される

101
00:05:40,960 --> 00:05:45,040
そしてシステムが正しいメソッドを
選択することを知っていることで

102
00:05:45,200 --> 00:05:47,960
よりエレガントな実装をすることができます。

103
00:05:48,120 --> 00:05:50,320
何を学んだのでしょうか？

104
00:05:50,480 --> 00:05:55,040
学んだことは、メッセージを送ることで
レシーバーに選択させて何かを決めさせることです。

105
00:05:55,200 --> 00:05:58,400
クライアントは何も決める必要ありません。

106
00:05:58,560 --> 00:06:00,760
クライアントコードは宣言的です。

107
00:06:00,920 --> 00:06:04,800
条件分岐はありません。命令を与えるのです。
「これをやれ」「あれをやれ」「開け」「閉じろ」と。

108
00:06:04,960 --> 00:06:09,280
「このクラスに属していますか？」や
「閉じられていますか？」ではなく。

109
00:06:09,440 --> 00:06:12,520
違いはレシーバーが動的に置き換えられる
可能性があることです。

110
00:06:12,680 --> 00:06:15,840
このことは後でまた出てきます。
ただし直接ではありません。暗黙に。

111
00:06:16,560 --> 00:06:20,240
そういうことで、多くの場合
if 文を書くことを避けるようにしてください。

112
00:06:21,240 --> 00:06:23,560
できるだけオブジェクトとメッセージを使うように。

113
00:06:23,720 --> 00:06:27,760
いつもそうだというわけではないですが
少なくともできるだけ使うようにしてください。

114
00:06:29,280 --> 00:06:31,880
実行エンジン
バーチャルマシンは

115
00:06:32,040 --> 00:06:37,120
メッセージを送るたびに
条件スイッチとして動作します。

116
00:06:37,680 --> 00:06:39,000
それを使うことです。

117
00:06:39,160 --> 00:06:41,960
キーボードを打つ時はいつも
アンチ if キャンペーンを楽しんでください。

118
00:06:42,120 --> 00:06:46,800
if 文を書くのをやめさせるために
プログラマー達がこのキャンペーンを立ち上げました。

119
00:06:48,760 --> 00:06:50,960
さて、このセッションでは何を学んだでしょうか？

120
00:06:51,120 --> 00:06:53,280
2つのことがありました。
Java や Pharo で

121
00:06:53,440 --> 00:06:57,720
x.f() と書いたら

122
00:06:58,600 --> 00:07:02,400
選択肢を作ることになります。

123
00:07:02,560 --> 00:07:06,080
レシーバーに応じて実行されるべき
メソッド f が選択されます。

124
00:07:06,840 --> 00:07:08,640
つまり選択演算子ということです。

125
00:07:08,800 --> 00:07:12,000
そして階層が可能な選択肢を表現します。

126
00:07:12,160 --> 00:07:16,560
つまりどんな選択が可能かを決める
枠組みだということです。

127
00:07:16,720 --> 00:07:20,800
結果として条件分岐のない
拡張性のあるプログラムを書くことができます。

128
00:07:21,800 --> 00:07:24,480
これで Pharo でのオブジェクト設計についての

129
00:07:24,640 --> 00:07:27,160
最初のセッションを終わります。

130
00:07:28,160 --> 00:07:30,520
次のセッションでもオブジェクト設計について
さらに見ていきます。
