Инкапсуляция против структур - это считается плохим стилем? - PullRequest
4 голосов
/ 28 января 2012

У меня есть группа классов в проекте CUDA, которые в основном прославляются struct s и зависят друг от друга по составу:

class A {
    public:
        typedef boost::shared_ptr<A> Ptr;
        A(uint n_elements) { ... // allocate element_indices };
        DeviceVector<int>::iterator get_element_indices();
    private:
        DeviceVector<int> element_indices;
}

class B {
    public:
        B(uint n_elements) { 
            ... // initialize members
        };
        A::Ptr get_a();
        DevicePointer<int>::iterator get_other_stuff();
    private:
        A::Ptr a;
        DeviceVector<int> other_stuff;
}

DeviceVector - это просто оболочка вокруг thrust::device_vectors и ::iterator можно привести к необработанному указателю устройства.Это необходимо, так как пользовательские ядра вызываются и требуют дескрипторов памяти устройства.

Теперь я забочусь об инкапсуляции, но

  • необработанные указатели на данные должны быть доступны,поэтому классы, использующие A и B, могут запускать пользовательские ядра на графическом процессоре
  • конструктор по умолчанию не требуется, память устройства должна выделяться автоматически ->> shared_ptr<T>
  • очень мало методов для A и B требуется

Итак, можно сделать жизнь намного проще, просто используя структуры

struct A {
    void initialize(uint n_elements);
    DeviceVector<int> element_indices;
}

struct B {
    void initialize(uint n_elements);
    A a;
    DeviceVector<int> other_stuff;
}

Интересно, смогу ли яПравильно, что в смысле инкапсуляции это практически эквивалентно.Если да, то что-то не так со всей концепцией и может в какой-то момент укусить?

Ответы [ 3 ]

2 голосов
/ 28 января 2012

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

Даже если вам нужно предоставить необработанные указатели на данные, все же будет хорошей идеей сделать это через геттеры. Вы можете изменить внутреннюю обработку данных, e. г. замените необработанный массив на std :: vector. Если ваш член данных является частным и вы используете метод получения, вы можете сделать это, не затрагивая код, использующий ваш класс. Кроме того, геттеры позволяют вам применять константу и создавать определенный фрагмент данных только для чтения, возвращая константный указатель.

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

2 голосов
/ 28 января 2012

Сделай это просто.Не вводите абстракцию и инкапсуляцию, пока она вам не понадобится.

1 голос
/ 28 января 2012

Это компромисс.

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

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

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

Я думаю, что они больше подходят как константные объекты.Проблема, в которую вы попадаете, состоит в том, что вы (пытаетесь) поддерживать неизменность этого «объекта» везде, где он используется в течение всей его жизни.Если другой уровень абстракции хочет их с небольшими мутациями, сделайте копию.Идиома именованного параметра хороша для этого.

Домен-управляемый дизайн дает вдумчивое, тщательное рассмотрение предмета.Это характеризует более практический смысл понимания и упрощения дизайна.

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

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

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