Factories with Initialization

C# has a feature where instead of using explicit constructors, we are able to use filed initializers instead. For example: var ex = new Example { Field1 = ..., Field2 = ..., ... };

The purpose of this is to reduce the number of constructors a class needs. Alas, this presents a problem for Traceability. If we create a factory that constructs a functional object using an initializer, then we must copy the same initializers into the Traceable Factory as well: namespace FunctionalLayer.Factories { public class InitializedClassFactory { public virtual InitializedClass ConstructFromDataStream(DataStream stream) { return new InitializedClass { Field1 = ..., Field2 = ... ... }; } } }

The major problem with this is that, if the Functional Factory is updated, then the Traceable Factory must be updated in the same way as well. This is a large opportunity for maintenance issues to appear between the layers. namespace TraceableLayer.Factories { public class TraceInitializedClassFactory : InitializedClassFactory { public override InitializedClass ConstructFromDataStream(DataStream stream) { // this must be updated anytime the functional layer is changed. return new TraceInitializedClass { Field1 = ..., Field2 = ... ... }; } } }

One of the ways to avoid, or at least minimize, this issue is to place as much as the construction in the Functional Classes constructors as possible. This way, the Trace Class automatically gets any new construction logic.

Another way to handle this is to use automatic code generation to create the Trace Factory. That way any initialization list may be copied to the Trace Factory in a more reliable manner.

Post Construction Initialization

A less ideal way to handle this situation is initialize the fields after construction, assuming the class allows this to be done.

For example: namespace FunctionalLayer.Factories { public class InitializedClassFactory { public InitializedClass ConstructFromDataStream(DataStream stream) { var initializedClass = Construct(); // initialize from stream initializedClass.Field1 = ...; initializedClass.Field2 = ...; ... return initializedClass; } protected virtual InitializedClass Construct() { return new InitializedClass(); } } }

The Trace version returns to being a simple override of the Construct() call. namespace TraceableLayer.Factories { public class InitializedClassFactory : FunctionalLayer.Factories.InitializedClassFactory { private ITracer _tracer; public InitializedClassFactory(ITracer tracer) { _tracer = tracer; } protected override InitializedClass Construct() { return new TraceInitializedClass(_tracer); } } }

Factories with Wrapped Initialization Logic

We may have situations where the initialization functions generates chaff much like the Copy() method did as shown in Traceable Layer. The most likely reason for this to happen is that existing instance are being copied, or that values from existing Traceable objects are being used. In this case, we can follow the same pattern in the Copy() method, and wrap the initialization method to remove the chaff. namespace FunctionalLayer.Factories { public class InitializedClassFactory { public virtual InitializedClass ConstructFromDataStream(DataStream stream) { var initializedClass = Construct(); // initialize from stream return initializedClass; } protected virtual InitializedClass Construct() { return new InitializedClass(); } } } namespace TraceableLayer.Factories { public class InitializedClassFactory : FunctionalLayer.Factories.InitializedClassFactory { private ITracer _tracer; public InitializedClassFactory(ITracer tracer) { _tracer = tracer; } public override InitializedClass ConstructFromDataStream(DataStream stream) { _tracer.NewNode("IgnoreInitialization"); var initializedClass = base.ConstructFromDataStream(stream); _tracer.CloseAndRemoveNode(); return initializedClass; } protected override InitializedClass Construct() { return new TraceableLayer.Entities.InitializedClass(_tracer); } } }

Next: Factories For Returned Types

Copyright © 2017-2019 Adin H. Baber, all rights reserved.