У меня есть класс верхнего уровня, который создает субмодули с помощью композиции.Пользователь знает, что у высшего класса будут эти подмодули.Является ли хорошей идеей сделать объекты подмодуля общедоступными членами, чтобы пользователь мог напрямую вызывать их функции?
Возможно, альтернативой является оборачивание вызовов их функций, которое защищает подмодули от обнародования, но нене имеет никакого преимущества в инкапсуляции, так как пользователь все равно должен указать субмодуль.
Вот дом верхнего уровня с субмодулями кухня и ванная.
// 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 () к приведенному выше коду.