Подтвердить что ты не робот

Дизайн: Java и возврат самореференции в методах setter

Я уже предложил это в мой блог, но я считаю это место наиболее подходящим.

Для классов с длинным списком сеттеров, которые используются часто, я нашел этот способ очень полезным (хотя я недавно прочитал о Шаблон Builder в Эффективной Java, которая является тем же самым). В принципе, все методы setter возвращают сам объект, поэтому вы можете использовать такой код:

  MyClass
    .setInt(1)
    .setString("test")
    .setBoolean(true)
  ;

Сеттеры просто вернут это в конце:

  public MyClass setInt(int anInt) {
    [snip]
    return this;
  }

Каково ваше мнение? Каковы плюсы и минусы? Это влияет на производительность?

4b9b3361

Ответ 1

@pek
Цепной вызов является одним из предложений для Java 7. В нем говорится, что если тип возвращаемого метода недействителен, он должен неявно возвращать этот. Если вас интересует эта тема, есть куча ссылок и простой пример на странице Alex Miller Java 7.

Ответ 2

Это называется Fluent Interface для справки.

Лично я думаю, что это довольно аккуратная идея, но дело вкуса действительно. Я думаю, jQuery работает таким образом.

Ответ 3

Я бы не стал делать это сам, потому что для меня это мешает то, что делает какой-то конкретный метод, и метод-цепочка имеет ограниченное применение для меня, делая это заново. Это не собирается посылать меня в дрожащий шар ярости и психоза, хотя, что всегда хорошо.: ')

Меня бы не беспокоило производительность; просто спросите Кнута.

Ответ 4

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

aWithB = myObject.withA(someA).withB(someB);

где myObject принадлежит этому классу:

class MyClass {
    withA(TypeA a) {
         this.a.equals(a) ? this : new MyClass(this, a);
    }

    private MyClass(MyClass copy, TypeA a) {
        this(copy);
        this.a = a;
    }
}

Шаблон построителя также полезен, поскольку он позволяет окончательному объекту быть неизменным, предотвращая промежуточные экземпляры, которые вы обычно должны создавать при использовании этой техники.

Ответ 5

Это имеет смысл для строителей, где все, что вы собираетесь делать, это установить нагрузку, создать реальный объект и выбросить строитель. Для строителей вы также можете избавиться от "установленной" части имени метода. Точно так же неизменяемым типам действительно не нужно "получать".

Something thing = new SomethingBuilder()
    .aProperty(wotsit)
    .anotherProperty(somethingElse)
    .create();

Полезный трюк (если вы не возражаете, что накладные расходы на время выполнения 2K для каждого класса) заключается в использовании идиомы двойной привязки:

JFrame frame = new JFrame("My frame") {{
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocation(frameTopLeft);
    add(createContents());
    pack();
    setVisible(true);
}};

Ответ 7

Я использую, чтобы быть поклонником практики Java (и хуже С#) создания геттеров и сеттеров (получить заданные свойства) по всему объекту. Это использование должно быть тем, что я рассматривал как объектно-ориентированное, но на самом деле это приводит нас к тому, чтобы разоблачать кишки и реализацию объекта, а не использовать инкапсуляцию. Иногда вы не можете уйти от этого (OR/M приходит на ум), но в целом объект должен быть настроен, а затем выполнять свою функцию. Объекты моей мечты имеют один или два конструктора и, возможно, полдюжины функций, которые работают.

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

Ответ 8

@Повторите еще раз для более сложных ситуаций (неизменность имеет в виду) шаблон Builder - отличное решение.

Кроме того, я согласен с вами в основном в геттерах. Я считаю, что вы говорите, что в основном следуете " Tell do not ask" парадигма, и я очень согласен. Но это ориентировано в основном на геттеры.

Наконец, все вышеперечисленное относится к классам с большим количеством атрибутов. Я не вижу причины, если у вас меньше, чем, скажем, 7.

Ответ 9

В итоге я много работал над работой с библиотекой Apache POI excel; Я закончил писать вспомогательные методы, которые были привязаны, поэтому я мог применять форматирование, типы данных, внутренние данные ячеек, формулы и позиционирование ячейки.

Для вещей с множеством маленьких крошечных элементов мухи, которые должны иметь небольшие хитрости, он работает очень хорошо.

Ответ 10

Как использовать

/**
 *
 * @author sanjay
 */
public class NewClass {
private int left ;
private int top;
public void set(int x,int y)
    {
    left=x;
    top=y;
}
public NewClass UP(int x)
    {
    top+=x;
    return this;
}
public NewClass DOWN(int x)
    {
    top-=x;
    return this;
}
public NewClass RIGHT(int x)
    {
    left+=x;
    return this;
}
public NewClass LEFT(int x)
    {
    left-=x;
    return this;
}
public void Display()
    {
    System.out.println("TOP:"+top);
    System.out.println("\nLEFT\n:"+left);
}
}
public static void main(String[] args) {
    // TODO code application logic here
    NewClass test = new NewClass();
    test.set(0,0);
    test.Display();
    test.UP(20).UP(45).DOWN(12).RIGHT(32).LEFT(20);
     test.Display();

Ответ 11

Я согласен с @Bernard, что метод цепочки, подобный этому, путает цель сеттеров. Вместо этого я бы предположил, что если вы всегда создаете такие сеттеры, как это, вы создаете собственный конструктор для своего класса, а вместо

    MyClass
    .setInt(1)
    .setString("test")
    .setBoolean(true)
  ;

Вы делаете

new MyClass(1,"test",true);

Это делает его более читаемым, и вы можете использовать его, чтобы сделать ваш класс неизменным, если вы решили.