繁体   English   中英

设计Java接口:具有可变数量参数的方法

[英]Design a Java interface: a method with variable numbers of parameters

我刚刚遇到了设计接口的问题,该接口的方法可能具有可变数量的输入参数。

public interface FoobarSerialization<T> {
    Foobar serialize(T obj); 
}

问题是,对于实现此接口的类,它们需要不同数量的输入参数。

public class FoobarA implements FoobarSerialization<FoobarA> {
    @Override
    public Foobar serialize(FoobarA obj, int bar) {
        //...
    }
}


public class FoobarB implements FoobarSerialization<FoobarB> {
    @Override
    public Foobar serialize(FoobarB obj, Date date, String str) {
        //...
    }
}

有没有好的设计或任何真正的方法来解决这个问题? 我知道界面中的方法可以声明为:

Foobar serialize(T... obj); 

但我不确定这是一个设计这样的界面的好习惯。

任何想法?

更新 :我使用接口的意图来自需要为不同目的进行序列化和反序列化的类集合。 它们作为同一域下的组件。 但是它们的序列化方法是完全不同的,特别是考虑到它们对不共享任何共同特征或类的对象和服务的依赖性。

我想这里要问的正确问题是:在设计方面,当退出一组具有相同行为(序列化,反序列化,doSomething等)但具有不同输入参数的类时,最好的方法是什么?

救援的组成模式。

在您的特定情况下,我将创建仅接受1个参数的接口:

public interface Serializer<T> {

    Foobar serialize(T object);

}

现在,如果需要序列化多个字段,只需创建一个包含序列化所需字段的对象:

class FoobarBundle {

    String stringField;
    int intField;
    byte[] arrayField;

    /* ... */

}

并编写一系列序列化器: FoobarBundleSerializerStringSerializerIntegerSerializerByteArraySerializer 最后将FoobarBundleSerializer所有序列化器组合起来:

class FoobarBundleSerializer implements Serializer<FoobarBundle> {

    StringSerializer stringSerializer;
    IntegerSerializer integerSerializer;
    ByteArraySerializer byteArraySerializer;

    /* constructor here */

    @Override
    public Foobar serialize(FoobarBundle bundle) {
        Foobar foobarString = stringSerializer.serialize(bundle.stringField);

        Foobar foobarInteger = integerSerializer.serialize(bundle.intField);

        Foobar foobarByteArray = byteArraySerializer.serialize(bundle.byteArrayField);

        return combineFoobarSomehow(foobarString, foobarInteger, foobarByteArray);
    }

}

您的里程可能会有所不同,但应避免使用同名方法的混乱 (例如相同数量但不同类型的参数)。 虽然可以采用方法重载的帮助,但它被认为是不可取的。 如果参数列表是可管理的,则应以不同方式命名方法以避免歧义。 参见Effective Java 2中的第26项

vararg方法没问题,但在Java中,最佳实践是指定至少一个具体参数,后跟可变数量的相同类型的参数。 这可能不适用于您的情况,因为对于像public Foobar serialize(FoobarB obj, Date date, String str);这样的方法没有vararg语法public Foobar serialize(FoobarB obj, Date date, String str); 使用类似(Object ... objects)的语法可能是可以接受的,但这种做法通常适用。

将此与printf类的方法进行对比,该方法可以并且应该能够将任意类型的可变数量的参数(包括基元)输出到输出流。

暂无
暂无

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

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