Until recently, I never really took the time to investigate the reason why the CSLA uses the factory pattern to create business object, so I was happy to see that this reasoning is explained in the latest eBook.
From what I am able to tell (based on the eBook info), the decision to use the factory pattern appears to be heavily influenced by two things:
1) Simplifies the UI Code.
2) Eliminates the amount of plumbing code.
I think the first point is a strong point, and it justify using either the “object in charge” or “class in charge” methods.
The second point however seems weak to me, and it does not really justify favoring the “class in charge” method over the “object in charge” method and here is why, take a look at the code below:
public class Customer : BusinessObject
// A make believe CSLA business object function
// that copies the state of a retrieved customer
// object to the current instance.
The code above shows the object capable of being instantiated via a constructor (object in charge). Internally, the constructor leverages the current implementation of “class in charge” method. In short, the code retrieves the object using “class in charge” and transfer the state found on that object to the current object using my make-believe “CopyState” method. The “CopyState” method basically iterates through all the variables on the object (including collection variables) and copies them to the current object.
The result is an object that can be instantiated using the familiar constructor (“object in charge” method) with no more code that what it would normally take if the “class in charge” method was used.
So, I feel like there should be more compelling arguments justifying why factory methods are used throughout the CSLA and I think I may have some……
Let’s take a look at the following “object in charge” method instantiation example:
var x = new Customer(123);
The problem with the statement above is that it can be ambiguous. What exactly are we trying to do with the statement above?
· Are we trying to create a new customer with a default id of 123?
· Are we trying to retrieve a customer with an id of 123?
· What if need the ability to do both, create and retrieve a customer using the same constructor signature?
To me, this is where the factory methods shine. They give us the ability to create object construction directives that are semantically accurate. In other words, there is not ambiguity between “Customer.NewCustomer(123)” and “Customer.GetCustomer(123)”.
So, the point of my post is that in the unlikely event that you agree with me J, I would add the semantics benefit provided by using factory methods as another compelling reason to go the factory way, because the ones that are listed right now on the eBook don’t seem to carry too much weight, at least not on my head.
There've been several discussions over the past decade on the value of in-place serialization schemes. And there is a very real value to doing this, but the problem is that it means discarding the entire serialization model provided by Microsoft and creating an alternative.
Serialization/deserialization is a copy process - you end up with a new object instance. By itself this is just a tool (look at MobileFormatter for example) that can be used in many different ways.
But you always must consider that any solution needs to apply to an object graph, not just an object. This particular problem area is pretty trivial to solve for an object. It is not trivial to solve for an object graph, especially when objects have no universal concept of identity.
Take a list of objects, serialize it and deserialize it. Now tell me which of the copied objects equates to which of the original objects. There's no absolute solution to this problem. Suppose the deserialization process changed the order of the items in the list (which can happen). So you can't use ReferenceEquals, you can't use absolute ordering of objects, and you can't use logical equality (since in the general case two of the original objects could have had the same property values).
I'm not saying the problem can't be solved. I'm saying that the solution is non-trivial, and requires the invention of a universal identity mechanism for all objects in every object graph.
If you look at the DiffGram sample app you can see that this is exactly what I did for that sample. I imposed a construct over every object in the graph that requires a universal identity for each object - thus allowing for in-place serialization of data.
I wouldn't mind doing this in CSLA - except that it would be a breaking change beyond any breaking change I've ever imposed. Basically no existing CSLA code would move forward - nor would any UI code built on existing objects. In short, it would be a new framework with a lot of similarities to the existing framework.
That's not a step I have yet been willing to take.
Copyright (c) Marimer LLC