How to protect the integrity of the data structure when invoking external logic through observers?

I am currently reorganizing an application in which classes can call observers if their state changes. This means that observers are called whenever:

  • data in an instance that changes class
  • new class instances are created
  • class instances are deleted

This last case makes me worried.

Suppose my class is a book. Observers are stored in the BookManager class (BookManager also stores a list of all books). This means that we have this:

class Book
   {
   ...
   };

class BookManager
   {
   private:
      std::list<Book *> m_books;
      std::list<IObserver *> m_observers;
   };

If the book is deleted (removed from the list and deleted from memory), the observers are called:

void BookManager::removeBook (Book *book)
   {
   m_books.remove(book);
   for (auto it=m_observers.cbegin();it!=m_observers.cend();++it) (*it)->onRemove(book *);
   delete book;
   }

The problem is that I do not control the logic in the observers. Observers can be delivered by the plugin according to the code written by the developers at the customer.

, ( , ):

auto itNext;
for (auto it=m_books.begin();it!=m_books.end();it=itNext)
  {
  itNext = it:
  ++itNext;
  Book *book = *it;
  if (book->getAuthor()==string("Tolkien"))
     {
     removeBook(book);
     }
  }

, :

void MyObserver::onRemove (Book *book)
   {
   if (book->getAuthor()==string("Tolkien"))
      {
      removeAllBooksFromAuthor("Carl Sagan");
      }
   }

, , , , , , , (itNext) .

, , .

, , , , , , , , , .

, , ( ), .

[] , ? , , .

+3
1

, ( ), .

:

  • . , , , (/ ), . , , .
  • , . , Observer, , . , , .

delete BookManager, :

  • , , "". ( 2 ) .
  • "" . , , .
  • 'deleted'.

BookManager.

+1

Source: https://habr.com/ru/post/1772736/


All Articles