DoSomethingToThing (Вещь n) по сравнению с Вещью. DoSomething ()

Как Брайан Гетц указал на в комментарии , основой для конструктивного решения было позволить адаптировать метод к функциональному интерфейсу так же, как вы можете назвать метод , т. е. вы можете вызвать метод возвращаемого значения и проигнорировать возвращаемое значение.

Когда дело доходит до лямбда-выражений, все становится немного сложнее. Существуют две формы лямбда-выражений: (args) -> expression и (args) -> { statements* }.

Независимо от того, совместима ли вторая форма void, зависит ли вопрос о том, значение, например () -> { return ""; } не совместим с void, но совместим с выражением, тогда как () -> {} или () -> { return; } совместимы void. Обратите внимание, что () -> { for(;;); } и () -> { throw new RuntimeException(); } оба являются совместимыми с void и совместимыми по значению, поскольку они не выполняются нормально.

Форма (arg) -> expression совместима по значению, если выражение оценивается значением , Но есть также выражения, которые являются операторами одновременно. Эти выражения могут иметь побочный эффект и поэтому могут быть записаны как автономные инструкции для создания только побочного эффекта, игнорируя полученный результат. Аналогично, форма (arg) -> expression может быть void совместимой, если выражение также является выражением.

Выражение формы s -> s не может быть void совместимым, так как s а не заявление, т. е. вы не можете писать s -> { s; }. С другой стороны, s -> s.toString() может быть void совместимым, потому что вызовы методов являются операторами. Аналогично, s -> i++ может быть void совместимым, поскольку приращения могут использоваться как оператор, поэтому s -> { i++; } также является допустимым. Конечно, i должен быть полем для этого, а не локальной переменной.

Спецификация языка Java §14.8. В выражениях выражения перечислены все выражения, которые могут использоваться в качестве операторов. Помимо уже упомянутых операторов вызова и операторов increment / decment, он присваивает имена и выражения создания экземпляра класса, поэтому s -> foo=s и s -> new WhatEver(s) также совместимы void.

В качестве примечания стороны, форма (arg) -> methodReturningVoid(arg) - это форма выражения только , которая не совместима со значением.

12
задан Jon Seigel 4 April 2010 в 05:00
поделиться

16 ответов

Я думаю, что у обоих есть их места.

Вы не должны просто использовать DoSomethingToThing(Thing n) просто, потому что Вы думаете, что "Функциональное программирование хорошо". Аналогично Вы не должны просто использовать Thing.DoSomething() потому что "Объектно-ориентированное программирование хорошо".

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

Например, если бы часть 'предложения', которое требуется подчеркнуть, является объектом, необходимо использовать стиль OO.

Пример:

fileHandle.close();

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

CounterExample:

string x = "Hello World";
submitHttpRequest( x );

В этом случае, отправляющем Запрос HTTP, намного более важно, чем строка, которая является телом, таким образом, submitHttpRequst(x) предпочтительно для x.submitViaHttp()

Само собой разумеется, они не являются взаимоисключающими. Вы будете, вероятно, на самом деле иметь

networkConnection.submitHttpRequest(x)

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

14
ответ дан 2 December 2019 в 05:16
поделиться

Я должен согласиться с Kevin Conner

Также имейте в виду вызывающую сторону любой из 2 форм. Вызывающая сторона является, вероятно, методом некоторого другого объекта, который определенно делает что-то к Вашей Вещи :)

0
ответ дан 2 December 2019 в 05:16
поделиться

Даже в объектно-ориентированном программировании могло бы быть полезно использовать вызов функции вместо метода (или в этом отношении вызов метода объекта кроме того, который мы обращаемся к нему). Вообразите простую платформу персистентности базы данных, где требуется просто звонить, сохраняют () на объекте. Вместо включения SQL-оператора в каждом классе требуется сохранить, таким образом усложняя код, распространяя SQL все через код и делая изменение механизма устройства хранения данных ЛАВАШЕМ, Вы могли создать Интерфейсное определение, сохраняют (Class1), сохраняют (Class2) и т.д. и его реализация. Затем Вы на самом деле назвали бы databaseSaver.save (class1) и иметь все в одном месте.

0
ответ дан 2 December 2019 в 05:16
поделиться

Если бы DoingSomething к объекту, вероятно, приведет к другому результату в другом сценарии, то я предложил бы Вас oneThing. DoSomethingToThing (anotherThing).

Например, Вы можете иметь два, имел сохранение вещи в Вас программа, таким образом, Вы могли бы принять DatabaseObject. Сохраните (вещь) SessionObject. Сохраните (вещь), было бы более выгодным, чем вещь. Сохраните () или вещь. SaveToDatabase или вещь. SaveToSession ().

Я редко не передаю параметров классу, если я не получаю общественные собственности.

0
ответ дан 2 December 2019 в 05:16
поделиться

Для добавления к ответу Вечности это зависит от вещь и что Вы хотите сделать к нему. Таким образом, если Вы пишете Вещь, и DoSomething изменяет внутреннее состояние Вещи, затем лучшим подходом является Вещь. DoSomething. Однако, если действие действительно больше, чем изменяет внутреннее состояние, то DoSomething (Вещь) имеет больше смысла. Например:

Collection.Add(Thing)

лучше, чем

Thing.AddSelfToCollection(Collection)

И если Вы не записали Вещь и не можете создать производный класс, затем у Вас нет выбора, кроме как сделать DoSomething (Вещь)

0
ответ дан 2 December 2019 в 05:16
поделиться

В целом, если "что-то" - действие, которое естественно знает "вещь", как сделать, затем необходимо использовать thing.doSomething (). Это - хорошая инкапсуляция OO, потому что иначе DoSomethingToThing (вещь) должен был бы получить доступ к потенциальной внутренней информации "вещи".

