The background of this question is based on a practical sample where I wanted to remove a «friend» dependency from a pair of classes that are used to manage read/write locked access to a shared resource.
Here's an abstraction of the original structural design for that scenario:

Marked in red, there's this ugly «friend» dependency I want to remove from the design.
In short, why do I have this thing there:
ClassAProvider shares a reference to a ClassA over a number of
concurrently accessing Client instancesClient instances should access ClassA solely through the ClassAAccessor helper class
that manages the internalsClassA hides all methods intended to be used from ClassAAccessor as protected.ClassA can ensure that Client needs to use a ClassAAccessor instanceThis pattern comes primarily useful, when it's about ensuring to leave instances of ClassA in a
defined state, if a Client operation bails out (because of e.g. an uncaught exception). Think of
ClassA providing (internally visible) paired operations like lock()/unlock() or open()/close().
The (state-)reversing operations should be called in any case, especially when a client crashes due
to an exception.
This can be safely handled through the ClassAAcessor's life cycle behavior, the destructor
implementation can ensure it.
The following sequence diagram illustrates what's the intended behavior:

Additionally Client instances can achieve a fine control of accessing ClassA easily, just using
C++ scope blocks:
// ...
{
ClassAAccessor acc(provider.getClassA());
acc.lock();
// do something exception prone ...
} // safely unlock() ClassA
// ...
All fine so far, but the «friend» dependency between ClassA and ClassAAccessor should be removed for a number of good reasons
The following table lists predefined standard elements for UML 1.x that are now obsolete. ... «friend» ... As my question title says
How can I remove/refactor a friend declaration properly (preferably starting out at the UML design for my classes)?
friend Function in C++ A friend function can access the private and protected data of a class. We declare a friend function using the friend keyword inside the body of the class.
The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.
Without the help of any object, the friend function can be invoked like a normal member function. Friend functions can use objects of the class as arguments. A friend function cannot explicitly access member names directly. Every member name has to use the object's name and dot operator . .
Benefits of friend function A friend function is used to access the non-public members of a class. It allows to generate more efficient code. It provides additional functionality which is not normally used by the class. It allows to share private class information by a non member function.
Let's setup some constraints for refactoring first:
Step 1: Introduce an abstract interface
For a first shot, I factored out the «friend» stereotype, and replaced it with a class (interface)
InternalInterface and the appropriate relations.

What made up the «friend» dependency, was split up into a simple dependency relation (blue) and
a «call» dependency (green) against the new InternalInterface element.
Step 2: Move the operations, that make up the «call» dependency to the interface
The next step is to mature the «call» dependency. To do this, I change the diagram as follows:

ClassAAccessor to the InternalInterface (I.e. ClassAAccessor contains
a private variable internalInterfaceRef).ClassA to InternalInterface.InternalInterface is extended with a protected constructor, that it's useful in inheritance
only.ClassA's «generalization» association to InternalInterface is marked as protected,
so it's made publicly invisible.Step 3: Glue everything together in the implementation
In the final step, we need to model a way how ClassAAccessor can get a reference to InternalInterface. Since the generalization isn't visible publicly, ClassAAcessor can't initialize it from the ClassA reference passed in the constructor anymore. But ClassA can access InternalInterface, and pass a reference using an extra method setInternalInterfaceRef() introduced in ClassAAcessor:

Here's the C++ implementation:
class ClassAAccessor {
public:
ClassAAccessor(ClassA& classA);
void setInternalInterfaceRef(InternalInterface & newValue) {
internalInterfaceRef = &newValue;
}
private:
InternalInterface* internalInterfaceRef;
};
This one is actually called, when the also newly introduced method ClassA::attachAccessor()
method is called:
class ClassA : protected InternalInterface {
public:
// ...
attachAccessor(ClassAAccessor & accessor);
// ...
};
ClassA::attachAccessor(ClassAAccessor & accessor) {
accessor.setInternalInterfaceRef(*this); // The internal interface can be handed
// out here only, since it's inherited
// in the protected scope.
}
Thus the constructor of ClassAAccessor can be rewritten in the following way:
ClassAAccessor::ClassAAccessor(ClassA& classA)
: internalInterfaceRef(0) {
classA.attachAccessor(*this);
}
Finally you can decouple the implementations even more, by introducing another InternalClientInterface like this:

It's at least necessary to mention that this approach has some disadvantages vs using friend declarations:
friend doesn't need to introduce abstract interfaces (that may affect the footprint, so constraint 3. isn't fully fulfilled)protected generalization relationsip isn't well supported by the UML representation (I had to use that constraint)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With