MATLAB has two ways of organizing classes:
@-directories:
@ClassName\
ClassName.m
Method1.m
Method2.m
Single files:
ClassName.m:
classdef ClassName
methods
% all methods included here
end
end
The first style existed before the new classdef
syntax, but seems to be a more structured way of doing things. The second style (everything in a single file) is new.
Which method do you use, and why?
The new single-file style has some advantages. It allows and encourages you to write lots of small methods, which I think leads to better-factored code. The hassle of creating a new file, saving it, and adding it to source control (we are all using source control, right?) is minor, but added up over a couple dozen little methods is enough that it usually discourages me from factoring a class into finer-grained bits of functionality. And editing the whole of your class is convenient for browsing, search and replace, and not having to open a dozen separate editor tabs, which can then be used to organize source code for different classes.
For larger codebases, there may be performance advantages to the single-file style. Source control and deployment systems that iterate over the source tree have a per-file cost for things like stat and diff operations. For a larger codebase, say, thousands of methods, that can be significant, especially on a network drive. I suspect there's also a performance effect for apps deployed with the Matlab compiler. Startup time increases with the size of the deployed codebase. There is a per-file part of this cost, from file operations, and because the files (I think) are encrypted individually. I suspect, but have not experimentally tested, that using single file class definitions will reduce the startup cost for compiled Matlab apps.
However, I use the old multi file organization for most of my code. Partly because our codebase was started a few years back before the new style was commonly available. But partly for performance. The new single file organization only works with the new style MCOS Matlab classes, and they are slower than old style Matlab classes due to a higher method dispatch overhead. E.g. here's a benchmark snippet showing execution time of do-nothing nop() methods.
Calling each function/method 100000 times
nop() function: 0.02715 sec 0.27 usec per call
nop(obj) method: 0.24629 sec 2.46 usec per call
classdef nop(obj): 0.98572 sec 9.86 usec per call
classdef obj.nop(): 1.81307 sec 18.13 usec per call
In a codebase that makes lots of method calls, this can have a significant performance impact.
(See also Is MATLAB OOP slow or am I doing something wrong?)
One other nit is that Matlab's auto-indenter will indent every section and every method in a class definition, so the baseline of all your executable code is two tab stops in, wasting 8 columns of screen real estate.
On balance, were it not for OO performance considerations, I'd probably go with single file, and I'm writing new non performance critical classes that way.
UPDATE: It also looks like contentsrpt(), a useful documentation generator, does not work with functions defined inside the classdef file; only those in separate function files.
I've found the @-directories
to be a kludge (e.g. public/private, what's that?) that is best forgotten. In the most recient versions (since 2007b, I believe), the best way to organize your classes is with packages. This gives a much cleaner namespace. I think working with the entire class in one file makes it a lot easier to get a sense of what the class is doing, and 1000% less annoying when it comes to refactoring (imagine changing 8 files after changing a variable name).
I use the single file method. I find it somewhat easier to organize the code when it consists of a single file, and cell titles make it very easy to jump around between methods. Also, if I create a new @-class, I might need to recreate the path before being able to use it, and I don't have the patience for that.
Having said all that, I do not think that the single-file style is much better than the multi-file style; having lots of small, easy-to-look-through files might be very useful as well.
The advantage of using the @ClassName directory is that matlab forces you to clear and reload a class if you make any changes to the classdef file. If you put the implementation of functions in separate m files and just put the method signatures in the classdef file, you can muck around with the implementation without having to clear the class.