Pergunta

What if I don't need a special factory class and I want a concrete client to instantiate right parts. The client needs to call Hello() from that part. Everywhere else the focus is on making the factory method a method of a special creator class. But here it is right away in a client. Is this still a factory method pattern and is it even correct to use it as shown below?

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            AClient c1 = new ClientUsingPart1();
            c1.Foo();
            AClient c2 = new ClientUsingPart2();
            c2.Foo();
            Console.ReadKey();
        }
    }

    abstract class AClient
    {
        public AClient() { this.ipart = Create(); }

        public void Foo() { ipart.Hello(); }
        // many other methods
        // ...
        public abstract IPart Create();  // factory method
        IPart ipart;
    }

    class ClientUsingPart1 : AClient
    {
        public override IPart Create() { return new Part1(); }
    }

    class ClientUsingPart2 : AClient
    {
        public override IPart Create() { return new Part2(); }
    }

    interface IPart
    {
        void Hello();
    }

    class Part1 : IPart
    {
        public void Hello() { Console.WriteLine("hello from part1"); }
    }
    class Part2 : IPart
    {
        public void Hello() { Console.WriteLine("hello from part2"); }
    }

}
Foi útil?

Solução 2

According to this: Differences between Abstract Factory Pattern and Factory Method It seems the code I posted in the original post shows a valid use of the factory method pattern. The key is - factory method is just a method of the class - which also may be the sole client of the created objects.

Or in another way: factory method does not need to be public and provide the created objects to the outside world. In my example the Create() method should be protected.

Outras dicas

Depending on exactly what you need to achieve you should probably use some for of dependency injection with an IoC container of your choice; with StructureMap, Autofac, Unit, Ninject, Castle Windsor all very popular. Once you IoC container has built the concrete classes it should support a syntax like this

foreach (var client in Container.Resolve<IEnumerable<AClient>>())
{
    client.Create();
}

You can read more about how to achieve this with StructureMap here: Does an abstract class work with StructureMap like an interface does?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top