Например, invoice.getTotal ()

Если "что-то" не естественно часть модели предметной области "вещи", то одна опция состоит в том, чтобы использовать вспомогательный метод.

Например: Logger.log (счет)

0
ответ дан 2 December 2019 в 05:16
поделиться

Даже если бы Вы не работаете на языке OO, где у Вас была бы Вещь. DoSomething (), для полной удобочитаемости Вашего кода, имея ряд функций как:

ThingDoSomething () ThingDoAnotherTask () ThingWeDoSomethingElse ()

затем

AnotherThingDoSomething ()

и так далее намного лучше.

Весь код, который работает над "Вещью", находится на одном местоположении. Конечно, "DoSomething" и другие задачи нужно последовательно называть - таким образом, у Вас есть ThingOneRead (), ThingTwoRead ()... к настоящему времени необходимо понять мысль. Когда Вы возвратитесь для работы над кодом через двенадцать месяцев, Вы будете ценить занимание время для создания вещей логичными.

0
ответ дан 2 December 2019 в 05:16
поделиться

Вот несколько факторов для рассмотрения:

  • Можно ли изменить или расшириться ли Thing класс. В противном случае используйте первого
  • Может Thing инстанцировать. В противном случае используйте позже в качестве статического метода
  • Если Thing на самом деле будьте изменены (т.е. имеет свойства, которые изменяются), предпочтите последнего. Если Thing не изменяется последний так же приемлем.
  • Иначе, поскольку объекты предназначены, чтобы отобразиться на объекте реального мира, выбрать метод, который кажется более основанным в действительности.
0
ответ дан 2 December 2019 в 05:16
поделиться

DoSomethingToThing (Вещь n) был бы большим количеством функционального подхода тогда как Вещь. DoSomething () был бы большим количеством объектно-ориентированного подхода.

0
ответ дан 2 December 2019 в 05:16
поделиться

Совсем не достаточно информации здесь. Это зависит, если Ваш язык даже поддерживает конструкцию "Thing.something" или эквивалентный (т.е. это - язык OO). Если так, это является намного более соответствующим, потому что это - парадигма OO (участники должны быть связаны с объектом, они действуют на). В процедурном стиле, конечно, DoSomethingtoThing () является Вашим единственным выбором... или ThingDoSomething ()

0
ответ дан 2 December 2019 в 05:16
поделиться

Я соглашаюсь с Orion, но я собираюсь перефразировать процесс принятия решений.

У Вас есть существительное и глагол / объект и действие.

  • Если много объектов этого типа будут использовать это действие, попытайтесь сделать часть действия объекта.
  • Иначе попытайтесь сгруппировать действие отдельно, но со связанными действиями.

Мне нравится Файл / строковые примеры. Существует много строковых операций, таких как "SendAsHTTPReply", который не произойдет для Вашей средней строки, но действительно часто происходит в определенной установке. Однако Вы в основном будете всегда закрывать Файл (надо надеяться), таким образом, будет иметь смысл помещать Близкое действие в интерфейс класса.

Другой способ думать об этом как покупает часть системы развлечений. Имеет смысл связывать телевизионный пульт дистанционного управления ТВ, потому что Вы всегда используете их вместе. Но было бы странно связать силовой кабель для определенного VCR с ТВ, так как многие клиенты никогда не будут использовать это. Ключевая идея состоит в том, как часто это действие будет использоваться на этом объекте?

1
ответ дан 2 December 2019 в 05:16
поделиться

Чтобы быть объектно-ориентированными, скажите, не спрашивайте: http://www.pragmaticprogrammer.com/articles/tell-dont-ask.

Так, Вещь. DoSomething (), а не DoSomethingToThing (Вещь n).

8
ответ дан 2 December 2019 в 05:16
поделиться

Если Вы имеете дело с внутренним состоянием вещи, Вещи. DoSomething () имеет больше смысла, потому что даже при изменении внутреннего представления Вещи, или как он работает, код, говорящий с ним, не должен изменяться. Если Вы имеете дело с набором Вещей или пишете некоторые служебные методы, процедурный стиль DoSomethingToThing () могли бы иметь больше смысла или более просты; но тем не менее, может обычно быть представлен как метод на объекте, представляющем тот набор: например,

GetTotalPriceofThings();

по сравнению с

Cart.getTotal();

Это действительно зависит от того, насколько объектно-ориентированный Ваш код.

3
ответ дан 2 December 2019 в 05:16
поделиться
  1. Вещь. DoSomething является соответствующим, если Вещью является предмет Вашего предложения.
    • DoSomethingToThing (Вещь n) является соответствующим, если Вещью является объект Вашего предложения.
    • ThingA.DoSomethingToThingB (ThingB m) является неизбежной комбинацией, с тех пор на всех языках я могу думать, функции принадлежат одному классу и взаимно не принадлежат. Но это имеет смысл, потому что у Вас могут быть предмет и объект.

Действительный залог более прост, чем пассивный залог, поэтому удостоверьтесь, что Ваше предложение имеет предмет, который не является просто "компьютером". Это означает, используйте форму 1 и сформируйтесь 3 часто и используйте форму 2 редко.

Для ясности:

// Form 1:  "File handle, close."
fileHandle.close(); 

// Form 2:  "(Computer,) close the file handle."
close(fileHandle);

// Form 3:  "File handle, write the contents of another file handle."
fileHandle.writeContentsOf(anotherFileHandle);
3
ответ дан 2 December 2019 в 05:16
поделиться

Это - Объектно-ориентированное по сравнению с выбором Процедурного программирования :)

Я думаю, что хорошо зарегистрированные преимущества OO относятся к Вещи. DoSomething ()

0
ответ дан 2 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

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