Greg
Greg

Reputation: 121

Factory Pattern Advice Needed Please

I'm working on wrapping my head around the factory pattern by using it in a simple data storage project in my free time. The idea is to take simple data and save it to a database using a simple factory pattern in VB.NET. I think I have a basic understanding of the pattern itself, however, what I'm struggling with is how to fit the factory classes into the architecture cleanly. I have a standard 3 tier architecture for this project that looks essentially like this:

Presentation

 -Presentation.Common
 -Presentation.DataStorageWebAppName

Business

 -BusinessLayer.Common
 -BusinessLayer.DataStorageAppName

Data

 -DataLayer.Common
 -DataLayer.DataStorageAppName

Common

 -Common
 -Common.DataStorageAppName

Interfaces

 -Interfaces.Common
 -Interfaces.DataStorageAppName

To highlight a particular scenario where I'm having trouble architecting the application, let me give an example. Let's say that in the business layer I create a class in the BusinessLayer.DataStorageAppName DLL called Foo. It has an interface, IFoo, that lives in the Interfaces.DataStorageAppName DLL. To create an instance of the class Foo through it's interface IFoo using a simple factory pattern, right now, I create a Factory class in BusinessLayer.DataStorageAppName and write a shared/static method to do give me an instance through the IFoo interface. Later, as I understand it, I could decide to swap out the object this Factory class returns without having to do much else (in theory).

To get to the point, this works, but what seems funky about it is that I'm now forced into creating several Factory classes: one per DLL essentially, so that I can avoid circular references. Is there a cleaner way to implement these factory classes without resorting to using a 3rd party solution like castle windsor, etc. etc. It seems as though I'm missing a fundamental concept here. It seems as though it should be possible to have a single "repository", if you will, in the architecture that is responsible for handing out object instances.

Thank you in advance!

Upvotes: 1

Views: 1065

Answers (3)

Giraffe
Giraffe

Reputation: 2013

Is there a reason why your implementation of IFoo and the factory method that returns it cannot live in a separate assembly from the BusinessLayer (and thus you can reference this new assembly from all the client assemblies)? If there is a reason, is it possible that IFoo should be defined in the BusinessLayer as well (and thus not require references to the Interfaces assembly)?

If your interface really does need to be accessible from more than the Business Layer, and the implementation really does rely on the Business Layer then you'll need to look at something a bit more than just the factory method. You could use some of the principles of Inversion of Control / Dependency Injection to get better separation of concerns.

[Edit in response to subsequent answer from O.P.] The Factory Method is not, IMO, sufficient to be considered an IoC approach. What it's best for is encapsulating construction of a specific implementation, to either re-use in multiple places or simply to sweep it under the rug. What's lacking for me is the breaking of dependencies: since your factory method is living in the same assembly as it's being called from, in order to change the concrete type returned, you'd need to recompile. Consider the difference between the following two:

public class FooConsumer1
{
    public void DoStuff()
    {
        IFoo myFoo = new Foo();
        myFoo.Bar();
    }
}

and:

public class FooConsumer2
{
    public void DoStuff()
    {
        IFoo myFoo = FooFactory.getFoo();
        myFoo.Bar();
    }
}

public class FooFactory
{
    public static IFoo GetFoo()
    {
        return new Foo();
    }
}

The advantage of the second is that if you create an IFoo in more than one place, you only have one place to change it when you create a SuperFoo class to replace Foo. Also, there is only one place to put logic if it will decide between two implementations dynamically in some way. Another advantage is that if the constructor is complicated/ugly, or requires some additional code to look up configuration settings or so on, then it hides all that away from the method that is using it.

However, none of those are really (to my mind at least) helping you break the dependencies between this method and the concrete implementation it uses.

Upvotes: 1

Øyvind Skaar
Øyvind Skaar

Reputation: 1840

It doesn't have to be funky to have several factory classes, if they handle different concerns. I would advice not to use static factory methods, but rather create instances of the factories you use. Then the factories themselves can implement interfaces, and perhaps some of the funkiness goes away.

Upvotes: 0

Otávio Décio
Otávio Décio

Reputation: 74270

I took a simpler approach. I defined an Entity class and I have a factory that produces list of entity (List< Entity >). I tell the factory what types I want to get back, it assumes the type to be the table, the properties to be the columns, generate the sql, get the data, populate a list of new instances of the type.

The factory can also receive an Entity object and use reflection to get update its values in the database.

Now the only thing I need to do is to create the set of Entity classes for a given database, which BTW are the data transfer objects as well.

Upvotes: 1

Related Questions