DoSomethingToThing (Thing n) против Thing.DoSomething ()

Какие факторы определяют, какой подход более уместен?

Дубликат stackoverflow.com/questions/68617/…

UnkwnTech 17.09.2008 00:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
1
922
16
Перейти к ответу Данный вопрос помечен как решенный

Ответы 16

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

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

Итак, Thing.DoSomething (), а не DoSomethingToThing (Thing n).

«Скажи, не спрашивай» Мне это нравится !! Niiice !!

Mostlyharmless 17.09.2008 00:45

Это одно из тех банальных высказываний, которые, кажется, приживаются :)

benefactual 17.09.2008 01:27

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

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

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

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

GetTotalPriceofThings();

против

Cart.getTotal();

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

Вот несколько факторов, которые следует учитывать:

  • Можете ли вы изменить или расширить класс Thing. Если нет, используйте первое
  • Можно ли создать экземпляр Thing. Если нет, используйте более позднее как статический метод.
  • Если Thing действительно модифицируется (т.е. имеет изменяющиеся свойства), отдайте предпочтение последнему. Если Thing не модифицируется, последнее также приемлемо.
  • В противном случае, поскольку объекты предназначены для сопоставления с объектом реального мира, выберите метод, который кажется более обоснованным.

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

ThingDoSomething () ThingDoAnotherTask () ThingWeDoSomethingElse ()

тогда

ДругойThingDoSomething ()

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

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

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

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

Если «что-то» не является естественной частью модели предметной области, тогда можно использовать вспомогательный метод.

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

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

Например, у вас может быть два объекта сохранения в вашей программе, поэтому вы можете принять DatabaseObject.Save (вещь) SessionObject.Save (вещь) будет более выгодной, чем thing.Save () или thing.SaveToDatabase или thing.SaveToSession () .

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

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

Collection.Add(Thing)

лучше, чем

Thing.AddSelfToCollection(Collection)

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

Ответ принят как подходящий

Думаю, у обоих есть свои места.

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

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

Например, если часть «предложения», которую вы хотели бы выделить, является объектом, вам следует использовать стиль объектно-ориентированного программирования.

Пример:

fileHandle.close();

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

Контрпример:

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

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

Излишне говорить, что они не исключают друг друга. У вас, вероятно, действительно будет

networkConnection.submitHttpRequest(x)

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

  1. Вещь. подходит, если Вещь является предметом вашего предложения.
    • DoSomethingToThing (вещь) подходит, если Вещь является объектом вашего предложения.
    • 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);

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

Я должен согласиться с Кевин Коннер

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

Я согласен с Орионом, но я перефразирую процесс принятия решения.

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

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

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

Еще один способ думать об этом - как о покупке части развлекательной системы. Имеет смысл связать пульт от телевизора с телевизором, потому что вы всегда используете их вместе. Но было бы странно связывать кабель питания для конкретного видеомагнитофона с телевизором, поскольку многие клиенты никогда не воспользуются этим. Ключевая идея - как часто это действие будет использоваться с этим объектом?

Другие вопросы по теме