`
KAXU
  • 浏览: 271603 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

接口和工厂

阅读更多

1 基本信息

摘要:本文说明在Java API设计中,面向接口编程的思想,以及接口和工厂的关系。

作者:陈光耀

2 正文

  现在的java API的设计中,提倡面向接口的编程,即在API的设计中,参数的传递和返回建议使用接口,而不是具体的实现类,如一个方法的输入参数类型应该使用Map接口,而不是HashMap或Hashtable等具体的实现类。这样做的好处是,程序容易扩展。如果使用Map作为参数,用户可以使用任何实现Map接口的类作为参数,而不是仅仅限制使用HashMap或Hashtable作为参数,使程序的实现更加灵活。

  接口(Java的Interface),只定义了一些抽象的方法(也可以定义一些常量,但不鼓励这么做),没有具体的实现,这些抽象方法的具体实现,必须由实现(implements)接口的具体类来实现。接口反映了系统设计人员对系统的抽象理解。实际上,接口只是定义了一个规范和约束,要求实现类必须遵循这些规范和约束,大家编程时都要按照这个规范进行编程。

  使用接口进行编程时,API的使用者只使用接口进行调用,而不管接口是如何实现的,这样你就可以随意更换接口的实现厂商(provider)。假如,你觉得厂商的接口实现不好,可以换一个厂商的实现类,甚至自己来实现,但确基本上不需要更改已经写好的应用程序(因为应用程序只对接口进行调用,而所有的实现类的接口都是相同的)。

  如java.sql包定义了很多jdbc的接口,大家在进行jdbc编程时都只需要使用Connection、PreparedStatment、ResultSet等接口,而不需要考虑这些接口的具体实现类是什么。每种数据库,如Oracle、SQLServer、DB2的JDBC驱动则是由各个厂商提供具体实现类,来实现统一的JDBC API接口规范。

  面向接口的编程中,工厂(Factory)的使用恐怕是最常用的,接口和工厂的关系是密不可分的,工厂,简单的说,就是生产接口实现类实例的类。可以说,在面向接口的编程中,工厂方法发挥了极其重要的作用。

  在开发应用时,如何对接口进行调用,如何实例化接口对象?你无法通过类似于new Inteface1()等来进行实例化,因为接口是不能实例化的(接口即Java的Interface不是类,所有方法都是抽象的,所以不能实例化,能够实例化的只能是接口的实现类)。实例化接口类对象主要有两种方法:

1) 直接new 接口的实现类的实例,类似于
Map map=new HashMap(); //HashMap实现了Map接口
Interface1 instance=new ConcreteClass1();   //ConcreteClass1实现了Inteface1接口

  在一个API内部,这样写无可厚非,因为对调用者是屏蔽的,你今后将HashMap改为hashtable,不会影响到API调用者的程序。但是对于一个API调用的程序来说,这样就不太好了。如下面的调用(出租车公司增加一种高级轿车):
Car car=new BenzCar(); //BenzCar实现了Car接口
carRentCompany.addSuperCar(car);

  虽然可以这样,但这与面向接口的编程的原则不符,因为这要求你必须要知道接口的实现类,如果你有天想换一个实现类(如将奔驰车换成宝马车),就麻烦了,你必须找到你以前的应用程序源代码,将每一个调用接口实现类的地方都改过来,工作量比较大了。

  还有一种更好的方法,就是使用工厂。

2) 使用工厂,如
Car car=CarFactory.getSuperCar();
carRentCompany.addSuperCar(car);

  由工厂来提供实例化方法,你不必关心实例化类是哪一个。当然你必须知道工厂类是哪一个,更换接口实现的时候,你只需要修改工厂的方法就可以了,其余的都不需要更改了。如上面的场景,将奔驰车换成宝马车,只要更改CarFactory.getSuperCar()方法就可以了,用户调用API的程序不需要修改。

  举个jdbc调用的例子:

Oracle的jdbc调用:
    ... ...
    Class.forName("oracle.jdbc.driver.OracleDriver";);
    Connection conn=DriverManager.getConnection(jdbcurl,username,password);

SQLServer的jdbc调用:
    ... ...
    Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
    Connection conn=DriverManager.getConnection(jdbcurl,username,password);

MySQL的jdbc调用:
    ... ...
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn=DriverManager.getConnection(jdbcurl,username,password);

  这里,DriverManager就是工厂,通过getConnection()方法来生产出数据库连接对象Connection, 用户使用Connect就可以实现JDBC编程了。

  但是,DriverManager是怎么知道使用的哪个数据库,使用哪个提供商的JDBC驱动来生产Connectin的吗?答案在这里,原因就在Class.forName()的过程中,Class.forName()是将一个类初始化,这里,调用不同厂商提供jdbc驱动时,使用了不同的jdbc驱动类的类名,该方法会初始化化该Driver类,该类在初始化时(static{}方法中)会初始化一个自己的Driver类实例,并将实例注册到DriverManager中(的一个Vector中),再通过DriverManager中的getConnection()方法找到Driver实例(通过jdbcurl),再调用Driver实例的getConnection()方法。Driver实例也是一个生产Connection接口实例的工厂。DriverManager实际上是一个保存了各个jdbc驱动的一个缓存管理类,缓存了各个驱动程序,并调用各个jdbc的驱动程序生产Connection对象。

  可以看出,只需要更改Driver的类名,提供不同的jdbcUrl和用户、密码,就可以生产出一个数据库连接(Connection接口类的实例)。

  建议:如果你使用配置文件来提供工厂类的名字,程序通过调用配置文件来读取工厂的类名,更换接口实现就更简单了,你只需要改配置文件就可以了,而不需要更改程序。

接口和工厂之间关系形象比喻:

  接口就好比是产品规格,如螺母和螺钉的产品规格,规定了不同的大小尺寸,左旋等,工厂好比生产这些螺母和螺钉的加工企业,而接口的实例好比不同工厂生成出的螺母、螺钉的产品。每一个不同的工厂虽然生成出的不同螺母和螺钉产品,但都必须遵守这个产品规格,这样不同工厂生产出来的不同的螺母和螺钉才可以拧在一起使用,你也可以随意更换不同工厂生产出来的螺母或螺钉,而不会出现问题。

分享到:
评论

相关推荐

    asp.net 接口和工厂 源代码

    在ASP.NET开发中,接口(Interface)和工厂模式(Factory Pattern)是两种非常重要的设计模式。接口主要用于定义对象之间的交互规范,而工厂模式则是一种创建型设计模式,它提供了一种创建对象的最佳方式,隔离了类...

    C# 泛型,以及泛型接口的,简单的工厂模式,实现新闻阅览器

    至于新闻阅览器的实现,我们可以构建一个`NewsReader`类,它利用上述的泛型接口和工厂模式来管理和展示新闻。`NewsReader`可能有一个`LoadNews`方法,它接收一个序列化的新闻数据(可能是JSON或XML格式),然后通过...

    JAVA高级:根据接口解耦示例

    4. 接口与工厂模式:可能介绍了如何结合接口和工厂模式,以更灵活地创建对象,进一步提高代码的解耦度。 通过学习这个示例,开发者可以更好地理解如何在实际项目中运用接口来设计模块,以及如何利用接口来提升软件...

    Java SE程序 接口实现的工厂模式

    Java SE程序 接口实现的工厂模式Java SE程序 接口实现的工厂模式Java SE程序 接口实现的工厂模式Java SE程序 接口实现的工厂模式Java SE程序 接口实现的工厂模式Java SE程序 接口实现的工厂模式Java SE程序 接口实现...

    工厂模式与面向接口编程例子

    首先,工厂模式有三种主要的形式:简单工厂模式、工厂方法模式和抽象工厂模式。简单工厂模式中,有一个中心工厂类负责创建所有实例;工厂方法模式则将创建对象的责任委托给子类,每个子类对应一个产品类型;抽象工厂...

    Java设计模式圣经连载工厂.doc

    在抽象工厂模式中,我们有两个层次的抽象:产品接口和工厂接口。工厂接口定义了一系列相关产品的创建方法,而具体工厂类则实现了这些方法,提供具体的产品实例。 例如,如果我们不仅有水果,还有蔬菜,我们可以创建...

    基于.NET框架的通用数据库访问接口研究与实现.pdf

    综上所述,利用ADO.NET提供的强大功能,结合通用接口和工厂模式,可以有效地实现跨数据库平台的应用程序。这种方式不仅简化了开发过程,而且提高了代码的复用性和系统的扩展性。未来的研究还可以探索更高级的技术,...

    简单MVC框架 接口、工厂、反射

    总结一下,这个"简单MVC框架"利用接口实现了组件间的松耦合,通过数据工厂和动态加载程序集实现了灵活的扩展性,而反射的运用则增强了框架的动态性和可维护性。这样的设计使得开发者能够更高效地构建和维护复杂的...

    基于接口的工厂模式多层架构程序

    总结起来,“基于接口的工厂模式多层架构程序”是一种结合了多层架构和工厂模式的设计,它通过接口定义创建对象的协议,使得系统更易于扩展和维护。在实际开发中,这种设计能帮助我们构建出高效、稳定且易于维护的...

    工厂模式、接口、抽象类的例子

    本示例中的“工厂模式、接口、抽象类”是面向对象设计中的关键概念,让我们逐一深入探讨。 首先,**工厂模式**是一种创建型设计模式,它提供了一种创建对象的最佳方式,将对象的创建过程封装起来,使得代码更加灵活...

    基于接口的工厂模式的三层架构Asp.net2.0

    <br>该项目是一个基于接口的工厂模式的三层架构示例解决方案的 Asp.Net 2.0版本。 <br>****************************************************** <br>Database : 该项目所使用的数据库 DEncryptTest ...

    21-04-03_FactoryPattern(001_在工厂模式下以通过接口结合列表、泛型和反射等方式实现指定类型的实例化操作_控制台).rar

    在这个“21-04-03_FactoryPattern(001_在工厂模式下以通过接口结合列表、泛型和反射等方式实现指定类型的实例化操作_控制台)”案例中,我们将探讨如何利用接口、泛型和反射等技术来进一步增强工厂模式的功能。...

    简单工厂和抽象工厂的Demo

    这种模式的优点在于良好的封装性和扩展性,但缺点是增加了系统的复杂性,特别是当产品族的结构发生变化时,可能需要修改工厂接口或增加新的工厂实现。 在给定的压缩包文件"factory (1)"中,我们可能找到一个示例...

    基于接口的工厂模式的三层架构

    本软件导航菜单使用了微软的iewebcontrols控件,如果不能显示树菜单链接,请安装该控件。 如果win2003系统,还需要将IE的Internet选项的本地Intranet的安全级别调低,以启用控件使用。

    .net接口,工厂模式开发

    在.NET编程环境中,接口(Interface)和继承(Inheritance)是面向对象设计的重要概念,而工厂模式是一种常用的设计模式,用于创建对象时隐藏创建逻辑。在这个实例中,我们将深入探讨这三个核心概念以及它们如何协同...

    SchoolManager(三层+实体+接口+简单工厂+抽象工厂+公共数据库访问类)示例C#源码

    在本篇中,我们将深入探讨一个名为"SchoolManager"的C#项目,它采用三层架构(数据访问层、业务逻辑层和表示层)并融合了实体、接口、简单工厂和抽象工厂的设计模式,以及公共数据库访问类。这些设计模式和架构方式...

    简单工厂和常用接口的实现

    在"简单工厂和常用接口的实现"这个实例中,我们可能会看到以下几个关键点: 1. **简单工厂的实现**:首先会有一个工厂类,比如`ProductFactory`,它包含了静态方法如`createProduct`,根据输入的类型参数返回相应的...

    C#工厂方法的实例,如何利用接口和

    C#工厂方法的实例,如何利用接口和类. 下例代码给出了一个实现鳄梨供货示例的简单程序。每一个出产鳄梨的国家都对应一个类,它们都实现了IProduct接口,从而可以向采购员提供鳄梨。根据不同的月份,FactoryMethod将...

    简单工厂-工厂方法-抽象工厂 对比总结

    抽象工厂模式可以保证在任何环境下都能正确地创建对象,提高了代码的可移植性,但其缺点是增加新平台时,需要增加新的抽象工厂和一系列具体工厂,这可能会导致系统结构变得复杂。 对比这三种工厂模式: 1. **简单...

    简单工厂模式-工厂方法模式-抽象工厂模式

    在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...

Global site tag (gtag.js) - Google Analytics