基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
设计模式是什么鬼(中介)
设计模式是什么鬼(中介)
阅读
1
2018-10-21
中介,作用于多个事物之间充当交互沟通的媒介。我们的生活中有各种各样的媒介,比如一些传统媒体,书刊杂志,报纸,把信息传递给读者。再比如利用电子信息技术的互联网,作为一种新媒体,不单可以更高效地把信息传递给用户,而且可以反向地获得用户反馈评论,用户与用户之间亦可以进行沟通,这种全终端双向互通是传统媒体所不能及的。
除此之外,再如婚介所、房产中介、交换机组网、现代电子商务、
C2C
购物平台、手机、即时通软件等等,这些都与我们的生活息息相关,离开它们我们将举步维艰。其实不管是任何中介,其本质都是相同的,都是充当中间媒介的角色,并达成多方业务互通的目的。
首先我们以最简单的模型来解决问题,以两个人交谈为例,其实他们之间并不需要任何第三方媒介,而是一对一直接沟通,看代码。
%
201public
%
20class
%
20People
%
20
%
7B
%
0A
%
202
%
20
%
20private
%
20String
%
20name
;//%
E7
%
94
%
A8
%
E5
%
90
%
8D
%
E5
%
AD
%
97
%
E6
%
9D
%
A5
%
E5
%
8C
%
BA
%
E5
%
88
%
AB
%
E4
%
BA
%
BA
%
E3
%
80
%
82
%
0A
%
203
%
20
%
20private
%
20People
%
20other
;//%
E6
%
8C
%
81
%
E6
%
9C
%
89
%
E5
%
AF
%
B9
%
E6
%
96
%
B9
%
E7
%
9A
%
84
%
E5
%
BC
%
95
%
E7
%
94
%
A8
%
E3
%
80
%
82
%
0A
%
204
%
0A
%
205
%
20
%
20public
%
20String
%
20getName
()%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20return
%
20this
.
name
;%
0A
%
207
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20public
%
20People
(
String
%
20name
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;//%
E5
%
88
%
9D
%
E5
%
A7
%
8B
%
E5
%
8C
%
96
%
E5
%
BF
%
85
%
E9
%
A1
%
BB
%
E8
%
B5
%
B7
%
E5
%
90
%
8D
%
E3
%
80
%
82
%
0A11
%
20
%
20
%
7D
%
0A12
%
0A13
%
20
%
20public
%
20void
%
20connect
(
People
%
20other
)%
20
%
7B
%
0A14
%
20
%
20
%
20
%
20this
.
other
%
20
=%
20other
;//%
E8
%
BF
%
9E
%
E6
%
8E
%
A5
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
E4
%
B8
%
AD
%
E6
%
B3
%
A8
%
E5
%
85
%
A5
%
E5
%
AF
%
B9
%
E6
%
96
%
B9
%
E5
%
BC
%
95
%
E7
%
94
%
A8
%
E3
%
80
%
82
%
0A15
%
20
%
20
%
7D
%
0A16
%
0A17
%
20
%
20public
%
20void
%
20talk
(
String
%
20msg
)%
20
%
7B
%
0A18
%
20
%
20
%
20
%
20other
.
listen
(
msg
);//%
E6
%
88
%
91
%
E6
%
96
%
B9
%
E8
%
AF
%
B4
%
E8
%
AF
%
9D
%
E6
%
97
%
B6
%
EF
%
BC
%
8C
%
E5
%
AF
%
B9
%
E6
%
96
%
B9
%
E8
%
81
%
86
%
E5
%
90
%
AC
%
E3
%
80
%
82
%
0A19
%
20
%
20
%
7D
%
0A20
%
0A21
%
20
%
20public
%
20void
%
20listen
(
String
%
20msg
)%
20
%
7B
%
0A22
%
20
%
20
%
20
%
20
//%
E8
%
81
%
86
%
E5
%
90
%
AC
%
E6
%
9D
%
A5
%
E8
%
87
%
AA
%
E5
%
AF
%
B9
%
E6
%
96
%
B9
%
E7
%
9A
%
84
%
E5
%
A3
%
B0
%
E9
%
9F
%
B3
%
0A23
%
20
%
20
%
20
%
20System
.
out
.
println
(%
0A24
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20other
.
getName
()%
20
%
20
%
22
%
20
%
E5
%
AF
%
B9
%
20
%
22
%
20
%
20this
.
name
%
20
%
20
%
22
%
20
%
E8
%
AF
%
B4
%
EF
%
BC
%
9A
%
22
%
20
%
20msg
%
0A25
%
20
%
20
%
20
%
20
);%
0A26
%
20
%
20
%
7D
%
0A27
%
7D
%
0A
一切就绪,两人开始沟通。
%
201public
%
20class
%
20Main
%
20
%
7B
%
0A
%
202
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
20args
%
5B
%
5D
)%
20
%
7B
%
0A
%
203
%
20
%
20
%
20
%
20People
%
20p3
%
20
=%
20new
%
20People
(%
22
%
E5
%
BC
%
A0
%
E4
%
B8
%
89
%
22
);%
0A
%
204
%
20
%
20
%
20
%
20People
%
20p4
%
20
=%
20new
%
20People
(%
22
%
E6
%
9D
%
8E
%
E5
%
9B
%
9B
%
22
);%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20p3
.
connect
(
p4
);%
0A
%
207
%
20
%
20
%
20
%
20p4
.
connect
(
p3
);%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20p3
.
talk
(%
22
%
E4
%
BD
%
A0
%
E5
%
A5
%
BD
%
E3
%
80
%
82
%
22
);%
0A10
%
20
%
20
%
20
%
20p4
.
talk
(%
22
%
E6
%
97
%
A9
%
E4
%
B8
%
8A
%
E5
%
A5
%
BD
%
EF
%
BC
%
8C
%
E4
%
B8
%
89
%
E5
%
93
%
A5
%
E3
%
80
%
82
%
22
);%
0A11
%
20
%
20
%
7D
%
0A12
%
20
%
20
/****************************%
0A13
%
20
%
20
%
E8
%
BE
%
93
%
E5
%
87
%
BA
%
E7
%
BB
%
93
%
E6
%
9E
%
9C
%
EF
%
BC
%
9A
%
0A14
%
20
%
20
%
20
%
20
%
E5
%
BC
%
A0
%
E4
%
B8
%
89
%
20
%
E5
%
AF
%
B9
%
20
%
E6
%
9D
%
8E
%
E5
%
9B
%
9B
%
20
%
E8
%
AF
%
B4
%
EF
%
BC
%
9A
%
E4
%
BD
%
A0
%
E5
%
A5
%
BD
%
E3
%
80
%
82
%
0A15
%
20
%
20
%
20
%
20
%
E6
%
9D
%
8E
%
E5
%
9B
%
9B
%
20
%
E5
%
AF
%
B9
%
20
%
E5
%
BC
%
A0
%
E4
%
B8
%
89
%
20
%
E8
%
AF
%
B4
%
EF
%
BC
%
9A
%
E6
%
97
%
A9
%
E4
%
B8
%
8A
%
E5
%
A5
%
BD
%
EF
%
BC
%
8C
%
E4
%
B8
%
89
%
E5
%
93
%
A5
%
E3
%
80
%
82
%
0A16
%
20
%
20
*****************************/%
0A17
%
7D
%
0A
从
People
类中我们可以看到,沟通只只能在两人之间进行,而且各自都持有对方对象的引用,以便把消息传递给对方的监听方法。这种模式虽然简单,但耦合性太强,你中有我,我中有你,谁也离不开谁。试想如果再有多个人加入交谈,那每个人都要持有其他所有人的引用了,这时会陷入一种多对多的关联陷阱,对象关系变得复杂不堪,如蛛网般难以维护。
我们就拿群聊天室举例,每当有人加入或离开,都要把每个人持有的其他人的引用关系更新一遍,发消息时更是繁琐不堪,重复工作显得非常多余。那么如何解决这个问题呢?我们开始进行思考,为何不把重复的部分抽离出来呢,也就是把对方的引用放在一个中介类里面去统一维护起来,于是设计更改如下。
可以看到,每个用户不再所持有其他所有用户的引用了,取而代之的是聊天室的引用,这样引用关系瞬间变得明朗起来,开始我们的代码重构。
%
201public
%
20class
%
20User
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20private
%
20String
%
20name
;//%
E5
%
90
%
8D
%
E5
%
AD
%
97
%
0A
%
203
%
0A
%
204
%
20
%
20
%
20
%
20private
%
20ChatRoom
%
20chatRoom
;//%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E5
%
BC
%
95
%
E7
%
94
%
A8
%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20public
%
20User
(
String
%
20name
)%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;//%
E5
%
88
%
9D
%
E5
%
A7
%
8B
%
E5
%
8C
%
96
%
E5
%
BF
%
85
%
E9
%
A1
%
BB
%
E8
%
B5
%
B7
%
E5
%
90
%
8D
%
E5
%
AD
%
97
%
0A
%
208
%
20
%
20
%
20
%
20
%
7D
%
0A
%
209
%
0A10
%
20
%
20
%
20
%
20public
%
20String
%
20getName
()%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20this
.
name
;%
0A12
%
20
%
20
%
20
%
20
%
7D
%
0A13
%
0A14
%
20
%
20
%
20
%
20public
%
20void
%
20login
(
ChatRoom
%
20chatRoom
)%
20
%
7B
//%
E7
%
94
%
A8
%
E6
%
88
%
B7
%
E7
%
99
%
BB
%
E9
%
99
%
86
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20chatRoom
.
connect
(
this
);//%
E8
%
B0
%
83
%
E7
%
94
%
A8
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E8
%
BF
%
9E
%
E6
%
8E
%
A5
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
chatRoom
%
20
=%
20chatRoom
;//%
E6
%
B3
%
A8
%
E5
%
85
%
A5
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E5
%
BC
%
95
%
E7
%
94
%
A8
%
0A17
%
20
%
20
%
20
%
20
%
7D
%
0A18
%
0A19
%
20
%
20
%
20
%
20public
%
20void
%
20talk
(
String
%
20msg
)%
20
%
7B
//%
E7
%
94
%
A8
%
E6
%
88
%
B7
%
E5
%
8F
%
91
%
E8
%
A8
%
80
%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20chatRoom
.
sendMsg
(
this
,%
20msg
);//%
E7
%
BB
%
99
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E5
%
8F
%
91
%
E6
%
B6
%
88
%
E6
%
81
%
AF
%
0A21
%
20
%
20
%
20
%
20
%
7D
%
0A22
%
0A23
%
20
%
20
%
20
%
20public
%
20void
%
20listen
(
User
%
20fromWhom
,%
20String
%
20msg
)%
20
%
7B
//%
E4
%
B8
%
94
%
E5
%
90
%
AC
%
E9
%
A3
%
8E
%
E5
%
90
%
9F
%
0A24
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
print
(%
22
%
E3
%
80
%
90
%
22
this
.
name
%
22
%
E7
%
9A
%
84
%
E5
%
AF
%
B9
%
E8
%
AF
%
9D
%
E6
%
A1
%
86
%
E3
%
80
%
91
%
22
);%
0A25
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(
fromWhom
.
getName
()%
20
%
20
%
22
%
20
%
E8
%
AF
%
B4
%
EF
%
BC
%
9A
%
20
%
22
%
20
%
20msg
);%
0A26
%
20
%
20
%
20
%
20
%
7D
%
0A27
%
7D
%
0A
可以看到第
14
行,用户登陆聊天室时不再是连接对方了,而是连接通知聊天室并告知:“有人进来了请进行注册”,然后记录下来用户当前所在聊天室的引用。第
19
行,用户发言时也不是直接找对方了,而是把消息扔给聊天室处理。第
23
行,聆听方法同样也是,将来会接受来自聊天室的声音。很显然,一切沟通都与是中介聊天室进行,这样用户之间就实现了解耦的目的。当然,用户当然还需要注销离开聊天室,请读者可自行练习添加,下面接着写我们的聊天室中介类。
%
201public
%
20class
%
20ChatRoom
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20private
%
20String
%
20name
;//%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E5
%
91
%
BD
%
E5
%
90
%
8D
%
0A
%
203
%
0A
%
204
%
20
%
20
%
20
%
20public
%
20ChatRoom
(
String
%
20name
)%
20
%
7B
%
0A
%
205
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;//%
E5
%
88
%
9D
%
E5
%
A7
%
8B
%
E5
%
8C
%
96
%
E5
%
BF
%
85
%
E9
%
A1
%
BB
%
E5
%
91
%
BD
%
E5
%
90
%
8D
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
0A
%
206
%
20
%
20
%
20
%
20
%
7D
%
0A
%
207
%
0A
%
208
%
20
%
20
%
20
%
20List
&
lt
;
User
&
gt
;%
20users
%
20
=%
20new
%
20ArrayList
&
lt
;&
gt
;();//%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E9
%
87
%
8C
%
E7
%
9A
%
84
%
E7
%
94
%
A8
%
E6
%
88
%
B7
%
E4
%
BB
%
AC
%
0A
%
209
%
0A10
%
20
%
20
%
20
%
20public
%
20void
%
20connect
(
User
%
20user
)%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
users
.
add
(
user
);//%
E7
%
94
%
A8
%
E6
%
88
%
B7
%
E8
%
BF
%
9B
%
E5
%
85
%
A5
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E5
%
8A
%
A0
%
E5
%
85
%
A5
%
E5
%
88
%
97
%
E8
%
A1
%
A8
%
E3
%
80
%
82
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
print
(%
22
%
E6
%
AC
%
A2
%
E8
%
BF
%
8E
%
E3
%
80
%
90
%
22
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
print
(
user
.
getName
());%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E3
%
80
%
91
%
E5
%
8A
%
A0
%
E5
%
85
%
A5
%
E8
%
81
%
8A
%
E5
%
A4
%
A9
%
E5
%
AE
%
A4
%
E3
%
80
%
90
%
22
%
20
%
20this
.
name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A15
%
20
%
20
%
20
%
20
%
7D
%
0A16
%
0A17
%
20
%
20
%
20
%
20public
%
20void
%
20sendMsg
(
User
%
20fromWhom
,%
20String
%
20msg
)%
20
%
7B
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E6
%
89
%
80
%
E6
%
9C
%
89
%
E7
%
94
%
A8
%
E6
%
88
%
B7
%
EF
%
BC
%
8C
%
E5
%
8F
%
AA
%
E5
%
8F
%
91
%
E6
%
B6
%
88
%
E6
%
81
%
AF
%
E7
%
BB
%
99
%
E9
%
9D
%
9E
%
E5
%
8F
%
91
%
E9
%
80
%
81
%
E6
%
96
%
B9fromWhom
%
E3
%
80
%
82
%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20users
.
stream
()%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
.
filter
(
user
%
20
-&
gt
;%
20
!
user
.
equals
(
fromWhom
))//%
E8
%
BF
%
87
%
E6
%
BB
%
A4
%
E6
%
8E
%
89
%
E5
%
8F
%
91
%
E9
%
80
%
81
%
E6
%
96
%
B9fromWhom
%
0A21
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
.
forEach
(
toWhom
%
20
-&
gt
;%
20toWhom
.
listen
(
fromWhom
,%
20msg
));//%
E5
%
8F
%
91
%
E9
%
80
%
81
%
E6
%
B6
%
88
%
E6
%
81
%
AF
%
E7
%
BB
%
99
%
E5
%
89
%
A9
%
E4
%
B8
%
8B
%
E7
%
9A
%
84
%
E6
%
89
%
80
%
E6
%
9C
%
89
%
E4
%
BA
%
BA
%
0A22
%
20
%
20
%
20
%
20
%
7D
%
0A23
%
7D
%
0A
这里我们新建一个聊天室作为中介类,所有参与者登陆时调用第
10
行的
connect
方法进入聊天室,并记录其引用到
users
列表中。第
17
行,当用户发消息到平台我们再转发给其他人,这里利用
Java8
的流和
Lambda
表达式进行过滤(
User
类的
equals
方法请自行加入),并循环调用所有接收方的
listen
方法即可。
为了说明问题,我们这里只是保持最简单的方式,如果某天情况变得复杂,有了不同的用户,或是聊天室也各不相同并加入了各自的特性,那我们就需要继续重构,抽象聊天室类,抽象用户类,读者可以灵活运用,这里就不做赘述了。
其实中介模式不止是在生活中广泛应用,在软件架构中也非常常见,当下流行的微服务分布式软件架构所用到的注册中心,例如最常用到的云组件
Eureka
Server
,其作用就是为众多分布式服务提供注册发现服务,它正是充当像中介一样的角色。
还记得之前讲到的组合模式中的树型结构吧,它主要描述的是子节点与父节点的关系。
而中介模式更像是网络拓扑中的星型结构,它描述了众节点与中心点的关系。
对像之间显式地互相引用越多,意味着依赖性越强,独立性越差,不利于代码维护与扩展,同时多方沟通的任务也应交由中间平台来完成,每个类应只具备各自该有的功能,这便是高内聚低耦合的设计标准。中介模式符合迪米特法则,它解决了对象间过度耦合、复杂频繁交互的问题,打破了你中有我,我中有你的相互依赖,第三方的介入有助于双方调停,打破如胶似漆、纠缠不休的关系,让他们之间变得松散、自由、独立。
点击图片加入
Java
知音交流群
↓↓↓
看完本文有收获?请转发分享给更多人
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
华为OD两轮技术面试记录,给后来人一个参考!
下一篇:
面试官:你能说出 方法重载和方法重写 的原理吗?
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目