Как правильно удалить / реорганизовать объявление «друга» зависимости?

Предпосылки этого вопроса основаны на практическом примере, где я хотел удалить зависимость «друг» из пары классов, которые используются для управления заблокированным доступом на чтение / запись к общему ресурсу.

Вот абстракция оригинального структурного проекта для этого сценария:

Помечено красным, есть эта уродливая «дружеская» зависимость, которую я хочу удалить из дизайна.

Короче, зачем мне эта штука там:

ClassAProvider делится ссылкой наClassA в течение ряда одновременного доступаClient экземплярыClient экземпляры должны получить доступClassA исключительно черезClassAAccessor вспомогательный класс, который управляет внутреннимиClassA скрывает все методы, предназначенные дляClassAAccessor как защищено.ТакClassA может гарантировать, чтоClient необходимо использоватьClassAAccessor пример

Этот шаблон в первую очередь полезен, когда речь идет о том, чтобы оставить экземплярыClassA в определенном состоянии, еслиClient операция выручает (например, из-за неперехваченного исключения). Думать оClassA предоставление (внутренне видимых) парных операций, таких какlock()/unlock() или жеopen()/close().

Операции реверсирования (состояния) должны вызываться в любом случае, особенно когда клиент падает из-за исключения.
Это может быть безопасно обработано черезClassAAcessorВ поведении жизненного цикла, деструктор реализации может обеспечить это. Следующая диаграмма последовательности иллюстрирует предполагаемое поведение:

ДополнительноClient экземпляры могут обеспечить точный контроль доступаClassA легко, просто используя блоки контекста C ++:

// ...
{ 
    ClassAAccessor acc(provider.getClassA());
    acc.lock();
    // do something exception prone ...
} // safely unlock() ClassA
// ...

Пока все хорошо, но «дружеская» зависимость междуClassA а такжеClassAAccessor должны быть удалены по ряду веских причин

В надстройке UML 2.2, раздел C.2 в разделе «Изменения по сравнению с предыдущим UML» говорится:The following table lists predefined standard elements for UML 1.x that are now obsolete. ... «friend» ...Большинство правил и руководств по кодированию, которые я видел, запрещают или настоятельно не рекомендуют использовать друга, чтобы избежать жесткой зависимости от экспортирующих классов для друзей. Эта вещь вызывает некоторые серьезные проблемы с обслуживанием.

Как говорится в заголовке моего вопроса

Как правильно удалить / реорганизовать объявление друга (желательно начиная с дизайна UML для моих классов)?

Ответы на вопрос(2)

Ваш ответ на вопрос