FOXDeveloper
FOXDeveloper

Reputation: 39

How can I make the factory class static in factory design pattern?

I was reading an e-book explaining design patterns, and after explaining the factory design pattern, it suggests some improvements. One of them was to make the factory static.

Make the factory (or a factory manager) static: This makes it easier to use but requires additional setup.

But c# doesn't allow inheritance from static classes, so in this case how can I inherit different factories from the main (static) factory class?

For example, if I make a factory BeeFactory as a base class that has a function that returns a product IBee:

public BeeFactory 
{
    public abstract IBee GetBee();
}

And make two subclasses, HoneyBeeFactory and QueenBeeFactory, inheriting from the base class and they have different implementations of what should be done to the product:

public HoneyBeeFactory : BeeFactory 
{
    public override IBee GetBee() 
    {
        IBee bee = new Bee();
        bee.isMakeHoney = true;
        return bee;
    }
}
public QueenBeeFactory : BeeFactory 
{
    public override IBee GetBee() 
    {
        IBee bee = new Bee();
        bee.isMakeHoney = false;
        return bee;
    }
}

So if I made the factory base class static:

public static BeeFactory {...}

The two subclasses would make a compilation error. And if I made the factory class the only factory that exists, how could I have different implementations for the product creation?

It seems to me that making the factory base class static breaks the design itself because I can't inherit from it, so how can I implement the static class concept in the factory pattern? or what does the book refer to?? Thanks in advance.

The book's link (https://unity.com/resources/design-patterns-solid-ebook)

Upvotes: -1

Views: 110

Answers (3)

Mark Seemann
Mark Seemann

Reputation: 233347

What's probably meant is to make each factory Singletons, like this:

public class HoneyBeeFactory : BeeFactory 
{
    public static readonly BeeFactory Instance = new HoneyBeeFactory();

    private HoneyBeeFactory() {}

    public override IBee GetBee() 
    {
        IBee bee = new Bee();
        bee.isMakeHoney = true;
        return bee;
    }
}

Notice that the constructor is private, so that client code can only access BeeFactory via HoneyBeeFactory.Instance.

You can also move common Singletons to the abstract class, if you find that useful:

public abstract class BeeFactory 
{
    public static readonly BeeFactory HoneyBee = HoneyBeeFactory.Instance;
    public static readonly BeeFactory QueenBee = QueenBeeFactory.Instance;

    protected abstract IBee GetBee();
}

Upvotes: 5

nik0x1
nik0x1

Reputation: 1461

You have understood the factory method pattern absolutely correctly.

  1. The factory method pattern deals with interfaces and concrete classes.
  2. We can't inherit from a static class in c# (some thoughts on why this was done - Why can't I inherit static classes?).

P.S. Everything else is the author's fantasy.

P.S. The main idea of ​​a factory method is to make code less coupled (where we did new use factory interface). By making the code less coupled we can, for example, provide a factory implementation in tests that will provide a fake object, without which we would not be able to write a unit test (often we would have to write an integration test with a real object).

Upvotes: 0

T.S.
T.S.

Reputation: 19384

Mark Seemann has your answer as standard approach - when you want to substitute factories, it has to be an instance class because of interface. You can make it singleton, or not - that is depends on situation. If factory construction is expensive, singleton is the better approach, but if cheap - you can make factory facade and create factories as needed.

But now, in the world of Dependency Injection, you can really do different things. For example, .net now allows you to wire objects AsSingleton. Wired this way, class can implement interface and while the class itself is not locked for new construction, calling it from DI GetService guaranteed same instance. Ninjet is a DI framework that allows really fancy object initialization and wiring.

Definitely remember, design patterns are general guidance and not written in stone. You should use it as metal frame but add your own components to it, to satisfy your needs.

Upvotes: 0

Related Questions