Должен ли мой API использовать функции, не являющиеся членами, чтобы воздействовать на объект, или сделать функции общедоступными функциями объекта? - PullRequest
1 голос
/ 24 сентября 2010

Недавно я узнал о многих преимуществах (включая красивый код) ООП.

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

Но дело в том, что многие API имеют такой интерфейс (включая Windows API):

// In this case, Object is just a plain data container without a constructor.
Object object = NewObject(...);
DoSomething(object);
DoAnotherThing(object,...);
 ... and so on

Это то, как должны быть организованы API , или есть более вещи в стиле OO, например:

Object object(...);
object.DoSomething(...);
object.DoAnother(otherObj,...);
otherObject.attachNode(object);
 ... and so on again

Я надеюсь, вы поняли идею. Итак, чтобы подвести итог по вопросу, какой метод является более предпочтительным, и почему я вижу много первого примера, несмотря на прославление ООП (хотя, возможно, эти API-интерфейсы в качестве ссылки просто старые, как Windows API).

Как примечание, что вы думаете о Windows API? Мне кажется, это немного ... не правильно.

Ответы [ 8 ]

5 голосов
/ 24 сентября 2010

API может выглядеть так, как вы хотите. Если вы хотите создать C ++ API, вы можете использовать функции-члены сколько угодно. С Win32 API, Microsoft должна была сделать что-то доступное из C (и множества других языков), а также C ++, поэтому они должны были выражать все, используя функции, которые являются универсально доступными. Это означает, что они не могли использовать классы (или расширения, функции-члены), пространства имен, перегрузку, шаблоны и множество других функций C ++.

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

Если ваш API предназначен для использования из кода C ++, тогда вы можете использовать все функции C ++, которые вам нравятся.

На заметку, даже в C ++ делать все функции-члены не обязательно. Использование функций, не являющихся членами по умолчанию, может быть очень хорошей идеей , даже в объектно-ориентированном коде, хотя причины этого отличаются от тех, что были у Microsoft в их API.

2 голосов
/ 24 сентября 2010

Одним из столпов объектно-ориентированного программирования является инкапсуляция. Как можно меньше кода должно зависеть от внутренних элементов объекта, потому что эти внутренние компоненты могут потенциально измениться. Функции-члены могут получать доступ к этим внутренним компонентам, функции, не являющиеся членами (не являющимися друзьями), не могут.

Это означает, что do_something(object) на самом деле больше OO , чем object.do_something(), и многие официальные лица OO, похоже, не понимают этого вообще.

Конечно, это упрощение. Если вам нужна динамическая диспетчеризация, вы должны использовать функции-члены. См. Пункт 23 в Эффективном C ++ или нажмите Как функции, не являющиеся членами, улучшают инкапсуляцию для получения подробной информации.

1 голос
/ 24 сентября 2010

Этот документ может не соответствовать 100% вопроса, но, тем не менее, тесно связан. Скотт Мейерс обсуждает оба стиля, упомянутых в вопросе. Скотт Мейерс: как функции, не являющиеся членами, улучшают инкапсуляцию

1 голос
/ 24 сентября 2010

Это зависит от того, ожидаете ли вы, что API будет работать с OO и не OO кодом. Ваш пример, Windows API, был разработан для работы, прежде всего, с не OO-кодом (по крайней мере, изначально). Поэтому, если вы уверены, что ваши пользователи используют только ОО-языки (особенно если это только для ваших собственных проектов), просто придерживайтесь того, что естественно для языка, с которым вы работаете. Поэтому для C ++ я бы выбрал второй вариант и максимально использовал возможности языка.

1 голос
/ 24 сентября 2010

Я думаю, что это очень субъективная тема.

Хотя я предпочитаю стиль object.DoSomething(), я не вижу ничего плохого в другом.Я бы даже сказал, что иногда это имеет больше смысла.

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

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

0 голосов
/ 24 сентября 2010

Не следует путать правописание с дизайном.

object.Foo() - это просто способ правописания, который говорит, что вы вызываете метод Foo для объекта.Другой язык ОО может использовать орфографию CallMethod(object, Foo), чтобы означать то же самое.Или он мог бы использовать синтаксис Foo(object).

Теперь Windows API - это API, который предназначен для использования как в OO, так и в других языках.Похоже, вы используете привязку C Windows API, привязку, полученную из #include <windows.h>.С не ОО вообще.Поэтому windows.h не выглядит как OO API с точки зрения C ++.

0 голосов
/ 24 сентября 2010

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

0 голосов
/ 24 сентября 2010

Прежняя система является C-подобной.Последний - ОО-способ ведения дел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...