Пути достижения эффективных черт Java? - PullRequest
11 голосов
/ 22 августа 2011

Пожалуйста, дайте мне знать, если это неуместно, как сформулировано (в частности, будет ли Programmers.SE или что-то еще лучше для вопроса.)

Хорошо.Итак, у меня есть ряд «черт», которые я сейчас выражаю как интерфейсы.Давайте назовем их «обновляемыми» и «разрушаемыми».Выражение их как интерфейсов имеет обратную сторону: я не могу разделить поведение между всеми «разрушаемыми» компонентами;с другой стороны, выражение их как абстрактных классов означает, что я не могу смешивать и сопоставлять без явного определения смешанной черты как другого абстрактного класса («UpdateableAndDestructible»), и, кроме того, это похоже на злоупотребление функциональностью абстрактного класса в этой точке.Это, вероятно, то, что я в конечном итоге сделаю, если не будет более чистых способов справиться с этим, однако.

Какие у меня варианты, кроме чисто Java-решений этой головоломки?Могу ли я описать общее поведение, а затем смешать и сопоставить так, как я считаю нужным, без необходимости явно описывать каждую перестановку, которую я буду использовать?

Ответы [ 4 ]

6 голосов
/ 22 августа 2011

Возможно, вы могли бы достичь цели, используя сочетание интерфейсов и реализаций по умолчанию.

Как:

public interface Updatable {
  void updated();
}

public interface Loadable {
  void load();
}

public class DefaultUpdatable implements Updatable {
 ...
}

public class DefaultLoadable implements Loadable {
 ...
}

public class SomeObject implements Updatable, Loadable {
  private final Updatable updatable = new DefaultUpdatable();
  private final Loadable loadable = new DefaultLoadable();

  public void load() {
    this.loadable.load();
  }

  public void updated() {
    this.updatable.updated();
  }
}

Все еще шумно и, возможно, не так гибко, как хотелось бы, но, возможно, немного чище, чем делать вещь UpdatableAndDestructable.

5 голосов
/ 22 августа 2011

Я не думаю, что есть хорошее решение этой проблемы, но, возможно, несколько выполнимых, в зависимости от того, насколько вы презираете шаблон.

Вы можете определить черту как другой интерфейс класса +, чтопринимает экземпляр объекта в качестве первого параметра.И они реализуют интерфейс с классом, который вы хотите иметь черту.Затем создайте методы-заглушки, которые вызывают методы для признака impl.

public class MyClass implements MyTrait {
    @Override
    public void doSomething() {
        MyTraitImpl.doSomething(this);
    }
}

И затем для самой черты:

public interface MyTrait {
    public void doSomething();
}

public class MyTraitImpl {
    public static void doSomething(MyTrait obj) {
        // do something with obj
    }
}

Как говорит Эрнест Фридман-Хилл, Scala делает это длявы (насколько я понимаю, именно так он реализует черты в JVM).

4 голосов
/ 22 августа 2011

Я знаю, что вы сказали "чистая Java", но это то, что Scala делает хорошо. Ограничения в языке Java сами по себе являются сильным стимулом для принятия другими языками JVM ...

1 голос
/ 23 августа 2011

Если вы планируете использовать lombok в качестве чистой Java, вы можете упростить свою жизнь, используя @Delegate, например:

public class SomeObject implements Updatable, Loadable {
    @Delegate private final Updatable updatable = new DefaultUpdatable();
    @Delegate private final Loadable loadable = new DefaultLoadable();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...