Design patterns in the test of timeA modern alternative to Abstract Factory–filtered dependencies

time to read 11 min | 2166 words

In my Abstract Factory post, I mentioned that I really don’t like the pattern, and in particular, code like this:

   1: static IGUIFactory CreateOsSpecificFactory()
   2: {
   3:    string sysType = ConfigurationSettings.AppSettings["OS_TYPE"];
   4:    if (sysType == "Win") 
   5:    {
   6:        return new WindowsFactory();
   7:    } 
   8:    else 
   9:    {
  10:        return new MacFactory();
  11:    }
  12: }

One of the comments mentioned that this might no be ideal, but it is still better than:

   1: if(RunningOnWindows)
   2: {
   3:     // code
   4: }
   5: else if(RunningOnMac)
   6: {
   7:    // code
   8: }
   9: else if(RunningOnLinux)
  10: {
  11:    // code
  12: }

And I agree. But I think that, as the comment mentioned, a far better alternative would be using the container. You can do this using:

   1: [OperationSystem("Windows")]
   2: public class WindowsFactory : IGUIFactory
   3: {
   4: }
   5:  
   6: [OperationSystem("Linux")]
   7: public class LinuxFactory : IGUIFactory
   8: {
   9: }
  10:  
  11: [OperationSystem("Mac")]
  12: public class MacFactory : IGUIFactory
  13: {
  14: }
  15:  

Then you just need to wire things through the container. Among other things, this means that we respect the open / closed principle. If we need to support a new system, we can just add a new class, we don’t need to modify code.

Remember, the Go4 book was written in the age of C++. Reflection didn’t exists, and that means that a lot of patterns do by hands things that can happen automatically.

More posts in "Design patterns in the test of time" series:

  1. (21 Jan 2013) Mediator
  2. (18 Jan 2013) Iterator
  3. (17 Jan 2013) Interpreter
  4. (21 Nov 2012) Command, Redux
  5. (19 Nov 2012) Command
  6. (16 Nov 2012) Chain of responsibility
  7. (15 Nov 2012) Proxy
  8. (14 Nov 2012) Flyweight
  9. (09 Nov 2012) Façade
  10. (07 Nov 2012) Decorator
  11. (05 Nov 2012) Composite
  12. (02 Nov 2012) Bridge
  13. (01 Nov 2012) Adapter
  14. (31 Oct 2012) Singleton
  15. (29 Oct 2012) Prototype
  16. (26 Oct 2012) Factory Method
  17. (25 Oct 2012) Builder
  18. (24 Oct 2012) A modern alternative to Abstract Factory–filtered dependencies
  19. (23 Oct 2012) Abstract Factory