See
SyntacticallyTransparentRefactorings.
(This thought arose in a newsgroup conversation with
AndreiAlexandrescu.)
Languages like
CeePlusPlus and
JavaLanguage distinguish syntactically between member functions
and free functions.
E.g.
class Number {
private:
int data;
public:
Number addMember(const Number& that) const {
Number ret;
ret.data = this->data + that.data;
return ret;
}
friend Number addFree( const Number& left, const Number& right );
}
Number addFree( const Number& left, const Number& right ) {
Number ret;
ret.data = left.data + right.data;
return ret;
}
These two functions are pretty much equivalent, except for syntax:
Number N1, N2, N3;
N1 = N2.addMember(N3);
N1 = addFree(N2,N3);
There are some C++ language specific issues involving conversions.
Most importantly, however, the member function has access to all
private data of the class, whereas the free function may be implemented
using private data (via friend) or by using public accessors.
The free function may be DENIED access to private data.
(
ExtremeProgrammers may not be so sure about the usefulness
of
PrivateData - it impedes refactoring - but if you buy into private,
not having privae is bad.)
If you wish to preserve syntax across refactorings that make things
public and private, you should start off with
FreeFunctions.
But that's almost as painful as using setters/getters everywhere.
MemberFunctions can be denied access to implementation details
by using the pimpl,
PrivateImplementation, pattern.
Moral: languages should not distinguish members and free functions
syntactically.
FreeFunctions can be defined as members (or friends.)
This is an implementation issued for the
ObserverPatternInCeePlusPlus.
CategoryCpp CategoryJava CategoryProgrammingLanguage