Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Interface或Abstract类隐藏实现类_Java_Oop_Design Patterns - Fatal编程技术网

Java 如何使用Interface或Abstract类隐藏实现类

Java 如何使用Interface或Abstract类隐藏实现类,java,oop,design-patterns,Java,Oop,Design Patterns,我有这个想法。项目建设有两种风格 正常身材 开发人员构建 在开发人员构建的情况下,我需要再编译几个包,并将它们包含在构建结构中 在这种情况下,存在公共文件MainClass Mainclass { if(devFeature){ CommonInterface int = new DeveloperFile(); ........ other logic ...... }else{ CommonInterface int =

我有这个想法。项目建设有两种风格

  • 正常身材
  • 开发人员构建
  • 在开发人员构建的情况下,我需要再编译几个包,并将它们包含在构建结构中

    在这种情况下,存在公共文件
    MainClass

    Mainclass {
         if(devFeature){
            CommonInterface int = new DeveloperFile();
             ........ other logic ......
         }else{
             CommonInterface int = new NormalFile();
             ........ other logic ......
         }
    }
    
    如上所述,
    MainClass
    是一个公共资源,保存
    DeveloperFile
    的jar仅在开发人员构建期间被引用但在正常构建期间,这将导致编译错误。

    我怎样才能解决这个问题?任何特定的设计模式?

    都可以用来实例化类

    下面是一个基本示例,
    concreteClass
    变量可以从文件中读取,也可以作为参数传递给main方法:

    String concreteClass = ...
    CommonInterface instance = Class.forName(concreteClass).newInstance();
    ...
    

    或者更好,您可以使用一个在幕后使用反射的框架。作为一个例子,我们要做到这一点

    在这种情况下,使用一个具体的类或另一个类只需要在配置文件中进行修改。

    可能是最合适的模式(在Java中,一个这样做的框架是Spring,另一个流行的是JEE的EJB),因为您基本上需要的是让环境告诉您的
    main类
    使用哪个类

    您可以使用的另一种模式是。您可以查看JDBC驱动程序的位置—在JDBC4之前的版本中,它基本上是这样工作的:

    • 您有一个registry类,它保存有关可用的
      CommonInterface
      实现的信息
    • 接口的具体实现有一个静态初始值设定项,它将类注册到注册表中
    • 您为
      main类
      提供了要使用的实现的名称(作为
      字符串
      ,因此不会创建编译时依赖项)
    • MainClass
      调用
      Class.forName(implName)
      ,这将加载类并调用静态初始值设定项,注册实现
    • 然后,
      main类将注册表用作工厂,调用类似于
      registry.getCommonInterface()

    JDBC4使用Java的内置机制,您可能也可以使用它。

    简单一点:使用工厂。您真正需要的是有两个版本的
    CommonInterfaceFactory
    ,一个创建
    DeveloperFile
    的实例,另一个创建
    NormalFile
    的实例。确保第一个包含在开发人员构建中,第二个包含在正常构建中

    CommonInterface int1 = CommonInterfaceFactory.makeCommonInterfaceInstance();
    

    所以你建议有两个不同的类共享相同的名称?EWW。那么,为什么还要麻烦工厂,而不使用两种不同的
    CommonInterface
    实现,它们都具有相同的名称“EWW”?哈哈。这不是一个精辟的批评,但能让人理解你的观点。但说真的,当然,为什么不呢?您肯定可以有两个同名的不同实现。这在为JNI代码提供特定于平台的实现时非常常见。我知道,形式上并不完全正确。对不起。关于为什么不这样做的一些要点-1)开发人员可能会感到困惑并编辑错误的类(因为他们无法通过查看文件/类名来确定)2)如果客户向您发送stacktrace,它与该类的哪个版本相关?你必须在你的文档中找到它,并希望它是真的。3) 团队内部沟通出现问题-“该类?哪个版本?”4)如果在同一个应用程序中需要两个版本,您就有麻烦了。合理的批评,但不是致命的。1-3可以简单地通过使该类成为另一个唯一命名类的薄包装来解决。而#4与问题的基本前提相矛盾,即它们是相互排斥的。