Как инкапсулировать данные при наличии класса менеджера

0

Здравствуй,

У меня есть класс под названием "Диспетчер", который управляет (создает, удаляет, изменяет и т.д.) Несколько экземпляров класса Element. Класс Element - очень простой класс (только контейнер данных).

class Manager
{
public:
    void add_element(ElemKey key);
    const Element *get_element(ElemKey key);

private:
    container<Element> my_elements;
};

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

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

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

void something_happend_to_elem_do_something(Element *elem, ...);

Проблема заключается в том, что пользователь получил указатель const, а не указатель, поэтому мне или ему нужно const_cast его. Если я это сделаю, пользователь может не понимать, что происходит, потому что даже если он дал const *, метод изменил объект. Кроме того, это, по-видимому, плохой подход.

Я подумал о других методах решения этого вопроса: 1. Элемент можно изменить на:

class Element {
public:
    int get_a();
private:
    int a;
};

И класс менеджера может быть другом Элемента, так что только он может его изменить. Теперь я могу удалить константу из диспетчера :: get_element

  1. Элемент может быть изменен на:

    class Element {public: virtual ~ Element() {} virtual int get_a() = 0; };

Внутри файла cpp manager будет создан еще один класс под названием ElementImpl, который только он знает с данными в нем, поэтому только он может его изменить. Как и раньше, я могу удалить константу из диспетчера :: get_element

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

Что вы, ребята, думаете?

Теги:
oop

1 ответ

0

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

class Proxy {
   public:
   Proxy(Element& e) : e(e) {}
   void modification() { e.modification(); } 
   private:
   Proxy(const Proxy&);
   Proxy& operator = (const Proxy&);
   Element& e;
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню