Factories with Initialization

If the factory is going to handle the actual initialization of the object, then we take a slightly different approach. We want to separate the construction from the initialization, which in turn allows us to reuse the initialization code in the Logging Layer. If there is no need to ever construct the class outside of the factory, then we may even make the Construct() call protected. namespace FunctionalLayer.Factories { public class InitializedClassFactory { public InitializedClass ConstructFromDataStream(DataStream stream) { var initializedClass = Construct(); // initialize from stream ... return initializedClass; } protected virtual InitializedClass Construct() { return new InitializedClass(); } } }

Note that ConstructFromDataStream() is not virtual. Since we want to use the same initialization sequence in both layers, we don't have any need to override it.

Now, all we need to do to implement the Logging Layer factory is add the ILogger and LoggingContext properties and override the Construct() call. namespace LoggingLayer.Factories { public class InitializedClassFactory : FunctionalLayer.Factories.InitializedClassFactory { private ILogger _logger; private LoggingContext _context; public InitializedClassFactory(ILogger logger, LoggingContext context) { _logger = logger; _context = context; } protected override InitializedClass Construct() { return new LoggingLayer.Entities.InitializedClass(_context, _context); } } }

When ConstructFromDataStream() is called, the Logging Layer factory will still use the initialization code, but will instead produce a Logging object. Once again, inheritance saves us an enormous amount of work.

What makes this pattern even more enticing is that the Functional Layer factory could have several more initializing functions, but if they all used the same Construct() call, then the Logging Layer factory would not change from above. namespace FunctionalLayer.Factories { public class InitializedClassFactory { public InitializedClass ConstructFromDataStream(DataStream stream) { var initializedClass = Construct(); // initialize from stream ... return initializedClass; } public InitializedClass ConstructFromDifferentDataStream(DifferentDataStream stream) { var initializedClass = Construct(); // initialize from stream ... return initializedClass; } public InitializedClass ConstructFromYetAnotherDataStream(YaDataStream stream) { var initializedClass = Construct(); // initialize from stream ... return initializedClass; } protected virtual InitializedClass Construct() { return new InitializedClass(); } } } namespace LoggingLayer.Factories { public class InitializedClassFactory : FunctionalLayer.Factories.InitializedClassFactory { // exactly the same as prior Logging factory example } }

Next: Factories For Returned Types