Хорошая идея сделать объекты-члены композиции публичными? - PullRequest
0 голосов
/ 17 февраля 2019

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

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

Вот дом верхнего уровня с субмодулями кухня и ванная.

// Public member objects
class Kitchen {
public:
    void turn_on_tap();
    int compute_area();
};
class Bathroom {
public:
    void turn_on_tap();
    int compute_area();
};
class House {
public:
    Kitchen kitchen;
    Bathroom bathroom;
    int compute_area() { return kitchen.compute_area() + bathroom.compute_area(); }
};

//User code:
House house;
house.kitchen.turn_on_tap();
house.bathroom.turn_on_tap();
house.compute_area() // OK
house.bathroom.compute_area(); // may not want user to be able to do this

// Private member objects
class House {
    Kitchen kitchen;
    Bathroom bathroom;
public:
    void turn_on_kitchen_tap() { kitchen.turn_on_tap(); }
    void turn_on_bathroom_tap() { bathroom.turn_on_tap(); }
    int compute_area() { return kitchen.compute_area() + bathroom.compute_area(); }
};

//User code:
House house;
house.turn_on_kitchen_tap();
house.turn_on_bathroom_tap();
house.compute_area();

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

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

РЕДАКТИРОВАТЬ: Но если я сделаю их общедоступными, я открою другие общедоступные функции бэкэнда в Кухне и Ванной, которыеЯ не обязательно хочу, чтобы пользователь был в курсе.Тогда мне, возможно, придется сделать это частным и использовать «друга», что немного уродливо.

Добавлен compute_area () к приведенному выше коду.

1 Ответ

0 голосов
/ 17 февраля 2019

Это зависит.Если дом представляет собой простой агрегат, например:

  1. Допустимое значение House - это любая комбинация действительных значений Kitchen и Bathroom.То есть, нет House конкретного инварианта для хранения.

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

  3. Функции-члены контейнера представляют собой крошечные обертки вокруг каждого компонента или даже просто возвращают ссылку на компонент для модификации.

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

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

...