887
00:38:03,240 --> 00:38:04,330
在外面
888
00:38:05,130 --> 00:38:06,120
有
889
00:38:06,400 --> 00:38:08,475
请求进来的时候
890
00:38:08,475 --> 00:38:10,550
有消息进来的时候
891
00:38:11,630 --> 00:38:14,000
那么经过我们状态机
892
00:38:15,010 --> 00:38:16,480
把这个逻辑
893
00:38:17,540 --> 00:38:18,482
运转一下
894
00:38:18,482 --> 00:38:19,425
判断一下
895
00:38:19,425 --> 00:38:20,840
最终才能够决定
896
00:38:21,120 --> 00:38:22,410
执行什么动作
897
00:38:24,530 --> 00:38:27,080
那么这个逻辑就回收到哪里
898
00:38:27,550 --> 00:38:29,320
回收到这里来
899
00:38:31,090 --> 00:38:32,293
就不在外面了
900
00:38:32,293 --> 00:38:34,700
判断的这个逻辑
901
00:38:35,210 --> 00:38:37,430
从外面就收到里面来了
902
00:38:37,710 --> 00:38:40,060
它就不需要外面的这个调用者
903
00:38:41,810 --> 00:38:44,800
外面的客户,Client
904
00:38:45,690 --> 00:38:47,520
他不需要善解人意
905
00:38:47,920 --> 00:38:49,310
逻辑在这里
906
00:38:49,770 --> 00:38:50,640
也就是说
907
00:38:51,380 --> 00:38:55,650
强制封装来保护信息的完整性
908
00:38:56,280 --> 00:39:01,280
平时我们说面向对象面向对象,说封装了这个逻辑
909
00:39:01,280 --> 00:39:02,190
保护数据
910
00:39:02,640 --> 00:39:05,610
但我们很多时候只是这样一说
911
00:39:06,240 --> 00:39:08,600
但是我们怎么做到这一点呢
912
00:39:10,420 --> 00:39:13,897
我们看很多面向对象的书里面
913
00:39:13,897 --> 00:39:14,629
说好啊
914
00:39:14,629 --> 00:39:15,361
好在哪里
915
00:39:15,361 --> 00:39:16,459
你看,面向对象
916
00:39:16,459 --> 00:39:16,825
好在哪里
917
00:39:16,825 --> 00:39:17,740
你看,人
918
00:39:18,020 --> 00:39:20,140
人有一个身高
919
00:39:20,830 --> 00:39:21,045
920
00:39:21,045 --> 00:39:22,980
然后我怎么保护它
921
00:39:22,980 --> 00:39:24,270
我get身高
922
00:39:24,550 --> 00:39:25,206
set升高
923
00:39:25,206 --> 00:39:27,395
我不能够直接访问身高
924
00:39:27,395 --> 00:39:29,583
而是要通过一个get身高
925
00:39:29,583 --> 00:39:30,240
set身高
926
00:39:31,660 --> 00:39:33,439
来访问
927
00:39:33,439 --> 00:39:34,710
或者来修改它
928
00:39:35,010 --> 00:39:37,184
然后在这里面保护它
929
00:39:37,184 --> 00:39:39,161
这当然也算是一种保护
930
00:39:39,161 --> 00:39:40,150
但是怎么样
931
00:39:40,430 --> 00:39:41,110
这是
932
00:39:42,030 --> 00:39:42,796
一一对应的
933
00:39:42,796 --> 00:39:43,945
换汤不换药
934
00:39:43,945 --> 00:39:44,520
对不对
935
00:39:46,700 --> 00:39:48,870
那状态对它的保护的话
936
00:39:49,570 --> 00:39:54,350
是对更复杂的情况的一些保护
937
00:39:55,450 --> 00:39:57,390
那么逻辑内收之后
938
00:39:58,510 --> 00:40:01,250
我们就会得到更合理的一个
939
00:40:01,530 --> 00:40:03,040
服务契约
940
00:40:07,330 --> 00:40:09,685
实际上就相当于类的操作
941
00:40:09,685 --> 00:40:11,570
那我们为什么不说
942
00:40:12,030 --> 00:40:14,610
类的操作,而是说服务契约
943
00:40:15,000 --> 00:40:17,530
因为状态机描述的
944
00:40:18,010 --> 00:40:20,118
不仅可以是描述类的状态
945
00:40:20,118 --> 00:40:21,700
可以描述整个系统的
946
00:40:21,980 --> 00:40:24,340
也可以描述某个组件的
947
00:40:25,120 --> 00:40:26,940
所以,我们用一个
948
00:40:27,580 --> 00:40:29,930
契约这个概念
949
00:40:31,700 --> 00:40:36,530
实际上,之前Peter Coad的方法学,把类的操作叫做类的服务
950
00:40:38,620 --> 00:40:40,673
这个名字更合理
951
00:40:40,673 --> 00:40:42,270
操作这个词
952
00:40:43,090 --> 00:40:44,606
不是很好
953
00:40:44,606 --> 00:40:46,555
什么方法也不是很好
954
00:40:46,555 --> 00:40:46,771
955
00:40:46,771 --> 00:40:47,854
服务更好
956
00:40:47,854 --> 00:40:50,236
一个类对外提供的服务嘛
957
00:40:50,236 --> 00:40:50,670
对吧
958
00:40:52,220 --> 00:40:53,260
service
959
00:40:53,860 --> 00:40:55,690
现在操作是operation
960
00:40:57,480 --> 00:40:57,840
961
00:40:57,840 --> 00:40:58,560
这个
962
00:40:58,840 --> 00:40:59,558
不是很好
963
00:40:59,558 --> 00:41:02,432
但是UML既然采用了这个词
964
00:41:02,432 --> 00:41:03,690
那我们就按照这个来
965
00:41:05,590 --> 00:41:07,110
就像右边这个一样
966
00:41:07,110 --> 00:41:07,680
比如说
967
00:41:09,100 --> 00:41:11,240
静音、有音两个状态
968
00:41:11,710 --> 00:41:14,240
那么它对外暴露的接口
969
00:41:14,520 --> 00:41:17,055
服务的这个契约是什么
970
00:41:17,055 --> 00:41:19,590
放两个,开声音,关声音
971
00:41:20,010 --> 00:41:22,150
两个命令,实际上不用
972
00:41:23,000 --> 00:41:25,040
我们发一个静音就行了
973
00:41:26,340 --> 00:41:28,160
只需要一个静音的按钮
974
00:41:28,620 --> 00:41:29,667
静音的命令
975
00:41:29,667 --> 00:41:30,924
如果是静音的
976
00:41:30,924 --> 00:41:32,391
就到有音,有音到静音
977
00:41:32,391 --> 00:41:32,810
978
00:41:33,230 --> 00:41:36,190
这个判断逻辑在里面了
979
00:41:36,570 --> 00:41:37,570
在这里面
980
00:41:40,630 --> 00:41:41,880
把它收进来
981
00:41:43,620 --> 00:41:46,610
得到更合理的一个接口
982
00:41:50,010 --> 00:41:52,970
所以呢,像之前我们讲什么
983
00:41:53,280 --> 00:41:56,230
UML这个分析序列图
984
00:41:56,510 --> 00:41:58,283
然后讲责任分配
985
00:41:58,283 --> 00:41:58,790
对吧
986
00:41:59,180 --> 00:42:02,100
责任分配怎么给一个类分配更合理
987
00:42:02,500 --> 00:42:04,815
有专家原则
988
00:42:04,815 --> 00:42:07,420
说要考虑到这个操作
989
00:42:07,830 --> 00:42:09,910
用到哪些属性
990
00:42:10,190 --> 00:42:13,220
这些属性呢哪个类里面有的是最多的
991
00:42:13,960 --> 00:42:15,310
那就优先
992
00:42:16,010 --> 00:42:17,220
分给它
993
00:42:18,250 --> 00:42:18,800
994
00:42:19,760 --> 00:42:20,345
然后呢
995
00:42:20,345 --> 00:42:21,712
如果它能解决的
996
00:42:21,712 --> 00:42:22,492
它就解决
997
00:42:22,492 --> 00:42:23,273
解决不了的
998
00:42:23,273 --> 00:42:24,640
再找别人帮忙
999
00:42:25,940 --> 00:42:26,194
1000
00:42:26,194 --> 00:42:27,210
专家原则
1001
00:42:27,990 --> 00:42:30,350
或者说什么老板原则、可视原则
1002
00:42:30,990 --> 00:42:32,576
那这些都是什么
1003
00:42:32,576 --> 00:42:33,030
就是
1004
00:42:34,100 --> 00:42:36,540
根据类图判断的一些
1005
00:42:37,070 --> 00:42:38,330
经验的
1006
00:42:40,130 --> 00:42:41,008
原则
1007
00:42:41,008 --> 00:42:42,180
经验法则
1008
00:42:46,460 --> 00:42:48,903
那有没有更好的一些判断呢
1009
00:42:48,903 --> 00:42:50,329
那状态机的话
1010
00:42:50,329 --> 00:42:53,180
可以给我们更好的一个判断
1011
00:42:54,440 --> 00:42:57,120
如果说,我们的状态机画出来
1012
00:43:00,020 --> 00:43:01,410
是很漂亮的
1013
00:43:03,370 --> 00:43:04,260
那么
1014
00:43:07,610 --> 00:43:10,630
状态机上规定的这些服务契约
1015
00:43:11,550 --> 00:43:13,070
就是合理的
1016
00:43:14,100 --> 00:43:17,950
这个类应该承担的责任或者说类的操作
1017
00:43:22,810 --> 00:43:23,770
因为
1018
00:43:24,720 --> 00:43:27,000
类图、序列图
1019
00:43:27,280 --> 00:43:28,592
和状态机图
1020
00:43:28,592 --> 00:43:30,780
它有这样的映射关系
1021
00:43:32,090 --> 00:43:34,140
类图上的操作
1022
00:43:34,570 --> 00:43:39,630
和序列图上,指向序列图上的类
1023
00:43:39,630 --> 00:43:41,930
那个类在这里嘛
1024
00:43:42,430 --> 00:43:45,118
指向这个类的对象
1025
00:43:45,118 --> 00:43:45,790
冒号
1026
00:43:46,070 --> 00:43:47,829
说明这是一个对象
1027
00:43:47,829 --> 00:43:49,588
对象名在这里
1028
00:43:49,588 --> 00:43:50,956
但是我们留空了
1029
00:43:50,956 --> 00:43:51,347
对吧
1030
00:43:51,347 --> 00:43:52,520
对象名在这里
1031
00:43:55,330 --> 00:44:01,510
类的操作和在序列图上指向这个类的消息的名字是
1032
00:44:01,840 --> 00:44:03,260
有对应关系的
1033
00:44:03,540 --> 00:44:05,920
那这个跟我们的
1034
00:44:06,250 --> 00:44:07,530
这个类的
1035
00:44:09,650 --> 00:44:11,580
状态机图上的
1036
00:44:11,860 --> 00:44:13,800
上面的这个事件
1037
00:44:15,650 --> 00:44:17,340
也是有对应关系的
1038
00:44:20,260 --> 00:44:23,918
那如果说,我们这里画了一个状态机图
1039
00:44:23,918 --> 00:44:25,290
针对这个Class1
1040
00:44:25,790 --> 00:44:26,942
画了一个状态机图
1041
00:44:26,942 --> 00:44:28,670
我们觉得非常好
1042
00:44:30,400 --> 00:44:32,200
那么意味着什么
1043
00:44:32,200 --> 00:44:33,230
我们认为
1044
00:44:33,700 --> 00:44:35,210
这个Class1
1045
00:44:35,490 --> 00:44:37,800
收到一个这样的消息
1046
00:44:38,490 --> 00:44:41,000
或者承担一个这样的责任
1047
00:44:41,330 --> 00:44:43,830
Operation1这样的责任是合理的
1048
00:44:45,080 --> 00:44:46,050
从这个
1049
00:44:46,500 --> 00:44:48,750
来佐证这个
1050
00:44:49,920 --> 00:44:50,670
这个
1051
00:44:53,040 --> 00:44:55,283
当然你可以反过来说
1052
00:44:55,283 --> 00:44:56,280
如果这边
1053
00:44:56,790 --> 00:44:58,865
画了,觉得挺好
1054
00:44:58,865 --> 00:45:00,940
这边呢,就不对
1055
00:45:02,530 --> 00:45:02,734
1056
00:45:02,734 --> 00:45:04,164
跟这边匹配不上
1057
00:45:04,164 --> 00:45:05,390
那应该改哪里
1058
00:45:05,840 --> 00:45:06,072
1059
00:45:06,072 --> 00:45:07,470
应该改这里
1060
00:45:08,270 --> 00:45:10,550
这个地方
1061
00:45:11,880 --> 00:45:13,290
因为这边是
1062
00:45:13,950 --> 00:45:16,060
有更充分的证据
1063
00:45:16,590 --> 00:45:18,030
认为这样
1064
00:45:20,220 --> 00:45:22,280
对我们这个类来说的话
1065
00:45:22,560 --> 00:45:23,750
更加合理
1066
00:45:24,570 --> 00:45:28,570
因为状态机里面的逻辑更加细致嘛
1067
00:45:30,160 --> 00:45:31,270
可以看出
1068
00:45:31,990 --> 00:45:34,100
更合理的安排是什么样子