其中的UsbDrive就是可替换的移动存储设备,之所以用这个名字,是为了让大家觉得直观,就像我们平常使用电脑上的USB插口插拔设备一样。
OK!下面我们来测试我们的“电脑”和“移动存储设备”是否工作正常。我是用的C#控制台程序,具体代码如下:
Code:测试代码
 1面向接口编程详解(二)——编程实例(2)_休闲namespace InterfaceExample
 2面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_02{
 3面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05    class Program
 4面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_06    {
 5面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        static void Main(string[] args)
 6面向接口编程详解(二)——编程实例(2)_休闲_10        {
 7面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Computer computer = new Computer();
 8面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            IMobileStorage mp3Player = new MP3Player();
 9面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            IMobileStorage flashDisk = new FlashDisk();
10面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            IMobileStorage mobileHardDisk = new MobileHardDisk();
11面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
12面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine("I inserted my MP3 Player into my computer and copy some music to it:");
13面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.UsbDrive = mp3Player;
14面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.WriteData();
15面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine();
16面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
17面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine("Well,I also want to copy a great movie to my computer from a mobile hard disk:");
18面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.UsbDrive = mobileHardDisk;
19面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.ReadData();
20面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine();
21面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
22面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine("OK!I have to read some files from my flash disk and copy another file to it:");
23面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.UsbDrive = flashDisk;
24面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.ReadData();
25面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.WriteData();
26面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.ReadLine();
27面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

28面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33    }

29面向接口编程详解(二)——编程实例(2)_职场_35}

现在编译、运行程序,如果没有问题,将看到如下运行结果:
面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_36
图2.1 各种移动存储设备测试结果
好的,看来我们的系统工作良好。
后来……

 
刚过了一个星期,就有人送来了新的移动存储设备NewMobileStorage,让我测试能不能用,我微微一笑,心想这不是小菜一碟,让我们看看面向接口编程的威力吧!将测试程序修改成如下:
Code:测试代码
 1面向接口编程详解(二)——编程实例(2)_休闲namespace InterfaceExample
 2面向接口编程详解(二)——编程实例(2)_休闲_38{
 3面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05    class Program
 4面向接口编程详解(二)——编程实例(2)_职场_42    {
 5面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        static void Main(string[] args)
 6面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_46        {
 7面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Computer computer = new Computer();
 8面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            IMobileStorage newMobileStorage = new NewMobileStorage();
 9面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
10面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine("Now,I am testing the new mobile storage:");
11面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.UsbDrive = newMobileStorage;
12面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.ReadData();
13面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.WriteData();
14面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.ReadLine();
15面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

16面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33    }

17面向接口编程详解(二)——编程实例(2)_职场_35}

编译、运行、看结果:
哈哈,神奇吧,Computer一点都不用改动,就可以使新的设备正常运行。这就是所谓“对扩展开放,对修改关闭”。
面向接口编程详解(二)——编程实例(2)_职场_60
图2.2 新设备扩展测试结果
又过了几天,有人通知我说又有一个叫SuperStorage的移动设备要接到我们的Computer上,我心想来吧,管你是“超级存储”还是“特级存储”,我的“面向接口编程大法”把你们统统搞定。
但是,当设备真的送来,我傻眼了,开发这个新设备的团队没有拿到我们的IMobileStorage接口,自然也没有遵照这个约定。这个设备的读、写方法不叫Read和Write,而是叫rd和wt,这下完了……不符合接口啊,插不上。但是,不要着急,我们回到现实来找找解决的办法。我们一起想想:如果你的Computer上只有USB接口,而有人拿来一个PS/2的鼠标要插上用,你该怎么办?想起来了吧,是不是有一种叫“PS/2-USB”转换器的东西?也叫适配器,可以进行不同接口的转换。对了!程序中也有转换器。
这里,我要引入一个设计模式,叫“Adapter”。它的作用就如现实中的适配器一样,把接口不一致的两个插件接合起来。由于本篇不是讲设计模式的,而且Adapter设计模式很好理解,所以我就不细讲了,先来看我设计的类图吧:

如图所示,虽然SuperStorage没有实现IMobileStorage,但我们定义了一个实现IMobileStorage的SuperStorageAdapter,它聚合了一个SuperStorage,并将rd和wt适配为Read和Write,SuperStorageAdapter
面向接口编程详解(二)——编程实例(2)_职场_61
图2.3 Adapter模式应用示意
具体代码如下:
Code:SuperStorageAdapter
 1面向接口编程详解(二)——编程实例(2)_休闲namespace InterfaceExample
 2面向接口编程详解(二)——编程实例(2)_职场_63{
 3面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05    public class SuperStorageAdapter : IMobileStorage
 4面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_67    {
 5面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        private SuperStorage _superStorage;
 6面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
 7面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        public SuperStorage SuperStorage
 8面向接口编程详解(二)——编程实例(2)_职场_73        {
 9面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            get
10面向接口编程详解(二)——编程实例(2)_休闲_77            {
11面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05                return this._superStorage;
12面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33            }

13面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            set
14面向接口编程详解(二)——编程实例(2)_职场_83            {
15面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05                this._superStorage = value;
16面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33            }

17面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

18面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05    
19面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        public void Read()
20面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_91        {
21面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            this._superStorage.rd();
22面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

23面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
24面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        public void Write()
25面向接口编程详解(二)——编程实例(2)_休闲_98        {
26面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            this._superStorage.wt();
27面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

28面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33    }

29面向接口编程详解(二)——编程实例(2)_职场_35}

好,现在我们来测试适配过的新设备,测试代码如下:
Code:测试代码
 1面向接口编程详解(二)——编程实例(2)_休闲namespace InterfaceExample
 2面向接口编程详解(二)——编程实例(2)_休闲_106{
 3面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05    class Program
 4面向接口编程详解(二)——编程实例(2)_职场_110    {
 5面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05        static void Main(string[] args)
 6面向接口编程详解(二)——编程实例(2)_职场_114        {
 7面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Computer computer = new Computer();
 8面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            SuperStorageAdapter superStorageAdapter = new SuperStorageAdapter();
 9面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            SuperStorage superStorage = new SuperStorage();
10面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            superStorageAdapter.SuperStorage = superStorage;
11面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05
12面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.WriteLine("Now,I am testing the new super storage with adapter:");
13面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.UsbDrive = superStorageAdapter;
14面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.ReadData();
15面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            computer.WriteData();
16面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_05            Console.ReadLine();
17面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33        }

18面向接口编程详解(二)——编程实例(2)_java  面向接口编程  接口编程 j_33    }

19面向接口编程详解(二)——编程实例(2)_职场_35}

运行后会得到如下结果:
面向接口编程详解(二)——编程实例(2)_职场_130
图2.4 利用Adapter模式运行新设备测试结果
OK!虽然遇到了一些困难,不过在设计模式的帮助下,我们还是在没有修改Computer任何代码的情况下实现了新设备的运行。
 好了,理论在第一篇讲得足够多了,所以这里我就不多讲了。希望各位朋友结合第一篇的理论和这个例子,仔细思考面向接口的问题。当然,不要忘了结合现实。