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

DoSomethingToThing (Thing n) vs Thing.DoSomething()

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

4b9b3361

Ответ 1

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

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

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

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

Пример:

fileHandle.close();

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

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

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

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

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

networkConnection.submitHttpRequest(x)

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

Ответ 3

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

GetTotalPriceofThings();

против

Cart.getTotal();

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

Ответ 4

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

Ответ 5

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

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

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

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Ответ 10

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

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

Ответ 11

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

ThingDoSomething() ThingDoAnotherTask() ThingWeDoSomethingElse()

затем

AnotherThingDoSomething()

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

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

Ответ 12

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

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

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

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

Ответ 13

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

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

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

Ответ 14

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

Collection.Add(Thing)

лучше, чем

Thing.AddSelfToCollection(Collection)

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

Ответ 15

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

Ответ 16

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

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