Универсальный интерфейс [закрывается]

Другие ответили на Ваш вопрос приятно. Таким образом, просто простая точка для создания...

я постарался бы не возвращать массив (если Вы не можете). Палка с IEnumerable и затем можно использовать Enumerable.Empty<T>() от API LINQ. Очевидно, Microsoft оптимизировала этот сценарий для Вас.

IEnumerable<string> GetTheStuff()
{
    List<string> s = null;
    if (somePredicate())
    {
        var stuff = new List<string>();
        // load data
        return stuff;
    }

    return Enumerable.Empty<string>();
}
54
задан Yvette Colomb 12 December 2018 в 09:57
поделиться

5 ответов

Вот одно предложение:

public interface Service<T,U> {
    T executeService(U... args);
}

public class MyService implements Service<String, Integer> {
    @Override
    public String executeService(Integer... args) {
        // do stuff
        return null;
    }
}

Из-за стирания типа любой класс сможет реализовать только одно из них. Это, по крайней мере, устраняет избыточный метод.

Вы предлагаете вполне разумный интерфейс, но я не уверен на 100%, какую ценность он добавляет. Вы можете просто использовать стандартный интерфейс Callable . Он не поддерживает аргументы, но эта часть интерфейса имеет наименьшее значение (imho).

84
ответ дан 7 November 2019 в 07:52
поделиться

Вот еще одно предложение:

public interface Service<T> {
   T execute();
}

с помощью этого простого интерфейса вы можете передавать аргументы через конструктор в конкретные классы служб:

public class FooService implements Service<String> {

    private final String input1;
    private final int input2;

    public FooService(String input1, int input2) {
       this.input1 = input1;
       this.input2 = input2;
    }

    @Override
    public String execute() {
        return String.format("'%s%d'", input1, input2);
    }
}
20
ответ дан 7 November 2019 в 07:52
поделиться

Я бы остановился на двух разных интерфейсах.

Вы сказали, что «Я хочу сгруппировать свои исполнители служб под общим интерфейсом ... Также кажется излишним создание двух отдельных интерфейсов для двух разных вызовов службы ... Класс будет реализовывать только один из этих интерфейсов. '

Непонятно, зачем тогда нужен единый интерфейс. Если вы хотите использовать его в качестве маркера, вы можете просто использовать аннотации.

Другой момент - это возможный случай, когда ваши требования меняются и методы с другой подписью появляются в интерфейсе. Конечно, тогда можно использовать шаблон адаптера, но было бы довольно странно видеть, что этот конкретный класс реализует интерфейс, скажем, с тремя методами, два из которых генерируют исключение UnsupportedOperationException. Это'

9
ответ дан 7 November 2019 в 07:52
поделиться

В качестве ответа, строго соответствующего вашему вопросу, я поддерживаю предложение Клейта .


Вы также можете использовать интерфейс маркера (без метода), скажем DistantCall , с несколькими несколькими подчиненными интерфейсами, которые имеют точные подписи, которые вы хотите.

  • Общий интерфейс может служить для пометки всех из них, если вы хотите написать общий код для всех из них.
  • Количество конкретных интерфейсов можно уменьшить, используя общую подпись Клейта.

Примеры «многоразовые» интерфейсы:

    public interface DistantCall {
    }

    public interface TUDistantCall<T,U> extends DistantCall {
      T execute(U... us);
    }

    public interface UDistantCall<U> extends DistantCall {
      void execute(U... us);
    }

    public interface TDistantCall<T> extends DistantCall {
      T execute();
    }

    public interface TUVDistantCall<T, U, V> extends DistantCall {
      T execute(U u, V... vs);
    }
    ....

ОБНОВЛЕНО в ответ на комментарий OP

Я не думал ни о каком instanceof в вызове. Я думал, что ваш телефонный код знает, что он звонит, В вашем вопросе я не встречал упоминания о том, что вызывающий код является универсальным :-(

Если так, я предлагаю вам иметь только один интерфейс, только одну подпись. Наличие нескольких приведет к усложнению всего ничего.

Однако вам нужно задать себе несколько более широких вопросов:
как вы обеспечите правильную связь между вызывающим и вызывающим абонентами?

Это может быть продолжение этого вопроса или другой вопрос ...

4
ответ дан 7 November 2019 в 07:52
поделиться

Если я правильно понимаю, вы хотите, чтобы один класс реализовывал несколько таких интерфейсов с разными параметрами ввода / вывода. ? Это не будет работать в Java, потому что универсальные шаблоны реализуются посредством стирания.

Проблема с универсальными шаблонами Java состоит в том, что универсальные шаблоны на самом деле являются не чем иным, как магией компилятора. Во время выполнения классы не хранят никакой информации о типах, используемых для универсального материала (параметры типа класса, параметры типа метода, параметры типа интерфейса). Следовательно, даже если у вас могут быть перегрузки определенных методов, вы не можете привязать их к нескольким реализациям интерфейса, которые отличаются только параметрами общего типа.

В общем, я понимаю, почему вы думаете, что этот код имеет запах. Однако для того, чтобы предоставить вам лучшее решение, необходимо знать немного больше о ваших требованиях. Почему вы вообще хотите использовать общий интерфейс?

3
ответ дан 7 November 2019 в 07:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: