Abstract Factory Sample - Point Concrete Plant

This is how I usually see an abstract Factory pattern:

public abstract class Factory { public abstract Product GetProduct(); } public class ConcreteFactory1 : Factory { public override Product GetProduct() { return new Product1(); } } class ConcreteFactory2 : Factory { public override Product GetProduct() { return new Product2(); } } interface Product { void SomeMethod(); } class Product1 : Product { public void SomeMethod() { Console.WriteLine("1"); } } class Product2 : Product { public void SomeMethod() { Console.WriteLine("2"); } } class Program { static void Main(string[] args) { Factory f = null; Product p = null; switch (args[0]) { case "1": f = new ConcreteFactory1(); p = f.GetProduct(); break; case "2": f = new ConcreteFactory2(); p = f.GetProduct(); break; } p.SomeMethod(); } } 

I usually write this in a way that is not a true pattern:

 interface Product { void SomeMethod(); } class Product1 : Product { public void SomeMethod() { Console.WriteLine("1"); } } class Product2 : Product { public void SomeMethod() { Console.WriteLine("2"); } } public static class Factory { public static Product GetProduct(prodType) { Product p = null; switch (prodType) { case "1": p = new Product1(); break; case "2": p = new Product2(); break; } return p; } } class Program { static void Main(string[] args) { Product p = Factory.GetProduct(args[0]); p.SomeMethod(); } } 

My question is: what is the advantage of specific plants? I never understood the point - it seems that this is just an extra layer. The second example looks much more concise and simple.

+4
source share
4 answers

Since Odrade agrees with me (I think I'm not quite from my rocker), I will send this as an answer:

I think, and correct me if I am wrong, is that usually your base level code does not have a clue about a specific factory. Also, you should not indicate the type of product (in your case) through prodType. Instead, a specific factory implementation is served through some form of dependency injection into your abstract factory, and your code continues its weighting path without having a clue that the factory is being used, or the specific types that are needed. Especially if specific factory implementations are provided by third-party consumers of your API.

The Wikipedia article on this subject is a good example of building a GUI for an operating system: http://en.wikipedia.org/wiki/Abstract_factory_pattern#C.23

In fact, your code in your library can function perfectly, without knowing any implementation details or dependencies on the operating system used. When you (or a user of your API) switch to Linux migration (in this example on Wikipedia), you simply implement LinuxFactory and LinuxButton and pass it to your API. If instead, as in your typical example, you control it through an input, say, an enumeration, then your factory should know about Linux:

 public static class Factory { public static Button GetButton(operatingSystem) { switch (operatingSystem) { case "windows": return new WindowsButton(); case "macintosh": return new MacButton(); } } } 

How is Linux now taken into account? Well, that can't unless you add support. Plus now all consumers of your API are indirectly dependent on all implementations of the operating system.

EDIT: Note that Factory Pattern and Abstract Factory Pattern are two completely different concepts. As for your problems with why you asked the question first, abstract factory templates are not always necessary. If you do not need this, then do not add the complexity of one. If you just need a simple factory (which your second example is an option), use it. The right tool for the right job and all that.

+6
source

I would call your approach a Factory pattern that is different from an abstract Factory.

+2
source

"Abstract Factory" is really a bad name for this template. It’s much better to name the β€œKit” template, which also used GoF. I agree, in the example you gave, this is an excessive design. it makes a lot more sense when your plants are responsible for creating many objects that work together. Then various groups of them (sets, if you want) are created by different factories, in accordance with a given set of execution conditions or development time.

This is a really good article about this. The non-software analogy of the metric and English socket sets is ideal there.

+1
source

What is the advantage of specific plants? I never understood the point - it just seems to add another unnecessary layer

factory (in general, the Factory Method, Factory Abstract, etc.) used to solve a complex type of object, if your Product1 and Product2 require a different type of initialization, then it would not be a good idea to hard-write it to your specific factory.

0
source

All Articles