LINUX.ORG.RU

return this


0

0

какие могут быть подводные камни при реализации setterов, возвращающих указатель(или ссылку) на изменяемый объект?

пример:

class SomeClass{
 private Object value;

 public SomeClass setValue(Object value) {
     this.value = value;
     return this;
 }
}
возвращать ссылку this удобно, запись создания/инициализации объекта становится более краткой, не теряя при этом читаемости. Можно строить цепочки из set-методов:
List<SomeClass> list = ...;
list.add( new SomeClass().setValue1(1).setValue2(0).setAttr(null));
а какие минусы у этого подхода?


работу с указателями всегда на С++ плохо. Если в сетере будет исключение, кто память чистить будет?

namezys ★★★★
()

Емнип никаких.

wfrr ★★☆
()

Лучше возвращать не указатель this, а ссылку на *this. И как сказали выше - складывать обычные указатели в список - не очень хорошая идея. Лучше или копировать объекты целиком (только если они маленькие), или завернуть в умный указатель.

Deleted
()
Ответ на: комментарий от namezys

> и при этом ты вынужден отказаться от объектов на стеке

Что мешает объектам на стеке?

Foo foo;

foo.setBoo(1).setBar("Ъ").setXyz(true);

Deleted
()
Ответ на: комментарий от namezys

Foo foo = Foo().setBool(true);

Хотя в таких случаях ИМХО логичнее сделать параметрами конструктора...

Deleted
()
Ответ на: комментарий от namezys

> Если в сетере будет исключение, кто память чистить будет?

Я что-то не очень понял. Продемонстрируй ситуацию примером, пожалуйста.

smh ★★★
()

я прошу прощения за то, что не указал сразу используемый язык. Пусть это будет Java. Таким образом мы пока отложим вопросы про стек/кучу.

savnn
() автор топика

> какие могут быть подводные камни при реализации setterов, возвращающих указатель(или ссылку) на изменяемый объект?

В Smalltalk, AFAIK, так и есть, кстати. Вообще нету методов, аналогичных void'овским. Те, которые ничего своего не возвращают, возвращают this.

Смоллтокеры, поправьте, если что. :)

Score-49
()
Ответ на: комментарий от savnn

>я прошу прощения за то, что не указал сразу используемый язык. Пусть это будет Java.

В Яве такая нотация используются в StringBuilder и в NIO для пайплайнов преобразований данных в буфферах ввода-вывода. В JavaBeans, с другой стороны, принято void setValue(Type value)/ Type getValue().

Т.е зависит от того что ты пишешь - если планируешь делать ЖабоБин, то не стоит.

Absurd ★★★
()
Ответ на: комментарий от sergio_nsk

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

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

Попробую привести пример. Пусть будет класс с конструктором, принимающим 5 параметров и 5-ю сеттерами:


class Weather{
    private String city;
    private double pressure;
    private double temperature;
    private double windSpeed;
    private double humidity; //влажность

    public Weather(){}

    public Weather(String c, double p, double t, double ws, double h){...}


    public Weather setCity(String c){
      city = c;
      return this;
    }

    ///..... все set-методы по аналогии
}



тогда вызов конструктора выглядит:

Weather w = new Weather("New York", 1019.0, 19.0, 7, 78);

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

Weather w = new Weather().setCity("New York").setPressure(1019.0).setTemperature(19.0).setWindSpeed(7).setHumidity(78)
;

savnn
() автор топика
Ответ на: комментарий от Score-49

>В Smalltalk, AFAIK, так и есть, кстати. Вообще нету методов, аналогичных void'овским. Те, которые ничего своего не возвращают, возвращают this.

я немножечко погуглил на эту тему. Есть ссылки, что такая же реализация рассматривается/рассматривалась для Java7. Т.е. методы возвращающие void неявно будут возвращать this. Ссылок не приведу, если очень интересно, то находится по ключевым словам "Fluent interface Java 7"

savnn
() автор топика
Ответ на: комментарий от savnn

Глубокоуважаемый ОП,

Довожу до Вашего сведения что Ваша херня проходит через месяц программирования реального быдлокода на Яве. Ну у слоупоков - через два месяца. Делайте пустой конструктор или вообще класс без конструктора, впердоливайте список полей структуры данных и методы-аксессоры с помощью Refactor->Encapsulate Fields... Когда нужен инстанс этой хрени, создаете ее с помошью new, заполняете ее set-методами и имеете Профит.

Если Вас очень беспокоит проблема неинициализированных данных можете запоминать для каких полей был вызван set-метод с помощью битовых масок и генерировать исключение когда запрошено поле которое не инициализировалось. Если Вы вообще ниибаццо перфекционист можете сделать DSL который автоматически генерит такие классы с битовой маской неинициализированных полей.

В качестве исключения можно привести атомарные типы типа "номера телефона", где у конструктора три параметра. В таких типах нужно наверно перегрузить equals() и hashCode(), как описано у Джошуа Блоха.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>Глубокоуважаемый ОП,

простите за каламбур, но не надо доводить каждую, пусть даже хорошую, идею до абсурда :)

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

Меня больше интересуют подводные камни этого подхода, вобщем вопрос был как раз об этом.

savnn
() автор топика
Ответ на: комментарий от savnn

>Меня больше интересуют подводные камни этого подхода, вобщем вопрос был как раз об этом.

Милостiвый государь ОП,

Подводных камня собственно два:

а) В Яве так не принято. В С++ есть такая идиома, да. Но там вообще много идиом сомнительной полезности. б) Пиши проще, (ч|м)удило.

return this из каждого модифицирующего состояние объекта метода делают классы типа StringBuilder и ByteBuffer(NIO), которые совсем не являются value-типами, а организуют пайплайны для построения последовательностей символов или байт. Изучите эти классы и поймите чем они отличаются от простых value-объектов.

// ИскрѢнне вашъ, Абсурдъ

Absurd ★★★
()

Основной минус -- если у тебя value объявленно константой, то из конструктора ты сможешь ее проинициализировать, а из сеттеров -- не сможешь. Кажется, это относится ко всем C#, Java, C++.

www_linux_org_ru ★★★★★
()

Если часто нужно вызывать кучу сеттеров, имхо что то не так с дизайном. А вообще читабельность похуже, если 1 2 0 null то нормально, а если сложные выражения, будет хуже.

Legioner ★★★★★
()
Ответ на: комментарий от Deleted

> Лучше возвращать не указатель this, а ссылку на *this. И как сказали выше - складывать обычные указатели в список - не очень хорошая идея. Лучше или копировать объекты целиком (только если они маленькие), или завернуть в умный указатель.

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

fmjs
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.