Posts

Showing posts from October, 2023

Enums and classes

One general piece of advice which I sometimes see is to avoid enums entirely and instead prefer the use of classes to represent what would otherwise be enum values. (This is not meaningful in Java where enums are classes with full extensibility.) Instead of enum class OfficeNames { LAUDS = 0, PRIME = 1, TERCE = 2, SEXT = 3, NONE = 4, VESPERS = 5, COMPLINE = 6 }; one would define an abstract class as a parent: class OfficeName { virtual ~OfficeName(); }; and then implement a set of inheriting concrete classes, which should be stateless: class LaudsName: public OfficeName { ~LaudsName() override; }; // etc. Even if you don't have any virtual functions which do something, this makes it impossible to cast an integer directly to the enum type (which can create surprises in handling what you may think is a strictly limited set of values). The bigger driver of the advice is that it allows the removal of switch statements. Instead of: void MyClass::performUpdate(con...

Function sizes

Having expressed my discomfort with the idea of a fixed function size, what do  I think should be the maximum size of a function? First of all, counting semicolons is pointless. There is no difference in essentials between. foo(generateX().createParam()); and auto x = generateX(); auto param = x.createParam(); foo(param); other than the greater scope in which the two temporary variables live. (I note that many developers tend to be more comfortable with the latter. I see much more of  int n = std::accumulate(...); process(n, param2); //n not used further than I do of process(std::accumulate(...),    param2); in general code.) There is an obvious outer limit on a normal maximum size: too large to be seen on one screen. We will allow the screen to be that of a large monitor. However, even that has its exceptions. Assume that you have received a message from an external source and that the type is expressed as a string. Based on that type we create a new message object...

Thoughts on Refactoring and Design: Five Lines

One (very decent) book on refactoring has the title Five Lines of Code in which five lines is taken as the upper limit on a function (where five means "count semicolons and control statements"). In addition, it has two rules which tightly restrict what those five lines can be: 1) Only one if statement per function, at the top of the function. This statement would be the "one thing" that function does. 2) No if plus else, or switch, controls for data one has control over (i.e. part of one's own source and not from a standard or third-party library). Instead, late bindings using polymorphism are prescribed. A corollary of this is the elimination of enums in favour of substantive classes (except in languages like Java, where enums are substantive classes). The author does note that the number five might vary a bit by domain. You can certainly do this in C++ -- the TypeScript examples are easily convertible to C++ -- but it may be worth putting forward some concer...