On Sunday, 20 April 2014 at 07:11:41 UTC, Lars T. Kyllingstad
wrote:
In his article "How non-member functions improve encapsulation"
[1], Scott Meyers makes a good argument for why free functions
should generally be preferred over class methods in C++.
TL;DR: Fewer member functions means fewer functions that break
when the class implementation changes, and free functions can
be spread across different header files, allowing client code
to only #include the ones that are needed.
In D, the situation is somewhat different. Firstly, private
symbols are accessible throughout the module within which the
class/struct is defined, and secondly, UFC allows us to call
free functions using the same syntax as member functions. In
other words, *any* non-virtual function could in principle be
written as a free function.
The fact that "private" really means "module private" in D
means that any number of functions can break when a
class/struct implementation changes. So if we are to take
Meyers' advice, we have to define a new module for each
class/struct, and move its associated free functions to
neighbouring modules. However, this would lead to a
proliferation of modules that I doubt anyone would want.
So, can anyone think of some good guidelines for when to make a
function a member, when to write it as a free function in the
same module, and when to move it to a different module?
[1]
http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197
This is a quote from Walter that sums the reasoning up perfectly:
"A huge reason for them is to head off the temptation to write
‘kitchen sink’ classes that are filled with every conceivable
method. The desired approach is to have the class implement the
bare minimum of functionality, and add other functionality with
extension methods (that do not have access to the class’ private
state)."
Writing classes like this allows for better encapsulation because
only the required behaviour is contained within the class keeping
it focused. Other methods that are useful for the class (but
don't really belong in the class) can be implemented as non
member function and if written in a generic way be reused
throughout the program.