The former one is called a violation of the single responsibility principle :) Your User
class shouldn't know or care about the database. It is an anti-pattern, if anything.
There should be only one reason to change the User
class - and it is that the concept of user within your application may change.
Implementing LoadUserById
on the User
class means that you'd have to rewrite that class for totally unrelated reasons - such as switching from MySQL to PostgreSQL, for example, which has nothing to do whatsoever with the user as such. Such implementation details should be detached, externalized.
The latter one is more of a Repository pattern than Factory, I believe. UserRepository
could be a quite reasonable name for such a class.
Note that the role of a Factory is to create objects, especially whenever this task is complex and involves some advanced logic that you want to keep in one place.
Retrieving data from the database is a different responsibility. It's not about creating an object in itself - the real goal is obtaining data for that object (or "hydrating" it, as some insist).
Xml deserialization - at least in case of C# (you're not referring to it directly, but your links indicate it as your language of choice) - has type recognition built in. Why not make use of that?
See https://stackoverflow.com/questions/775647/how-do-i-deserialize-xml-without-knowing-the-type-beforehand for more details.
1: Make some super class that contains every possibility of contained
types.
As demonstrated in the question I linked to above, all it takes is creating some common base class for your errorMessage
objects. Then you need to use XmlInclude
.
So the super class would only have to "contain every possibility" in the sense of knowing about all its subtypes (but not their implementation details). It's still all nice and neat in terms of OOP.
Note that if you feel that .NET serialization is too limiting, there's always more sophisticated alternatives such as SharpSerializer - better suited for polymorphic scenarios.
Again, this is not a language-agnostic suggestion, but if you used another programming language, the advice still applies: you can look for a good open-source library.
2: Make some mechanism for reading the xml first to identify what's in it.
You could also use reflection and retrieve the type in run-time (as Kirtan suggested) by the name of the root element, or some attribute of the root element.
Another option would be to create, or generate, XSD schemas for your errorMessage
items, then use these schemas to validate the incoming messages - thus establishing their "type identity".
One advantage of this admittedly a bit more troublesome solution is that if the incoming xml was somehow broken, xsd validation could tell you exactly where and why (eg. some unexpected, unrecognized element), you don't have to handle this "manually".
Then there's dynamic typing and yet another interesting approach:
https://stackoverflow.com/a/13705918/168719
A more elegant approach would be to implement some kind of Action
pattern, where, once the object was identified you could create the
proper action to take with it.
That's what takes place after you deserialize the message, doesn't it?
With regard to this, I don't think one could come up with suggestions superior to what you have already found in this thread: https://stackoverflow.com/questions/298976/is-there-a-better-alternative-than-this-to-switch-on-type
I hope this gives you some inspiration. If not, the principle I go by is: when it's awfully hard to solve a problem, most likely the problem itself is badly posed from the very beginning. So if you are stuck, maybe it's time to step back and redesign. I don't know broader context, so I have no way of knowing how possible it is in your case.
Best Answer
The Factory Pattern allows objects having different types but conforming to the same interface to be created, the specific type which is created being based on some condition. Seems particularly appropriate here.
So create some static methods with different overloads that each accept a different parameter signature and return the appropriate object (polymorphism), or create a single static method and put a
switch
statement in it that switches over a method parameter and returns the appropriate object.ICDRInterface
implementations:Usage: