How to: ClassFactory?

M

matthias s.

Hi there,

I'm working on a class library. The class library contains a couple of
public classes which should serve as class factories and I'm wondering
how to implement this strategy correctly.

Let me explain using a simple example: I've got a class called
SecureUserFactory and another one called SecureUser. The user of my
class library should not be able to instanciate SecureUser objects as
stand alone objects, but should be forced to call a method like
SecureUserFactory.GetSecureUser(...).

This is done because the class factory is implementing a caching/object
reuse mechanism (planned to be used in WebApps).

Can somebody share his/her experiences?

Thanks in advance!

/matthias
 
J

Jon Skeet [C# MVP]

I'm working on a class library. The class library contains a couple of
public classes which should serve as class factories and I'm wondering
how to implement this strategy correctly.

Let me explain using a simple example: I've got a class called
SecureUserFactory and another one called SecureUser. The user of my
class library should not be able to instanciate SecureUser objects as
stand alone objects, but should be forced to call a method like
SecureUserFactory.GetSecureUser(...).

This is done because the class factory is implementing a caching/object
reuse mechanism (planned to be used in WebApps).

Can somebody share his/her experiences?

Just make the constructor of SecureUser internal; that way no classes
outside your assembly will be able to create instances of SecureUser.
 
N

Nick Malik [Microsoft]

From what you say, you are implementing this pattern correctly.

The goal of the factory class is simply to seperate the concerns between
creation and use of an object. You have done that.

I would add one thing. In my experience, factory methods are often
implemented as static methods in a class. This is completely appropriate if
there is NEVER any way that you would want to derive a sub-class of the
factory itself. Think about it carefully, and use a static method to
implement the SecureUserFactory.GetSecureUser(...) call only if you, or the
users of your class, will never need to create an Abstract Factory.

That doesn't mean that I don't declare any factory methods as static. On
the contrary... I often do. However, I think about it each time.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
 
J

Jonathan Allen

I have found that Class Factories are, generally speaking, a needless
complication. I worked for a company that got to the point where they had
class factories for their class factories. And more often than not, the
underlying class was every simple.

Besides making it harder to use, the maintenance story was a nightmare.
Every time a field was added/changed in the class, its factory had to be
updated as well. And since we were using Java, so did all the interfaces.
Add J2EE, and you need an extra remote and local interface for every
aforementioned class, factory, and interface. (yea, I'm bitter)

My suggestions:

0. You do you need special, shared information for your class. For example,
a connection string to the database where the user data is stored. In that
case, create a Connection class that either creates the SecureUser objects
or can be passed to the constructor for SecureUser.

If that isn't the case, then you have two options.

1. If the class is meant to be used both with and without the factory, then
it makes sense to use a factory. But don't call it SecureUserFactory. Give
it a name that reflects what it does, why you should use it instead of
creating the class directly. Say, SecureUserCache.

2. If you intend for the class to never be created directly, then don't
bother making a class factory. Include any code that you would have put in
the factory in the class itself as a static.
 
G

Guest

I can't really say as to the appropriateness of a given design pattern (of
which of course a class factory is), but I found an excellent reference for
those of you who want to see both theory and real implementation code (their
code is in C#):

http://www.dofactory.com/Patterns/Patterns.aspx#list

I'm not affiliated, but it seems to cover the gambit of basic design
patterns, in fairly easy to understand language.

Ciao,
mcse3010
 
M

Michael S

I've read what Nick and Jon wrote but this thread sums it up...
I'll inline my 2 cents...

Jonathan Allen said:
I have found that Class Factories are, generally speaking, a needless
complication. I worked for a company that got to the point where they had
class factories for their class factories. And more often than not, the
underlying class was every simple.

Yep. Not to mention that the factories for the factories are typically are
loaded at runtime via some obscure config file in xml. Really. How often do
we interchange our classes? I would say almost never, and if so, it it
easier to let Visual Studio (or eclipse or X or Y) ensure type safety while
compiling classes, than browsing through thousands of xml-lines to map a
class-name to an interface that won't be checked until runtime.

Yuk!
Besides making it harder to use, the maintenance story was a nightmare.
Every time a field was added/changed in the class, its factory had to be
updated as well. And since we were using Java, so did all the interfaces.
Add J2EE, and you need an extra remote and local interface for every
aforementioned class, factory, and interface. (yea, I'm bitter)

This is why I don't endorse Java and their fanatic trust in patterns.

We have a abstract factory (1 file) that gives an interface to the actual
factory (1 interface, 1 class) that returns an interface for a class (2 more
files) loaded at runtime. Now this is five files plus a classloader and an
xml-file of highly interconnected code. What happened to encapsulation?

In Java, I see people go heads over heals to solve small problems. What I've
also found is that the people who are most inclined in supporting J2EE have
little or no experience in maintainance. They make their world overly
complex without thinking about complexity. And we get to clean their
laundry.

Isn't J2EE supposed to be Agile? What happened to the YAGNY principle? - Yo
Ain't Gonna Need It.

Be bitter Jonathan; it's a sign of mental health! =)
My suggestions:

0. You do you need special, shared information for your class. For
example, a connection string to the database where the user data is
stored. In that case, create a Connection class that either creates the
SecureUser objects or can be passed to the constructor for SecureUser.

Smells like VB-style of doing things. But I realize that this is not what
you propose we do...
If that isn't the case, then you have two options.

1. If the class is meant to be used both with and without the factory,
then it makes sense to use a factory. But don't call it SecureUserFactory.
Give it a name that reflects what it does, why you should use it instead
of creating the class directly. Say, SecureUserCache.

I totally agree. Whenever I find my self naming a class ending with factory
I stop and ponder:
- Am I doing real code here or just implementing yet another pattern? What
is this class supposed to do?
After some analysis I usually wind up renaming the class or removing it
completely...
2. If you intend for the class to never be created directly, then don't
bother making a class factory. Include any code that you would have put in
the factory in the class itself as a static.

... for this strategy. I suspect this scheme is what you was getting at all
along.

Thingy myThingy = new Thingy(); // explicit instance.
Thingy myThingy = Thingy.Create(); //method implies class factory
Thingy myThingy = Thingy.Instance; //property implies singelton

Let the class know how to instanciate itself. What I love with .NET is that
it reinforces the concept of classes.
Let interfaces be general like IStream, specific like IDisposable or
interchangable as IXmlNode, but don't map interfaces straight to classes.

For me this is pure .NET. And what seperates C# from Java. Different idioms.
Different cultures.
Me myself and I have found that the .NET culture don't make me feel bitter.
=)

Happy Coding
- Michael S
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top