知识卡片
入口与外观、适配器、调停者的精确区别
内容
入口是封装外部系统或资源访问的对象——把某个外部资源天然复杂的API(关系数据库的JDBC/SQL、XML的W3C/JDOM等)包装成一个看起来像常规对象的简单接口,让其他代码不必直接理解这些API的复杂性。作者曾犹豫要不要把入口单独列为一个新模式,还是把它归为外观或适配器的变体,最终基于三点实质区别把它独立出来。与外观模式的区别:外观通常是服务的作者提供给通用受众使用的,目的是简化一个较复杂的API,且外观呈现的接口形状往往与原始接口不同;入口则是客户方为了自己的特定应用而编写的,接口可以只是原样照搬被包装的资源接口,目的主要是为将来替换资源或做测试提供切入点,而不是为了改变接口形状。与适配器模式的区别:适配器修改一个已经实现好的接口、让它匹配另一个你要用的接口;入口通常面对的场景是压根没有一个已存在的接口需要去适配(虽然实现入口内部时可能会用到适配器,那时适配器只是入口实现的一部分,而不是入口本身)。与调停者模式的区别:调停者用来解耦多个对象,让它们不必互相引用、只需各自和调停者打交道;入口通常只涉及两方(客户端和被包装的资源),而且被包装的资源本身完全不知道入口的存在。可迁移启发:几个”看起来都是包一层”的经典模式(外观/适配器/调停者/入口),真正的分野往往不在”包了一层”这个表面动作本身,而在于”这层包装是谁写的、为了谁而写、面对的是几方关系、原始接口是否已经存在”这几个更细致的问题——判断该用哪个名字/哪种设计定位,要回到这些具体问题上找答案,而不是停留在”都是包装”这个笼统印象。
结构图:
flowchart TB
A["入口 vs 相似模式"]
A --> B["vs 外观<br/>外观:服务作者写/通用/改变接口形状<br/>入口:客户方写/特定应用/常照搬原接口"]
A --> C["vs 适配器<br/>适配器:改造已有接口去匹配另一接口<br/>入口:通常无已存在接口需适配"]
A --> D["vs 调停者<br/>调停者:解耦多个互相引用的对象<br/>入口:只涉及两方,资源不知道入口存在"]
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第18章 基本模式"之"18.1.2 使用时机"(源文件:_epub-src/OEBPS/Text/000211.html)
- 结论依据:原文说明"外观模式对较复杂的API进行简化,其通常由服务的作者提供,而且是通用的。入口则是客户方为了其特定应用而撰写的……适配器模式修改某一已经实现的接口,使其与另一个你所用到的接口相匹配。入口模式中通常没有一个已存在的接口……调停者模式通常用来将多个对象解耦……入口模式中通常只涉及两个对象,而且被包装的资源并不知道入口的存在",直接支撑本卡结构图。
- 原始内容:入口则是客户方为了其特定应用而撰写的。此外,一个外观通常暗示一个与原始接口不同的接口,但在入口中可以只是简单地照搬被包装的接口。