Search code examples
c#design-patternsabstract-factoryfactory-methodcreation-pattern

Parametrized Abstract Factory / Factory Method / other creation patterns


I want to have some factory (doesn't matter if Abstract Factory pattern or Factory Method - looks like the second is specific form of the first one. In my case only one object should be created). The thing is that although created products are similar, they depends on some arguments.

How to prepare this architecture in compliance with design patterns?

Current approach below

public abstract class Product {}

public class MyProduct : Product
{
    public bool Abc { get; set; }
}

public class YourProduct : Product {}

public abstract class ProductFactory
{
    //in some cases parameter not in use
    public abstract Product Create(HelpData additionalData);
}

public class MyProductFactory : ProductFactory
{
    public override Product Create(HelpData additionalData)
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory : ProductFactory
{
    //unused parameter
    public override Product Create(HelpData additionalData)
    {
        return new YourProduct();
    }
}

public class HelpData
{
    public bool SomethingImportantForMyProduct { get; set; }
}

EDIT

I see it's not clear so will repeat.

Usually I'm not using patterns just because of using them. But this problem seems not to be border case. Looks rather quite frequent. Going further I believe there's design pattern suitable to this, but I'm not sure which one. For now looks like abstract factory is not right choice.


Solution

  • Don't use design-patterns because you're using design-patterns. Always have in mind when to use one and when not. In your circumstances at least the abstract factory-pattern is wrong, as it assumes all factories to work with the same parameters. So if you have different parameters you surely need different factories.

    However there's no way for the abstract factory to guess how to get an instance of a HelpData in some case but not in the other, so either pass it to every abstract factory or completely omit this further abstraction and stay with two independent factories:

    public abstract class Product {}
    
    public class MyProduct : Product
    {
        public bool Abc { get; set; }
    }
    
    public class YourProduct : Product {}
    
    public class MyProductFactory
    {
        public Product Create(HelpData additionalData)
        {
            return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
        }
    }
    
    public class YourProductFactory
    {
        //unused parameter
        public Product Create()
        {
            return new YourProduct();
        }
    }
    
    public class HelpData
    {
        public bool SomethingImportantForMyProduct { get; set; }
    }
    

    Exposing a parameter only used within one factory to all factories isn't a good idea.

    Besides this just imagine you don't have factories but any other classes that have a Create-method, where one needs a parameter, but the other one does not. Why should those two classes derive from the same base-class (in your case the abstract factory), when the don't have any common members? There's apparently no reason for this, so don't overcomplicate things just for the sake of using a pattern which doesn't fit.