Single Template Method

- ConcreteClass has to subclass the entire AbstractClass
- The ConcreteClass has to include any AbstractClass dependencies
- For each abstract method, ConcreteClass must provide a definition
Multiple Template Methods

- What about if there is more than one template method?
- ConcreteClassA has to implement all AbstractClass abstract methods, i.e.,
primitiveOperationA1()
, primitiveOperationA2()
, primitiveOperationB1()
, and primitiveOperationB2()
, even if only interested in templateMethodA()
- Similarly for ConcreteClassB
- Only class this works fine for is ConcreteClassAB
Another Issue

- PDFReader has a dependency on PDFFormatLibrary
- CountArticles derived from PDFReader and (indirectly) has all of PDFReader's dependencies
- What if we don't want CountArticles to depend on PDFFormatLibrary?
Goal
- Separate primitive operations for a particular purpose from the rest of the class interface allows for decoupling of the rest of class
- Subclass the set of primitive operations instead of the entire class
- Reduces coupling and has multiple template methods
Solution

Solution

- AbstractHandler has only essential dependencies for the interface and does not have the dependencies of the MainClass
- ConcreteHandler is derived from AbstractHandler, so it does not share the dependencies of MainClass
Solution: Class Structure
Multiple Handlers

Standard Handlers

- Can provide standard, off-the-shelf handlers
- Clients can pick these or even further subclass them
- Users can even create their own sets of off-the-shelf handlers
Advantages
- Replaces subclassing a large, complex class with subclassing a cohesive interface
- Handlers are almost always all pure virtual or empty methods
- The only dependencies that handlers have are for parameters and return types
- Allows multiple types of handlers, which the design can mix in new ways
- Allows standard handlers to be created and shared
- Easier to test, as can test individual handlers
Template Method Includes

DockerReport: Template Method & Handler Comparison


Handler Includes

Decoupling YAMLParser

Decoupling YAMLParser

Decoupling YAMLParser
ParserEngine
can be a free function, a static method of a class, a method of a class, or even part of a framework
- The implementation of
ParserEngine
(i.e., .cpp
files) are the ones that use YAMLParser
- The interface of
ParserEngine
(i.e., .hpp
files) does not use or include YAMLParser
and is completely decoupled from YAMParser
- The interface of
ParserEngine
(i.e., .hpp
files) does use YAMLParserHandler
as a parameter