- 浏览: 14051 次
- 性别:
- 来自: 北京
最新评论
通过上一篇文章的讨论,我想各位朋友对“面接接口编程”有了一个大致的了解。那么在这一篇里,我们用一个例子,让各位对这个重要的编程思想有个直观的印象。为充分考虑到初学者,所以这个例子非常简单,望各位高手见谅。 问题的提出 定义:现在我们要开发一个应用,模拟移动存储设备的读写,即计算机与U盘、MP3、移动硬盘等设备进行数据交换。 上下文(环境):已知要实现U盘、MP3播放器、移动硬盘三种移动存储设备,要求计算机能同这三种设备进行数据交换,并且以后可能会有新的第三方的移动存储设备,所以计算机必须有扩展性,能与目前未知而以后可能会出现的存储设备进行数据交换。各个存储设备间读、写的实现方法不同,U盘和移动硬盘只有这两个方法,MP3Player还有一个PlayMusic方法。 名词定义:数据交换={读,写} 看到上面的问题,我想各位脑子中一定有了不少想法,这是个很好解决的问题,很多方案都能达到效果。下面,我列举几个典型的方案。 解决方案列举 方案一:分别定义FlashDisk、MP3Player、MobileHardDisk三个类,实现各自的Read和Write方法。然后在Computer类中实例化上述三个类,为每个类分别写读、写方法。例如,为FlashDisk写ReadFromFlashDisk、WriteToFlashDisk两个方法。总共六个方法。 方案二:定义抽象类MobileStorage,在里面写虚方法Read和Write,三个存储设备继承此抽象类,并重写Read和Write方法。Computer类中包含一个类型为MobileStorage的成员变量,并为其编写get/set器,这样Computer中只需要两个方法:ReadData和WriteData,并通过多态性实现不同移动设备的读写。 方案三:与方案二基本相同,只是不定义抽象类,而是定义接口IMobileStorage,移动存储器类实现此接口。Computer中通过依赖接口IMobileStorage实现多态性。 方案四:定义接口IReadable和IWritable,两个接口分别只包含Read和Write,然后定义接口IMobileStorage接口继承自IReadable和IWritable,剩下的实现与方案三相同。 下面,我们来分析一下以上四种方案: 首先,方案一最直白,实现起来最简单,但是它有一个致命的弱点:可扩展性差。或者说,不符合“开放-关闭原则”(注:意为对扩展开放,对修改关闭)。当将来有了第三方扩展移动存储设备时,必须对Computer进行修改。这就如在一个真实的计算机上,为每一种移动存储设备实现一个不同的插口、并分别有各自的驱动程序。当有了一种新的移动存储设备后,我们就要将计算机大卸八块,然后增加一个新的插口,在编写一套针对此新设备的驱动程序。这种设计显然不可取。 此方案的另一个缺点在于,冗余代码多。如果有100种移动存储,那我们的Computer中岂不是要至少写200个方法,这是不能接受的! 我们再来看方案二和方案三,之所以将这两个方案放在一起讨论,是因为他们基本是一个方案(从思想层面上来说),只不过实现手段不同,一个是使用了抽象类,一个是使用了接口,而且最终达到的目的应该是一样的。 我们先来评价这种方案:首先它解决了代码冗余的问题,因为可以动态替换移动设备,并且都实现了共同的接口,所以不管有多少种移动设备,只要一个Read方法和一个Write方法,多态性就帮我们解决问题了。而对第一个问题,由于可以运行时动态替换,而不必将移动存储类硬编码在Computer中,所以有了新的第三方设备,完全可以替换进去运行。这就是所谓的“依赖接口,而不是依赖与具体类”,不信你看看,Computer类只有一个MobileStorage类型或IMobileStorage类型的成员变量,至于这个变量具体是什么类型,它并不知道,这取决于我们在运行时给这个变量的赋值。如此一来,Computer和移动存储器类的耦合度大大下降。 那么这里该选抽象类还是接口呢?还记得第一篇文章我对抽象类和接口选择的建议吗?看动机。这里,我们的动机显然是实现多态性而不是为了代码复用,所以当然要用接口。 最后我们再来看一看方案四,它和方案三很类似,只是将“可读”和“可写”两个规则分别抽象成了接口,然后让IMobileStorage再继承它们。这样做,显然进一步提高了灵活性,但是,这有没有设计过度的嫌疑呢?我的观点是:这要看具体情况。如果我们的应用中可能会出现一些类,这些类只实现读方法或只实现写方法,如只读光盘,那么这样做也是可以的。如果我们知道以后出现的东西都是能读又能写的,那这两个接口就没有必要了。其实如果将只读设备的Write方法留空或抛出异常,也可以不要这两个接口。总之一句话:理论是死的,人是活的,一切从现实需要来,防止设计不足,也要防止设计过度。 在这里,我们姑且认为以后的移动存储都是能读又能写的,所以我们选方案三。 实现 下面,我们要将解决方案加以实现。我选择的语言是C#,但是在代码中不会用到C#特有的性质,所以使用其他语言的朋友一样可以参考。 首先编写IMobileStorage接口: Code:IMobileStorage 代码比较简单,只有两个方法,没什么好说的,接下来是三个移动存储设备的具体实现代码: U盘 Code:FlashDisk Code:MP3Player Code:MobileHardDisk Code:Computer OK!下面我们来测试我们的“电脑”和“移动存储设备”是否工作正常。我是用的C#控制台程序,具体代码如下: Code:测试代码
2{
3 public interface IMobileStorage
4 {
5 void Read();//从自身读数据
6 void Write();//将数据写入自身
7 }
8}
2{
3 public class FlashDisk : IMobileStorage
4 {
5 public void Read()
6 {
7 Console.WriteLine("Reading from FlashDisk……");
8 Console.WriteLine("Read finished!");
9 }
10
11 public void Write()
12 {
13 Console.WriteLine("Writing to FlashDisk……");
14 Console.WriteLine("Write finished!");
15 }
16 }
17}
MP3
2{
3 public class MP3Player : IMobileStorage
4 {
5 public void Read()
6 {
7 Console.WriteLine("Reading from MP3Player……");
8 Console.WriteLine("Read finished!");
9 }
10
11 public void Write()
12 {
13 Console.WriteLine("Writing to MP3Player……");
14 Console.WriteLine("Write finished!");
15 }
16
17 public void PlayMusic()
18 {
19 Console.WriteLine("Music is playing……");
20 }
21 }
22}
移动硬盘
2{
3 public class MobileHardDisk : IMobileStorage
4 {
5 public void Read()
6 {
7 Console.WriteLine("Reading from MobileHardDisk……");
8 Console.WriteLine("Read finished!");
9 }
10
11 public void Write()
12 {
13 Console.WriteLine("Writing to MobileHardDisk……");
14 Console.WriteLine("Write finished!");
15 }
16 }
17}
可以看到,它们都实现了IMobileStorage接口,并重写了各自不同的Read和Write方法。下面,我们来写Computer:
2{
3 public class Computer
4 {
5 private IMobileStorage _usbDrive;
6
7 public IMobileStorage UsbDrive
8 {
9 get
10 {
11 return this._usbDrive;
12 }
13 set
14 {
15 this._usbDrive = value;
16 }
17 }
18
19 public Computer()
20 {
21 }
22
23 public Computer(IMobileStorage usbDrive)
24 {
25 this.UsbDrive = usbDrive;
26 }
27
28 public void ReadData()
29 {
30 this._usbDrive.Read();
31 }
32
33 public void WriteData()
34 {
35 this._usbDrive.Write();
36 }
37 }
38}
其中的UsbDrive就是可替换的移动存储设备,之所以用这个名字,是为了让大家觉得直观,就像我们平常使用电脑上的USB插口插拔设备一样。
2{
3 class Program
4 {
5 static color:
发表评论
-
学JFreeChart不得不看的中文API
2011-09-26 11:03 389学JFreeChart不得不看的 ... -
一些关于AXIS类的方法:
2011-09-26 11:02 597一些关于AXIS类的方法: Axis类: void s ... -
JAVA基础--JAVA中的反射机制详解
2010-09-14 16:20 594JAVA反射机制 JAVA反射机制是在运 ... -
面向接口编程详解(三)——模式研究
2010-09-14 14:01 790通过前面两篇,我想各位朋友对“面向接口编程”的思想有了一定 ... -
奇偶列變換底色
2010-09-13 15:09 889報表的奇數列與偶數列以不同的背景色彩呈現是常見的報表格式, ... -
Unknown hyperlink target 0
2010-09-13 15:00 2227错误的原因可以查看 工具生成的报表和 类报表的jar是否 ... -
赋值运算符
2010-08-26 11:44 514public class MainClass { publ ... -
JSP DOM解析器
2010-08-26 11:32 578<!--Sams Teach Yourself J ...
相关推荐
面向接口编程详解(二)——编程实例 面向接口编程是一种编程思想,强调通过接口来实现多态性和可扩展性。在本文中,我们将通过一个实例来详细解释面向接口编程的思想和优点。 问题提出:我们要开发一个应用,模拟...
面向接口编程是面向对象编程中的一个重要概念,它并非与面向对象编程平级,而是面向对象思想的精华之一。本文将详细解释面向接口编程的思想基础。 首先,我们需要理解接口的定义和本质。接口在编程中是一个包含一...
编程实例在学习Windows API时起到关键作用,因为理论知识只有通过实践才能更好地理解和掌握。例如,创建一个简单的“Hello, World!”程序,需要涉及窗口类的注册、窗口的创建、消息循环的设置以及消息处理函数的编写...
### 面向接口编程详解 #### 一、面向接口编程与面向对象编程的关系 面向接口编程并非一种独立于面向对象编程之外的新编程思想,而是面向对象编程思想体系中的一个重要组成部分。面向对象编程的核心在于模拟现实...
全称为Struts2 + Spring + Hibernate,是Java Web开发中常用的一种集成框架,它结合了Struts2的MVC设计模式、Spring的IoC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)...
Java基础入门编程详解,这本...综上所述,"打通经脉——Java基础入门编程详解"这个资源涵盖了Java编程的基础知识,适合初学者逐步掌握这门强大的编程语言。通过深入学习和实践,可以为进阶的Java开发打下坚实的基础。
《Think in C++编程详解》是一本旨在帮助读者从初级水平逐步提升至高阶的C++编程指南。这本书深入浅出地介绍了C++语言的核心概念和技术,结合作者多年的编程实践经验,为学习者提供了丰富的知识与实用技巧。 首先,...
面向对象编程(OOP)是计算机编程中一种极为重要的范式,它的核心思想是将数据(属性)和行为(方法)封装成一个单独的实体——类。通过类的实例化,我们能够创建对象,并利用对象之间相互作用来解决实际问题。OOP的...
拦截器遵循AOP(面向切面编程)的理念,它将关注点分离,使得核心业务逻辑与辅助功能可以独立管理。 首先,让我们了解一下创建一个处理器拦截器的基本步骤: 1. 创建Interceptor类:你需要实现SpringMVC提供的`...
Java 2 编程详解 Part1 是一个针对Java编程初学者和进阶者的教程资源,旨在帮助大家系统地学习和理解Java语言的核心概念和技术。在这个部分,我们将深入探讨Java的基础知识,包括语法、数据类型、控制结构、类与对象...
《独门架构——JavaWeb开发应用详解》是一本深度探讨JavaWeb开发技术的专业书籍,旨在帮助已经具备Java基础知识的学习者和开发者进一步提升在Web领域的专业技能。本书详细讲解了JavaWeb开发中的各种核心概念、技术和...
### Java的面向对象编程——继承、接口、包 #### 一、面向对象编程基础 **1.1 类与对象** 面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它将数据和对数据的操作封装在一个实体内,即类...
《TCP/IP详解第二卷——实现》是网络通信领域的一部经典著作,由知名网络专家W. Richard Stevens撰写。这本书深入浅出地介绍了TCP/IP协议族的实际运作机制,为读者提供了全面而详尽的TCP/IP实现知识。由于内容涵盖...
通过这个“VC++课件——轻松搞定VC++”的学习,你可以掌握C++的基础语法,深入理解面向对象编程的核心概念,并学会如何在VC++环境中运用这些知识。每个章节的PPT文件将详细讲解每个主题,并提供实例代码和练习,确保...
6. 面向接口编程和依赖注入的概念。 7. 实战项目,通过例子来理解和应用面向对象分析与设计。 通过学习这个教程,你将能够更好地理解面向对象的思维方式,掌握分析和设计的技能,为编写高效、可扩展的软件打下坚实...