Posts

Showing posts from January, 2024

Decent First Drafts

Let's say that you are implementing a Composite pattern for an interface with several interface functions. For functions which return void, it's straightforward to anticipate that the implementation will be a simple for_each. For functions which return a value, something has to be done to convert multiple return values into one. There are several obvious patterns: - For functions like size() you call accumulate/fold_left and return an accumulated value.  This can't be extended arbitrarily to functions returning a numeric type: you might want, for example, to return a maximum value. - For functions which return a boolean status, you return the results of applying std::none_of to a test for a false return, std::all_of to a test for a true return. - For functions generating a string representation you return a string concatenating outputs with interpolated delimiters and possibly a beginning and ending. The same applies as a special case of output functions which return void b...

From Template Method to Delegation

Here is a mildly interesting refactoring from a use of the GoF Template Method to a use of delegation injected into a parent class. In determining the Lauds and Vespers hymns on a seasonal basis, most are straightforward and do not vary by Use: Roman and Sarum uses agree, and the hymns are the same throughout the season.  But for days during Ordinary Time these vary by day of week and in one of the two periods of Ordinary time the Roman and Sarum uses do not agree: Roman use uses the same pattern as during the other period, but Sarum use uses one hymn per office for the whole  season (which is the same as the Roman Sunday hymn). The original solution to this was to use a form of the GoF Template Method pattern. A switch statement which generally returns fixed values has four functions it calls for the relevant cases:   switch (inOffice)     {       using enum OfficeNames;     case COMPLINE:       return ComplineChapter::Ge...