¿Cómo puedo eliminar / refactorizar una declaración de dependencia «amigo» correctamente?

Los antecedentes de esta pregunta se basan en una muestra práctica en la que quería eliminar una dependencia de "amigo" de un par de clases que se utilizan para administrar el acceso bloqueado de lectura / escritura a un recurso compartido.

Aquí hay una abstracción del diseño estructural original para ese escenario:

Marcado en rojo, existe esta fea dependencia de "amigo" que quiero eliminar del diseño.

En resumen, ¿por qué tengo esto aquí:

ClassAProvider comparte una referencia a unClassA sobre un número de acceso simultáneoClient instanciasClient las instancias deberían accederClassA únicamente a través delClassAAccessor clase auxiliar que gestiona las partes internasClassA oculta todos los métodos destinados a ser utilizadosClassAAccessor como protegidoEntoncesClassA puede asegurar queClient necesita usar unClassAAccessor ejemplo

Este patrón es principalmente útil cuando se trata de garantizar dejar instancias deClassA en un estado definido, si unClient la operación se rescata (debido a, por ejemplo, una excepción no detectada). Pensar enClassA proporcionando operaciones emparejadas (visibles internamente) comolock()/unlock() oopen()/close().

Las operaciones de reversión (estado) deberían llamarse en cualquier caso, especialmente cuando un cliente falla debido a una excepción.
Esto se puede manejar de manera segura a través deClassAAcessorEl comportamiento del ciclo de vida, la implementación del destructor puede garantizarlo. El siguiente diagrama de secuencia ilustra cuál es el comportamiento previsto:

AdicionalmenteClient las instancias pueden lograr un buen control de accesoClassA fácilmente, simplemente usando bloques de alcance C ++:

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

Todo bien hasta ahora, pero la dependencia de "amigo" entreClassA yClassAAccessor debe eliminarse por varias buenas razones

En la Superestructura UML 2.2, Sección C.2 bajo Cambios de UML anterior dice:The following table lists predefined standard elements for UML 1.x that are now obsolete. ... «friend» ...La mayoría de las reglas y pautas de codificación que he visto prohíben, o desaconsejan, usar un amigo, para evitar la dependencia de las clases de exportación a los amigos. Esto trae algunos problemas serios de mantenimiento.

Como dice el título de mi pregunta

¿Cómo puedo eliminar / refactorizar una declaración de amigo correctamente (preferiblemente comenzando en el diseño UML para mis clases)?

Respuestas a la pregunta(2)

Su respuesta a la pregunta