简体   繁体   English

Java接口中静态的替代方法是什么

[英]What is the alternative to static in java interface

I have a design question. 我有一个设计问题。 I have an interface that read XML. 我有一个读取XML的接口。 Each implementer class read different XML and I want a way to identify which implementer should I dynamically create for the xml type I get. 每个实现者类都读取不同的XML,我想要一种方法来标识应该为所获取的xml类型动态创建的实现者。 The problem is that java interface can't have static members. 问题是java接口不能有静态成员。 What is the best way to do it? 最好的方法是什么?

Example: 例:

public interface MyXML{
    public void readXML(String xml);
    public final static String getType();
}

Usage: 用法:

func(String xml, String type)
    {
       MyXML obj;

       switch(type)
       {
          case MyImpl.getType():
             obj = new MyImpl();
             break;
         case MyImpl2.getType():
             obj = new MyImpl2();
             break;
      }
      obj.readXML(xml);
   }

EDIT: I'll try to explain better what I want: I need to know which xml can be read by which implementation and I search for a way to force anyone that implements MyXML to tell which xml it can read so I'll not need to maintain the translation outside in another list or factory. 编辑:我将尝试更好地解释我想要什么:我需要知道哪种XML可以通过哪种实现读取,并且我寻找一种方法来强制实现MyXML的任何人告诉它可以读取哪种xml,所以我不需要在其他列表或工厂之外维护翻译。

I suggest you design your system around instances , not types themselves. 我建议您围绕实例设计系统,而不要自己输入类型。

The application would instantiate all the XML reader types and would query each instance for the type it is in charge of. 该应用程序将实例化所有XML读取器类型,并将向每个实例查询其负责的类型。 You can use that to organize the XML readers into a map and retrieve them with no switch or if-statements. 您可以使用它来将XML阅读器组织到一个映射中,并且无需切换或if语句即可检索它们。

If there are some heavyweight resources associated with an instance in your current design, then change that design such that all the resource acquisition happens later into the object's lifecycle, not at construction time. 如果当前设计中有一些与实例相关的重量级资源,请更改该设计,以使所有资源获取都在对象的生命周期中进行,而不是在构造时。

If you need several instances of the same reader at once (for example, in a concurrent setting), then use the idea exemplified by java.util.regex.Pattern and its corresponding Matcher . 如果一次(例如,在并发设置中)需要同一阅读器的多个实例,请使用java.util.regex.Pattern及其对应的Matcher举例说明的想法。 A pattern is a thread-safe factory of single-threaded, disposable matchers. 模式是单线程,一次性匹配器的线程安全工厂。

Take a look at Factory Design Pattern. 看一看工厂设计模式。 The client should call the factory passing the Type, then the factory returns an instance of the correct class: 客户端应通过传递Type来调用工厂,然后工厂返回正确类的实例:

public class MyFactory {
    public MyXML createMyXML(Type type) {
        return ...
    }
}

This way the client is free from the responsability to know which concrete class needs to be provided. 这样,客户无需承担责任就知道需要提供哪个具体类。

There's no point in storing implementation types in interface. 在接口中存储实现类型没有意义。 The interface shouldn't know about implementations. 该接口不应该了解实现。 Instead you can store the XML Type in Enum. 相反,您可以将XML类型存储在Enum中。

enum Type{
TYPE1,
TYPE2;
}

Then you can create a Map<Type, MyXML> variable and add implementations with their corresponding Type in it. 然后,您可以创建一个Map<Type, MyXML>变量,并在其中添加具有相应Type的实现。

Factory can then be something like: 然后,Factory可以像这样:

public MyXml getImplementation(String type){
   Type type = Type.valueOf(type);
   MyXml impl= implementations.get(type);
   if(impl == null){
       throw new UnsupportedOperationException();//or whatever ex you see fit
   }
   return impl;
}

Java only allow static constants in the interface. Java仅在接口中允许使用静态常量。 In Java 8 you can have also default implementations, but that's a different thing. 在Java 8中,您还可以使用默认实现,但这是另一回事。

One way to solve this is to make getType normal instance method, same as readXML and instantiate implementations in advance, something like this 解决此问题的一种方法是使getType普通实例方法,与readXML相同,并提前实例化实现,类似这样

// somewhere in the constructor or main
List<MyXML> readers = Arrays.asList(new MyImpl1(), new MyImpl2());

public MyXML findReaderForType(String type) {
  for (MyXML reader : readers) {
    if (reader.getType().equals(type)) {
      return reader;
    }
  }
}

However you need to be careful to design your implementations in the way, so they can be reused. 但是,您需要谨慎地设计实现方式,以便可以重用它们。

Another option is to create some sort of static factory, which will contain the equivalent of findReaderForType method. 另一种选择是创建某种静态工厂,其中将包含与findReaderForType方法等效的方法。 Then the mapping between the type and implementation is contained in this factory class. 然后,该工厂类中包含类型和实现之间的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM