然后,冯·诺伊曼又用三名士兵构建了与非门、或非门、异或门、同或门和三态门,最后只用两名士兵构建了最简单的非门,出总是举与入颜色相反的旗。
冯:诺伊曼对皇帝鞠躬说:“现在,陛下,所有的门部件都已演示完毕,这很简单不是吗?任何三名士兵经过一小时的训练就可以掌握。
“他们不需要学更多的东西了吗?”秦始皇问。
不需要,我们组建一千万个这样的门部件,再将这些部件组合成一个系统,这个系统就能进行我们所需要的运算,解出那些预测太阳运行的微分方程。这个系统,我们把它叫做……嗯,叫做
“计算机。”汪淼说。
“啊–好!"冯·诺伊曼对汪淼竖起一根指头,"计算机,这个名字好,整个系统实际上就是一部庞大的机器,是有史以来最复杂的机器!
——《三体》
人列计算机无疑是《三体》中最震撼的场景之一,在小说中,“冯诺依曼”让每三个人组成一个门部件,整整动用了“秦始皇”三千万个士兵,组成了一个包含一千万门部件的巨型计算机,只为了尝试解决三体运行的终极问题——测算下一个恒纪元。
将微观的、结构化的事物宏观化的、成体系的展示出来,往往会给人以震撼心灵的感受。 就像大火的透明主机机箱设计一样,相信大部分对计算机感兴趣的人都会和笔者一样对它毫无抵抗力。
今天,我就以半开放过程的角度,以计算机运行的视角,在领略计算机魅力的同时,尝试拆解一下什么是外观模式。
一言
外观模式就是通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。
你好,冯诺依曼
我们可以暂时把计算机的启动过程浅显的理解为:
- CPU处理数据
- 内存加载数据
- 硬盘驱动读取数据
突然,你一阵头晕目眩,发现自己就是《三体》中正在给秦始皇设计 “秦一号人列计算机” 的冯诺依曼。你会如何设计?
什么?这还用想?
冯诺依曼一号玩家忍俊不禁,这还用想嘛?面向对象,让秦始皇想调哪个调哪个,已经不能再简单了。
然而,事与愿违,计算机的启动过程并不像我们假设的这样简单。
参照这种设计,“秦始皇”需要亲自对成千上万个门部件下达具体的指令。当“秦始皇”得知了这种设计的交互实质后,直接将“冯诺依曼”送上了断头台。
是的,还真得想想
骄横的“冯诺依曼”玩家再次进入了游戏并陷入了沉思。看来这一关的重点在于如何屏蔽“秦一号”的内部实现细节啊。怎样才能让“秦始皇”轻松的当一个皇帝而不是让他“嵌入”到“人列计算机”内部呢?
有了!
我可以为他提供统一的调用接口,作为外观类,这样只有它知道哪些子系统负责处理请求从而将调用端的请求代理给适当的子系统对象。
“赵高,你过来!陛下要给你个好活!”
设计
我们通过将一群复杂的接口转化为一个接口,将繁重的工作交给赵高大人(外观类),而秦始皇(调用者)只需要从赵高那里得到想要的结果就可以了。
代码实现
CPU
interface CPU {void processData();
}
class CPUImpl implements CPU {@Overridepublic void processData() {System.out.println("CPU is processing data.");}
}
Memory
interface Memory {void loadMemory();
}
class MemoryImpl implements Memory {@Overridepublic void loadMemory() {System.out.println("Memory is loading data.");}
}
HardDrive
interface HardDrive {void readData();
}
class HardDriveImpl implements HardDrive {@Overridepublic void readData() {System.out.println("Hard Drive is reading data.");}
}
ComputerFacade(赵高)
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;public ComputerFacade() {this.cpu = new CPUImpl();this.memory = new MemoryImpl();this.hardDrive = new HardDriveImpl();}public void startComputer() {cpu.processData();memory.loadMemory();hardDrive.readData();System.out.println("Computer started successfully.");}
}
Client(秦始皇)
public class Client {public static void main(String[] args) {ComputerFacade computer = new ComputerFacade();computer.startComputer();}
}
执行
外观模式在Mybatis源码中的应用
在 MyBatis 中,Configuration
类负责管理 MyBatis 的全局配置信息,包括对映射器、参数映射器、结果映射器等的管理。Configuration
对象在 MyBatis 的启动过程中被创建,并在整个应用程序的生命周期中负责管理各种配置信息。
Configuration
对象在创建的过程中会通过 MetaObject
工具类创建 MetaObject
对象,主要用于处理对象的元数据操作。MetaObject
是 MyBatis 提供的一个工具类,用于方便地访问对象的属性信息,进行对象的属性赋值、获取、判断等操作。
具体在 MyBatis 中,MetaObject
被用来处理配置信息、映射器、参数、结果等的属性访问和操作。通过 MetaObject
,可以方便地动态地获取和设置对象的属性值,而不必直接操作对象本身。这样可以提高代码的灵活性和可维护性,使得配置信息的管理更加便捷。
总的来说,Configuration
中通过创建 MetaObject
对象,可以方便地管理和操作 MyBatis 的配置信息,提供了更灵活、方便的方式来处理对象的属性操作,从而实现更加高效和可维护的代码编写。
在Configuration创建MetaObject的过程中,就用到了外观模式。
框架设计
源码分析
在Configuration创建MetaObject时,用到的MetaObject的forObject方法,在object不为空的情况下,其实质是将ObjectFactory,RelectorFactory,ObjectWrapperFactory组合了进来,并根据实际情况进行了进一步的判断和处理。
相关源码
结
外观模式对外屏蔽了子系统的细节,因此我们可以说它降低了客户端对子系统的使用复杂性,在耦合度上它也让子系统的内部模块更容易维护和扩展。
只要外观模式使用的合理,是很容易实现分层设计的。尤其对于一些老系统的维护往往会有奇效。
关注我,共同进步,每周至少一更。——Wayne