HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Abstract Factory Experiment

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
factoryabstractexperiment

Problem

While I should probably be using Dependency Injection via Ninject or a similar project, I have been attempting to implement an abstract factory design that would provide me with the following easy to read and use syntax:

UniversalFactory.Factory.Create(... parameters ...);


I'm throwing this experiment on here in order to solicit some constructive feedback both with implementation logic and design reasoning.

Here is my current implementation:

public class UniversalFactory
{
    private readonly IFactory FooFactoryEx;

    public UniversalFactory()
    {
        FooFactoryEx = new FooFactory();
    }

    public IFactory Factory()
    {
        if (typeof (T) == typeof (IFoo))
            return (IFactory)FooFactoryEx;
        return null;
    }
}

public interface IFactory
{
    T Create(params object[] p) where T : TF;
}

public class FooFactory : IFactory
{
    public T Create(params object[] p) where T : IFoo
    {
        if (typeof(T) == typeof(FooImpl))
        {
            var id = Convert.ToInt32(p[0]);
            return (T)FooImpl.Create(id);
        }
        return default(T);
    }
}

public interface IFoo
{
    // Some interface
}

public class FooImpl : IFoo
{
    public int Id { get; set; }

    private FooImpl(int id)
    {
        Id = id;
    }

    public static IFoo Create(int id)
    {
        var foo =  new FooImpl(id);
        return foo;
    }
}


This code allows a UniversalFactory to be instantiated and the following to be invoked successfully:

UniversalFactory.Factory().Create(1);


My reasoning for this approach:

  • All construction is easily identifiable via the call to UniversalFactory.



  • Factories are invoked based on the interface implementation being constructed, hiding all details about the specific factory being used from the new object request.



  • The object type and its construction parameters are clearly identifiable in the request.



  • Object construction stays in each class, and any additional updat

Solution

Well what you are trying to do is not strictly speaking an abstract factory. For it to be an abstract factory the use case should look like this:

UniversalFactory.Factory  // client has no idea about IFactory implementation
                .Create(... parameters ...); // client has no idea about IFoo implementation, returns IFoo


Ideally, you should not even need to pass parameters. That is why you are building factories after all. To delegate object creation.

Other minor remarks:

  • where T : TF - those are not very descriptive names for generic arguments. Perhaps you can come up with better naming.



  • var id = Convert.ToInt32(p[0]); - i'm not sure i like Convert here. It might hide bugs and misusages. I think that strong cast is better in that case.



-
public static IFoo Create(int id) - i don't see any reason to use factory method.

public class FooImpl : IFoo
{
    public int Id { get; private set; }

    public FooImpl(int id)
    {
        Id = id;
    }
}


this looks a lot cleaner. Also i think Id setter should be always private.

Overall, i think unless you are doing it for studying purposes, you should just grab an existing DI library, as you've metioned yourself :)

Code Snippets

UniversalFactory.Factory<IFoo>  // client has no idea about IFactory<IFoo> implementation
                .Create(... parameters ...); // client has no idea about IFoo implementation, returns IFoo
public class FooImpl : IFoo
{
    public int Id { get; private set; }

    public FooImpl(int id)
    {
        Id = id;
    }
}

Context

StackExchange Code Review Q#41030, answer score: 2

Revisions (0)

No revisions yet.