我从小就爱游戏,小时候的插卡红白机,游戏厅的大街机,再到单机电脑游戏,真是满满的回忆呀!不小心透漏了80后的年纪了,哎老了。既然这么爱玩游戏,那么我要自己创作一款即时战略类的游戏,说干就干,开始啪啦啪啦的敲起键盘来。。我想编写的游戏用到了显卡,看了下显卡的编程文档,它提供了硬件指令接口
public class Hardware {
public void graphicsCard(String ...command) {
for(String cmd : command){
System.out.println("执行英伟达显卡专有指令:" + cmd);
}
System.out.println("我是英伟达显卡,我开始工作了");
}
}
然后开始在操作系统上编写游戏
public class OperatingSystem {
public void playGame() {
Hardware hardware = new Hardware();
System.out.println("开始调用显卡指令...");
hardware.graphicsCard("0x12345678", "0xFFFFFFFFFF");
System.out.println("游戏开始了");
}
}
编写好了,我们开始测试,自己玩自己编的游戏
public class Main {
public static void main(String[] args) {
OperatingSystem os = new OperatingSystem();
os.playGame();
}
}
哇自己编写的游戏就是牛逼,我发现编写的游戏火了,大家都给出好评,但是还有些问题,有些人用的显卡不是英伟达的,是AMD的,然后我又针对AMD的显卡进行了指令调整,并且修改了游戏的代码,发布一个专门amd的版本。过了一段时间,英伟达和AMD又出了新的显卡,阅读了他们的文档发现指令都有细微的调整,而越来越多的人用的是最新的显卡,我不得不又去改游戏的代码,if else兼容不同的硬件指令。。天哪硬件这东西,每隔几个月都有可能出个新的,机器指令也可能会更改。这样下去的话,每次硬件改动都要改游戏代码和硬件代码,对于用户来说,换个显卡还要找对应的专有游戏程序,这一下就违反了开闭原则了,怎么办??
经过查阅网上资料,发现操作系统有提供标准的操作硬件指令的抽象接口,在操作系统层面意味着我们编写的游戏可以直接调用它提供的标准接口,其实就是编写硬件专有驱动,在系统上安装了驱动之后,我们的游戏无论调用了是哪种显卡的专有指令,都会按照操作系统的标准接口来,这样就不用修改游戏代码了。好像有种模式叫适配器模式,对就是它,经过一番改良之后,游戏得以很好的运行,用户也不再抱怨了。
为了扩展不同品牌的硬件,我们先抽象出硬件接口以及其实现
public interface Hardware {
void graphicsCard(String ...command);
}
public class DirosHardware implements Hardware{
@Override
public void graphicsCard(String... command) {
for(String cmd : command){
System.out.println("执行英伟达显卡专有指令:" + cmd);
}
System.out.println("我是英伟达显卡,我开始工作了");
}
}
操作系统提供了标准的硬件驱动接口
public interface Driver {
void startPower();
void writeMemory();
}
下面是重头戏,我们要实现这个驱动接口,建立英伟达XXX型号专有驱动,实际上这个实现就是适配器
public class DirosDriver implements Driver {
Hardware hardware = new DirosHardware();
@Override
public void startPower() {
hardware.graphicsCard("0x12345678");
}
@Override
public void writeMemory() {
hardware.graphicsCard("0xFFFFFFFFFF");
}
}
接下来我们在操作系统上重新修改游戏代码
public class OperatingSystem {
private Driver driver;
public void installDriver(Driver driver) {
this.driver = driver;
}
public void playGame() {
driver.startPower();
driver.writeMemory();
System.out.println("游戏开始了");
}
}
可以看到在游戏中可以调用操作系统标准的驱动接口(适配器)操作显卡硬件指令。
最后客户在操作系统上安装驱动,而后开始启动游戏
public class Main {
public static void main(String[] args) {
OperatingSystem os = new OperatingSystem();
Driver hardwareDriver = new DirosDriver();
os.installDriver(hardwareDriver);
os.playGame();
}
}
通过重新编写的游戏,我们可以看到,当显卡换成任意品牌,只需要扩展适配器以及硬件实现即可,对于游戏编写者和玩家而言无需改动,完全符合开闭原则了。当然这个仅是例子,真正的调用硬件指令可不是这么简单的事情。
我们再来看下GOF给出的定义:将一个类的接口转换成客户期望的另一种接口。使得使原本不能一起工作的类能够协同工作。在我们的例子中,客户期望的接口就是Driver接口,在概念中就是目标接口(Target)(请忽略操作系统强制提供),但实际上真正执行的是Hardware接口,在概念中是需要被适配的类(Adaptee),这二者通过适配器(Adapter),即DriosDriver来建立联系。
在真实的场景中多数用于解决一些功能无法在修改或难以修改,无法使用继承等方式去使用、扩展功能。而使用者由于要用的地方比较多,他们就可以用到适配器模式去适配新老接口。如音视频解码器,语言翻译器等。在生活场景中,笔记本电脑的电源适配器,小区外面的变压器等。

被折叠的 条评论
为什么被折叠?



