Как бороться с идеей «много маленьких функций» для классов, не передавая много параметров? - PullRequest
6 голосов
/ 12 мая 2011

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

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

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

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

Является ли все это вопросом предпочтения, или есть широко используемый способ иметь дело с такими вещами?

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

Итак, как вы, ребята, справляетесь с этим?

Edit: Несколько примеров, которые побудили меня задать этот вопрос:

О бесплатных функциях: DeadMG был озадачен тем, чтобы заставить работать свободные функции ... без аргументов.

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

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

Это фрагмент функции, которая преобразует данные в формат, который принимает мой класс сетки. Например, для преобразования этого параметра в функцию «finalizeMesh» потребуются все эти параметры. На данный момент это часть огромной компьютерной сетки данных, и биты информации о размерах, размерах и информации о масштабировании используются повсеместно, переплетены.

Вот что я имею в виду, говоря, что "свободным функциям иногда нужно слишком много параметров".

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

Я постараюсь прояснить ситуацию по пути, если необходимо.

Ответы [ 4 ]

4 голосов
/ 12 мая 2011

Каждая дополнительная вспомогательная функция загромождает интерфейс

A private вспомогательная функция отсутствует.

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

Не делайте этого, если это абсолютно не неизбежно.Возможно, вы захотите разбить данные вашего класса на меньшие вложенные классы (или простые старые struct s), а затем передать их между методами.

Я все еще УЖАСУ простой мысли о передаче всего материалаИногда мне нужно, даже в качестве справки

Это не преждевременная оптимизация, это совершенно приемлемый способ предотвращения / уменьшения когнитивной нагрузки.Вы не хотите, чтобы функции принимали более трех параметров.Если их больше трех, рассмотрите возможность упаковки ваших данных в struct или class.

1 голос
/ 12 мая 2011

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

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

Скотт Мейерс утверждает, что в Effective C ++ классы или функции-друзья в большинстве случаев не являются наилучшим вариантом, поскольку клиентский код может что угодно с объектом.

Может быть, вы можете попробовать вложенные классы, которые имеют дело с внутренними объектами вашего объекта. Другим вариантом являются вспомогательные функции, которые используют открытый интерфейс вашего класса и помещают его в пространство имен, связанное с вашим классом.

0 голосов
/ 12 мая 2011

Еще один способ уберечь себя от занятий - использовать идиому pimpl. Скройте вашу личную реализацию за указателем на класс, который фактически реализует то, чем вы занимаетесь, и затем предоставьте ограниченный набор функций тому, кто является потребителем вашего класса.

// Your public API in foo.h (note: only foo.cpp should #include foo_impl.h)
class Foo {
  public:
    bool func(int i) { return impl_->func(i); }
  private:
    FooImpl* impl_; 
};

Есть много способов реализовать это. Шаблон Boost pimpl в Vault довольно хорош. Использование умных указателей - еще один полезный способ справиться с этим.

http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/sp_techniques.html#pimpl

0 голосов
/ 12 мая 2011

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

Итак, позвольте мне получить это совершенно прямо. Вы не профилированы или не разобраны. Но каким-то образом вы намерены ... заставить функции работать ... без аргументов? Как именно вы предлагаете программировать без использования аргументов функции ? Функции-члены не более или менее эффективны, чем бесплатные функции.

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

Универсальные алгоритмы, которые принимают параметры, являются основой современного объектно-ориентированного программирования - в этом весь смысл как шаблонов, так и наследования.

...