Как правильно спроектировать мой интерфейс, если у меня есть операции, которые поддерживаются не всеми разработчиками? - PullRequest
8 голосов
/ 27 июля 2011

У меня есть Интерфейс и два Класса, которые реализуют Интерфейс.

public interface MyInterface {
    public void firstMethod();  
    public int secondMethod();
}

public class MyClass1 implements MyInterface  {
    public void firstMethod() {}
}

public class MyClass2 implements MyInterface  {
    public void firstMethod() {}
    public int secondMethod() {}
}

Класс MyClass1 сообщает мне Add unimplemented methods, потому что secondMethod не реализован, хорошо, я будусделай это.Но проблема в том, что мне не нужен этот метод в MyClass1.

По вашему мнению, что лучше всего сделать?

  1. Добавьте нереализованный метод с помощью чего-то вроде return 0
  2. Есть еще один способ исправить это, еслиЯ не хочу это реализовывать.

Ответы [ 8 ]

15 голосов
/ 27 июля 2011

Вы должны выполнить одно из следующих действий:

  1. Разбейте интерфейс на более мелкие части и при необходимости скомпонуйте. Это предпочтительный подход, особенно если выcontrol MyInterface.

  2. Возвращает наиболее разумное значение по умолчанию, которое вы можете.

  3. БроситьUnsupportedOperationException.

Вот более наглядный пример.Допустим, ваш интерфейс выглядит следующим образом:

public interface Driveable {
  public Position accelerate(Vector v, Time t);
  public String getVehicleIdentificationNumber();
}

Если ваш MyClass1 на самом деле Boat и не имеет идентификационного номера транспортного средства, тогда вам не имеет смысла реализовывать это,На самом деле, это на самом деле неправильно.Другие клиенты ожидают, что вы получите это значение, но вы не можете им его дать.

Лучше было бы порция и объединить интерфейсы в более мелкие части, используя правильный фрагмент какнеобходимо.Например, вместо этого вы могли бы написать следующее:

public interface Driveable {
  public Position accelerate(Vector v, Time t);
}

public interface Vehicle extends Driveable {
  public String getVehicleIdentificationNumber();
}

public class Boat implements Driveable { ... }
public class Car implements Vehicle { ... }

Это лучший подход, поскольку он распределяет обязанности между интерфейсами в точности так, как это необходимо.

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

public String getVehicleIdentificationNumber() {
  return "";
}

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

public String getVehicleIdentificationNumber() {
  throw new UnsupportedOperationException("vehicle identification
    number not supported on boats");
}
2 голосов
/ 27 июля 2011

Если есть для вас неуместные методы:

  1. возможно, вам не следует использовать этот интерфейс, рассмотрите возможность изменения дизайна.
  2. Добавьте методы-заглушки (как вы сделали).
2 голосов
/ 27 июля 2011

Если вам все еще нужно это в интерфейсе, и он никогда не должен вызываться (в этой реализации), я бы реализовал, чтобы оно выдавало UnsupportedOperationException :

public int secondMethod() {
    throw new UnsupportedOperationException("Should not be called!");
}
1 голос
/ 27 июля 2011

Это зависит от требования.1. Шаблон интерфейса полезен, когда каждый другой класс, реализующий интерфейс, имеет почти одинаковое поведение, что объясняет, почему все реализации метода являются обязательными.некоторые методы, а другие нет, вероятно, вы можете получить модель abstract Class , где вы можете расширить и дать реализацию, которая нужна вашему классу.что решает вашу цель в большей степени.

для примера: если вы реализуете 9 из 10 методов, то, вероятно, лучше всего реализовать с возвратом 0.

0 голосов
/ 27 июля 2011

Вы создаете класс, который обещает любому абоненту, что он сделает все, что предлагает MyInterface.

Что-то в корне не так с дизайном, если вы не можете выполнить это обязательство.

Поставьте себя в положение вызывающего: что они собираются делать с ответом secondMethod ()?Скорее всего, это разумное значение, например 0 или 1. Вы можете вернуть его.

Важно то, что вы не удивляете своего абонента, поэтому я против создания исключения NotImplementedException.

0 голосов
/ 27 июля 2011

нет нет пути, потому что вы реализуете интерфейс (со всеми методами внутри). Неверно реализовывать только один метод. Это сломает полиморфизм

0 голосов
/ 27 июля 2011

Обычно в этих случаях вы создаете базовый класс, который предоставляет пустые реализации всех методов интерфейса и расширяет его. Например, взгляните на MouseAdapter

0 голосов
/ 27 июля 2011

Для этого вам придется использовать абстрактный родительский класс вместо интерфейса (который может быть не тем, что вы хотите).

...