{"id":2117,"date":"2012-11-30T01:03:18","date_gmt":"2012-11-30T07:03:18","guid":{"rendered":"https:\/\/daedtech.wpenginepowered.com\/?p=2117"},"modified":"2015-06-30T01:37:41","modified_gmt":"2015-06-30T06:37:41","slug":"factory-method","status":"publish","type":"post","link":"https:\/\/daedtech.com\/factory-method\/","title":{"rendered":"Factory Method"},"content":{"rendered":"<h3>Quick Information\/Overview<\/h3>\n<table>\n<tbody>\n<tr>\n<td>Pattern Type<\/td>\n<td>Creational<\/td>\n<\/tr>\n<tr>\n<td>Applicable Language\/Framework<\/td>\n<td>Agnostic OOP<\/td>\n<\/tr>\n<tr>\n<td>Pattern Source<\/td>\n<td><a href=\"http:\/\/en.wikipedia.org\/wiki\/Design_Patterns\">Gang of Four<\/a><\/td>\n<\/tr>\n<tr>\n<td>Difficulty<\/td>\n<td>Moderate &#8212; slightly easier than <a href=\"https:\/\/daedtech.com\/abstract-factory\">Abstract Factory<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<figure style=\"width: 469px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif\" alt=\"\" width=\"469\" height=\"185\" \/><figcaption class=\"wp-caption-text\">Image courtesy of dofactory<\/figcaption><\/figure>\n<h3>Up Front Definitions<\/h3>\n<ol>\n<li><strong>Creator:<\/strong>\u00a0This is the basic, abstract factory interface.<\/li>\n<li><strong>Concrete Creator:<\/strong> Inheritor factory classes that implement some actual object creation scheme.<\/li>\n<li><strong>Product: <\/strong>This is the base\/abstract polymorphic object that gets created by the factories.<\/li>\n<\/ol>\n<h3>The Problem<\/h3>\n<p>Let&#8217;s say that you&#8217;re coding up some kind of game and in this game a character navigates a world and encounters various entities with which to interact, including enemies. You&#8217;re starting out with a very bare bones proof of concept, and here is your sketch of some enemies:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class Enemy\r\n{\r\npublic abstract string Attack();\r\n}\r\n\r\npublic class Dragon : Enemy\r\n{\r\npublic override string Attack()\r\n{\r\nreturn \"You've been torched with fire breath!\";\r\n}\r\n}\r\n\r\npublic class Gator : Enemy\r\n{\r\npublic override string Attack()\r\n{\r\nreturn \"You've been chomped!\";\r\n}\r\n}\r\n\r\npublic class HouseFly : Enemy\r\n{\r\npublic override string Attack()\r\n{\r\nreturn \"You've been annoyed!\";\r\n}\r\n}\r\n\r\npublic class MotherInLaw : Enemy\r\n{\r\npublic override string Attack()\r\n{\r\nreturn \"You've been guilt-tripped!\";\r\n}\r\n}\r\n\r\npublic class ChuckNorris : Enemy\r\n{\r\npublic override string Attack()\r\n{\r\nreturn \"Your entire existence has been erased from space-time in one devastating but magnificent master-stroke!\";\r\n}\r\n}\r\n<\/pre>\n<p>The concrete enemies return a string representation of their attack, which you will, no-doubt, later transform into some kind of first class attack object or even graphic as the game moves along, but for now, you just want to get the concept right. To get things going, you create the following class:<\/p>\n<pre lang=\"C#\">\r\npublic class GameNarrative\r\n{\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nif (placeName == \"swamp\")\r\nInteractWithEnemy(new Gator());\r\n}\r\n\r\nprivate void InteractWithEnemy(Enemy enemy)\r\n{\r\nConsole.Write(enemy.Attack());\r\n}\r\n}\r\n<\/pre>\n<p>You want to keep things clean, so you abstract an interaction method, knowing that at some point this will probably mean something different than dumping to Console. From there, you&#8217;re now left to figure out the enemy situation based on where the character goes and you&#8217;re off to a good start since gators tend to hang out in swamps. Let&#8217;s add in a few more scenarios:<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nif (placeName == \"swamp\")\r\nInteractWithEnemy(new Gator());\r\nelse if (placeName == \"starbucks\" || placeName == \"family reunion\")\r\nInteractWithEnemy(new MotherInLaw());\r\nelse if (placeName == \"middleEarth\")\r\nInteractWithEnemy(new Dragon());\r\nelse if (placeName == \"texas truck stop\")\r\nInteractWithEnemy(new ChuckNorris());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n<\/pre>\n<p>Now you&#8217;re off and running. You decide that HouseFly is a good enemy to use in this case, since it seems like a good stock enemy ala the &#8220;Goombas&#8221; in Super Mario Brothers or Foot Soldiers in the Teenage Mutant Ninja Turtles (I&#8217;m probably dating myself a bit here). But wait a minute &#8212; house flies could happen anywhere. Let&#8217;s say that they&#8217;re the else condition, but they also have a 50\/50 chance of appearing in the other places. Hmmm&#8230; let&#8217;s introduce an abstraction to hide the ugly and annoying details of randomization and do this:<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nif (placeName == \"swamp\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new Gator());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse if (placeName == \"starbucks\" || placeName == \"family reunion\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new MotherInLaw());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse if (placeName == \"middleEarth\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new Dragon());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse if (placeName == \"texas truck stop\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new ChuckNorris());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n<\/pre>\n<p>Ew, that&#8217;s starting to smell a bit, but no time to worry about that now. Your efforts here have led to some angel investment capital and now the pressure is on. You use that money to hire a UX\/gameplay expert so that he can worry about the gaming decisions while you focus on architecture. He tells you that you need to introduce the concept of difficulty and that Chuck Norris can be anywhere except Middle Earth but only if the difficulty level is set to 5 or more. But Chuck Norris is a family man himself, so he&#8217;ll only attack you at a family reunion on a <strong>really<\/strong> high difficulty level like 10. Otherwise, he&#8217;ll wait until you leave. Hmmm&#8230;.<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nif (placeName == \"swamp\")\r\n{\r\nif (_difficultyLevel &gt; 5)\r\n{\r\nswitch (_randomizer.PickANumberOneThrough(3))\r\n{\r\ncase 1: InteractWithEnemy(new Gator()); break;\r\ncase 2: InteractWithEnemy(new HouseFly()); break;\r\ncase 3: InteractWithEnemy(new ChuckNorris()); break;\r\n}\r\n}\r\nelse\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new Gator());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n}\r\nelse if (placeName == \"starbucks\")\r\n{\r\nif (_difficultyLevel &gt; 5)\r\n{\r\nswitch (_randomizer.PickANumberOneThrough(3))\r\n{\r\ncase 1: InteractWithEnemy(new MotherInLaw()); break;\r\ncase 2: InteractWithEnemy(new HouseFly()); break;\r\ncase 3: InteractWithEnemy(new ChuckNorris()); break;\r\n}\r\n}\r\nelse\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new MotherInLaw());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n}\r\nelse if (placeName == \"family reunion\")\r\n{\r\nif (_difficultyLevel &gt; 10)\r\n{\r\nswitch (_randomizer.PickANumberOneThrough(3))\r\n{\r\ncase 1: InteractWithEnemy(new Gator()); break;\r\ncase 2: InteractWithEnemy(new HouseFly()); break;\r\ncase 3: InteractWithEnemy(new ChuckNorris()); break;\r\n}\r\n}\r\nelse\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new Gator());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n}\r\nelse if (placeName == \"middleEarth\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new Dragon());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse if (placeName == \"texas truck stop\")\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new ChuckNorris());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse\r\n{\r\nif (_difficultyLevel &gt; 5)\r\n{\r\nif (_randomizer.IsRandomCoinFlipHeads())\r\nInteractWithEnemy(new ChuckNorris());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n}\r\n<\/pre>\n<p>You look at this and realize that you&#8217;re definitely whipping up some spaghetti code here, but no time for that now. Your game designer tells you that you need a new mode of the game where instead of interacting with the enemies you talk with them first. The logic for encountering the enemies is exactly the same and you still need your old code, but you need it in a new module. Oh, and you should probably add a few new enemies that you find in a few new places. And house flies should probably stop appearing after difficulty level 7. Oh, and dragons can appear in Starbucks sometimes after a successful battle with MotherInLaw. Oh, and gators can appear at your family reunion if you have it in Florida.<\/p>\n<p>Here&#8217;s the code for that&#8230; just kidding. You&#8217;re probably not going to read subsequent posts if I destroy your eyesight with the code I&#8217;m describing.<\/p>\n<h3>So, What to Do?<\/h3>\n<p>As has become customary in this section, let&#8217;s examine what went wrong. Most of the time it&#8217;s the point at which copying and pasting start, but not in this case. Another good tell in this series of posts where things go off the rail is when I start trotting out excuses for what &#8216;you&#8217; are doing in the second person narrative. As soon as things are a little ugly because &#8216;you&#8217; have a deadline or &#8216;your&#8217; project manager is riding you, that&#8217;s usually when things went wrong. Here is no exception. Let&#8217;s rewind to the second code snippet, representative of a simpler time:<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nif (placeName == \"swamp\")\r\nInteractWithEnemy(new Gator());\r\nelse if (placeName == \"starbucks\" || placeName == \"family reunion\")\r\nInteractWithEnemy(new MotherInLaw());\r\nelse if (placeName == \"middleEarth\")\r\nInteractWithEnemy(new Dragon());\r\nelse if (placeName == \"texas truck stop\")\r\nInteractWithEnemy(new ChuckNorris());\r\nelse\r\nInteractWithEnemy(new HouseFly());\r\n}\r\n<\/pre>\n<p>This is alright, though I would argue that we can make a nice improvement here. Notice that we&#8217;re following a pretty consistent pattern here: we check place name and then we invoke the same method on a polymorphic object that varies with place name. It might seem like a trivial bit of redundancy, but these add up as you leave them in and, I would argue, poison the well when it comes to future design decisions. <a href=\"http:\/\/en.wikipedia.org\/wiki\/Broken_windows_theory\">Broken Window Theory<\/a> and all that. So let&#8217;s change the code to this:<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nvar enemy = GenerateLocalEnemyFor(placeName);\r\nInteractWithEnemy(enemy);\r\n}\r\n\r\nprivate static Enemy GenerateLocalEnemyFor(string placeName)\r\n{\r\nswitch (placeName)\r\n{\r\ncase \"swamp\": return new Gator();\r\ncase \"starbucks\":\r\ncase \"family reunion\": return new MotherInLaw();\r\ncase \"middleEarth\": return new Dragon();\r\ncase \"texas truck stop\": return new ChuckNorris();\r\ndefault: return new HouseFly();\r\n}\r\n}\r\n<\/pre>\n<p>Notice that there&#8217;s now only one call to &#8220;InteractWithEnemy&#8221; and we&#8217;ve split the functionality of mapping place name to en enemy instance from the functionality of interacting with the enemy in a nod to the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\">SRP<\/a>. You also might notice that we have implemented what has come to be a common variant of the original Factory Method pattern, which is the static factory method. A static factory method is a stateless method that takes in some criteria and spits back a matching polymorphic instance of the common base return type. For instance, this method says &#8220;if the place is middle earth, we need a dragon enemy.&#8221;<\/p>\n<p>With this refactoring accomplished, let&#8217;s take on the next requirement, which is that house flies can occur anywhere with a 50% probability. Before our heads start rushing with design patterns and complex implementations, let&#8217;s consider what might be the easiest way to get this working. Didja think of this:<\/p>\n<pre lang=\"C#\">\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nvar enemy = GenerateLocalEnemyFor(placeName, _randomizer);\r\nInteractWithEnemy(enemy);\r\n}\r\n\r\nprivate static Enemy GenerateLocalEnemyFor(string placeName, IRandomizeThings randomizer)\r\n{\r\nif (randomizer.IsRandomCoinFlipHeads())\r\nreturn new HouseFly();\r\n\r\nswitch (placeName)\r\n{\r\ncase \"swamp\": return new Gator();\r\ncase \"starbucks\":\r\ncase \"family reunion\": return new MotherInLaw();\r\ncase \"middleEarth\": return new Dragon();\r\ncase \"texas truck stop\": return new ChuckNorris();\r\ndefault: return new HouseFly();\r\n}\r\n}\r\n<\/pre>\n<p>Notice how easy that is with a little bit of logic separation. But, if that implementation strategy were going to hold up, there&#8217;d be no meat to this post, so let&#8217;s press on. Chuck Norris can be anywhere except for Middle Earth and a family reunion if the difficulty level is at least 5 and anywhere except Middle Earth if the difficulty level is at least 10. At this point it&#8217;s important to recognize what&#8217;s happening here and it&#8217;s easier to do so now with this factored road down which we&#8217;ve started. What&#8217;s happening is that what was originally a simple mapping from place name to enemy inheritor is becoming muddied by a growing number of additional factors. And what&#8217;s a good way to handle additional complexity in an object oriented programming language? Well, encapsulate it in an object.<\/p>\n<p>The idea of centering the enemy generation around places is appealing since that&#8217;s how we originally conceived of it, so let&#8217;s stick with that. The family reunion one seems to be the most complicated, so let&#8217;s take a look at that:<\/p>\n<pre lang=\"C#\">\r\npublic class FamilyReunionFactory\r\n{\r\nprivate readonly IRandomizeThings _randomizer;\r\n\r\npublic FamilyReunionFactory(IRandomizeThings randomizer)\r\n{\r\n_randomizer = randomizer;\r\n}\r\n\r\npublic Enemy GetEnemy(int difficultyLevel)\r\n{\r\nif (difficultyLevel &lt; 10)\r\nreturn _randomizer.ChooseAtRandom(new HouseFly(), new MotherInLaw());\r\nelse\r\nreturn _randomizer.ChooseAtRandom(new HouseFly(), new MotherInLaw(), new ChuckNorris());\r\n}\r\n}\r\n<\/pre>\n<p>(I added a &#8220;choose at random&#8221; method to the interface of signature T ChooseAtRandom&lt;T&gt;(params T[] thingsToChoose) to keep the emphasis on the factory class as much as possible rather than distracting with worries about random implementation. I acknowledge that this would have made the problem code a little less noisy, but it still would have been headed down a bad street with creeping complexity)<\/p>\n<p>Cool! Now the GameNarrative class doesn&#8217;t need to worry about the creeping complexity around what goes into the decision of which enemy to generate beside the place name. We have a class with the single responsibility of figuring out how enemies get generated for the family reunion location. But how does this fit with the original class? Well, let&#8217;s take a look at an interim solution. Here is an updated, no-longer-static factory method:<\/p>\n<pre lang=\"C#\">\r\nprivate Enemy GenerateLocalEnemyFor(string placeName)\r\n{\r\nswitch (placeName)\r\n{\r\ncase \"swamp\": return new Gator();\r\ncase \"starbucks\":\r\ncase \"family reunion\": return new FamilyReunionFactory(_randomizer).GetEnemy(_difficultyLevel);\r\ncase \"middleEarth\": return new Dragon();\r\ncase \"texas truck stop\": return new ChuckNorris();\r\ndefault: return new HouseFly();\r\n}\r\n}\r\n<\/pre>\n<p>Notice that instead of directly instantiating an enemy when we&#8217;re at the family reunion, we delegate that task to our newly created factory. Let&#8217;s make a factory for each place now so that we can remove that awkward GetEnemy call and keep this method clean. In order to do this and return a factory instead of an enemey, we&#8217;re also going to need to make these factories polymorphic cousins of one another, by defining an interface (could also be an abstract base, which is less decoupled but allows implementation of a common constructor).<\/p>\n<pre lang=\"C#\">\r\npublic interface IFamilyReunionFactory\r\n{\r\nEnemy GetEnemy(int difficultyLevel);\r\n}\r\n<\/pre>\n<p>And, with that in place and all of the other factories defined (elided), here is the new narrative class:<\/p>\n<pre lang=\"C#\">\r\npublic class GameNarrative\r\n{\r\nprivate readonly IRandomizeThings _randomizer;\r\n\r\nprivate readonly int _difficultyLevel;\r\n\r\npublic GameNarrative(IRandomizeThings randomizer, int difficultyLevel)\r\n{\r\n_randomizer = randomizer;\r\n_difficultyLevel = difficultyLevel;\r\n}\r\n\r\npublic void MoveMainCharacterTo(string placeName)\r\n{\r\nvar enemyFactory = GetEnemyFactory(placeName);\r\nvar enemy = enemyFactory.GetEnemy(_difficultyLevel);\r\nInteractWithEnemy(enemy);\r\n}\r\n\r\nprivate IEnemyFactory GetEnemyFactory(string placeName)\r\n{\r\nswitch (placeName)\r\n{\r\ncase \"swamp\": return new SwampFactory(_randomizer);\r\ncase \"starbucks\": return new StarbucksFactory(_randomizer);\r\ncase \"family reunion\": return new FamilyReunionFactory(_randomizer);\r\ncase \"middleEarth\": return new MiddleEarthFactory(_randomizer);\r\ncase \"texas truck stop\": return new TexasTruckStopFactory(_randomizer);\r\ndefault: return new DefaultFactory(_randomizer);\r\n}\r\n}\r\n\r\nprivate void InteractWithEnemy(Enemy enemy)\r\n{\r\nConsole.Write(enemy.Attack());\r\n}\r\n}\r\n<\/pre>\n<p>That&#8217;s looking pretty darn legible now. But it&#8217;s not just that the code is easy to read or even that it&#8217;s separated into factored methods and classes. The important thing here is conformance to SRP and the fact that it&#8217;s easy to find what needs to change and change it independently of other concerns. Think back to the change request that broke our spirit earlier. Adding new enemies? Piece of cake &#8212; just add classes for them and then add them to the random generation in the factories that are eligible to generate them. Porting enemy generation? Just make the GetEnemyGeneration method (or some variant of it) publicly accessible and call it elsewhere. All of the new enemy generation business rules? Put them in their appropriate factories. Cross cutting rules? Create a base factory class. These tasks are now quite manageable.<\/p>\n<h3>A More Official Explanation<\/h3>\n<p>The stated purpose of the Factory Method design pattern (from <a href=\"http:\/\/www.dofactory.com\/Patterns\/PatternFactory.aspx\">dofactory<\/a>) is:<\/p>\n<blockquote><p>Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.<\/p><\/blockquote>\n<p>This creational pattern is also sometimes referred to as &#8220;virtual constructor&#8221; because of the way it separates the promise of object creation from the implementation via polymorphism. Be it an interface or abstract base class, the abstract definition defines a contract for the generation of polymorphic entities and then delegates that work to implementers\/inheritors.<\/p>\n<p>This has the powerful benefit of allowing flexibility and following of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Open\/closed_principle\">open\/closed principle<\/a> not just for creation of objects but for strategies for object creation. In our example above, the IEnemyFactory is the Creator, the various factories are the Concrete Creators and the enemies are Products. We have the ability with this implementation to seamlessly add new enemies but also to seamlessly add new schemes for generating enemies. If we wanted to add a location called &#8220;mountains&#8221; with its own unique set of denizens to the game, this would be straightforward and have nearly 0 bearing on existing code.<\/p>\n<p>It is worth noting the conceptual similarity to Abstract Factory at this point and pointing out that the jump from Factory Method to Abstract Factory is just the addition of more polymorph families. For instance, if each location had enemies, terrain, and allies, Abstract Factory would be a good fit. That said, the transition from Factory Method to Abstract Factory is <em>extremely<\/em> violent to the code base since the addition of methods to the factory require changes to all implementers. Thus it is probably good to spend some effort up front reasoning about what the factory should do, particularly if the concrete factories are spread far and wide (unless you are using an abstract base class and then there is some reprieve here as you can specify default behavior).<\/p>\n<h3>Other Quick Examples<\/h3>\n<ol>\n<li>An enterprise application capable of pulling information from multiple persistence models (factory methods to create DAOs).<\/li>\n<li>A GUI intensive application that generates controls\/forms\/pages on the fly depending on user interaction.<\/li>\n<\/ol>\n<h3>A Good Fit \u2013 When to Use<\/h3>\n<p>This is an interesting one circa 2012 because it seems like a decent amount of the heavy lifting that I used to see this pattern do has been replaced by IoC containers or plugin architectures. In other words, the Gang of Four made it fashionable to move complex instance creation into its own place in your code, and the Unit Test\/TDD crowd later made it fashionable to move it out of your code altogether. It&#8217;s also been squeezed on the other side, so to speak, by the prevalence of the &#8220;poor man&#8217;s factory method&#8221; &#8212; a simple static method that returns polymorphs representing a common interface or base class.<\/p>\n<p>But in reality, this pattern has its own niche not covered by either of these situations. IoC containers and, to some extent, plugin architectures are really about decisions made at application start time. The point of abstracting them out of the codebase is to allow application behavior to be changed without rebuilding and re-deploying. Factory Method as I would advocate covers a subtly different usage scenario wherein the polymorphic type is not known at application startup. An obvious example (and the one we covered in this post) is where the user supplies input that governs which object should be created in some way.<\/p>\n<p>But this could still mean using the static method rather than the class hierarchy of Factory Method. I would recommend the latter specifically in situations where the logic surrounding instance creation is more complex than switching over a simple argument or two and\/or likely to grow and change with time (the aforementioned Open\/Closed Principle). If you find that you have a static factory method that&#8217;s ballooning in size and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Cyclomatic_complexity\">cyclomatic complexity<\/a> it&#8217;s probably time to consider a factory method hierarchy.<\/p>\n<h3>Square Peg, Round Hole \u2013 When Not to Use<\/h3>\n<p>The inverse of various situations described in the previous section is a good place to start. You probably don&#8217;t want to use this pattern for very simple scenarios (say, switching over an enum or character to create instances) and you probably don&#8217;t want to use it for decision that can be made prior to runtime as that introduces more complexity and indirection to your application than necessary. Another place that you&#8217;d avoid this is when you need an abstract factory because you&#8217;re creating object families.<\/p>\n<p>As always, YAGNI applies, and factories are sort of iconic in representing over-engineering in OOP. I once heard a cynical but funny quote (don&#8217;t recall who originally said it, but if you know, please comment): &#8220;some people think they&#8217;ll use java to solve their problems &#8212; now they have a problem factory.&#8221; This is obviously tongue in cheek, but the implied point about pattern happy enterprise development shines through. It&#8217;s easy to get pretty elaborate when abstracting instance creation out of plumbing and service code (and I love the practice) but there&#8217;s a fine line between this and creating too many levels of indirection. Be careful that you actually need these factories and aren&#8217;t just speculatively abstracting. As a rule of thumb, I&#8217;d say that you should be able to look at them and think &#8220;man, it&#8217;s a good thing I pulled that into a class.&#8221;<\/p>\n<h3>So What? Why is this Better?<\/h3>\n<p>As show in the example, when judiciously used, the Factory Method pattern can transform what would have been a snarl of instantiation spaghetti into a well separated, maintainable set of classes. The &#8220;after&#8221; in this picture shows code that conforms to established OOP principles such as the Open\/Closed Principle and the Single Responsibility Principle (you can throw <a href=\"http:\/\/en.wikipedia.org\/wiki\/Liskov_substitution_principle\">Liskov<\/a> in there too since there&#8217;s a lot of polymorphism here).<\/p>\n<p>Once this is in place, adding new target\/product objects for creation is a segregated and approachable problem and adding new creation schemes becomes quite easy. It&#8217;s also straightforward to separate creation from use in your code as well, leading to a lot of architectural flexibility. And, properly applied, it&#8217;s a good mechanism for avoiding the bane of programming existence &#8212; copy and paste coding.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quick Information\/Overview Pattern Type Creational Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Moderate &#8212; slightly easier than Abstract Factory Up Front Definitions Creator:\u00a0This is the basic, abstract factory interface. Concrete Creator: Inheritor factory classes that implement some actual object creation scheme. Product: This is the base\/abstract polymorphic object that gets created by&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[25],"tags":[],"class_list":["post-2117","post","type-post","status-publish","format-standard","hentry","category-design-patterns"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Factory Method - DaedTech<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/daedtech.com\/factory-method\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Factory Method - DaedTech\" \/>\n<meta name=\"twitter:description\" content=\"Quick Information\/Overview Pattern Type Creational Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Moderate &#8212; slightly easier than Abstract Factory Up Front Definitions Creator:\u00a0This is the basic, abstract factory interface. Concrete Creator: Inheritor factory classes that implement some actual object creation scheme. Product: This is the base\/abstract polymorphic object that gets created by...\" \/>\n<meta name=\"twitter:image\" content=\"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Erik Dietrich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/\"},\"author\":{\"name\":\"Erik Dietrich\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/person\\\/3dae63e91a0fa60c8051a2171fa687d2\"},\"headline\":\"Factory Method\",\"datePublished\":\"2012-11-30T07:03:18+00:00\",\"dateModified\":\"2015-06-30T06:37:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/\"},\"wordCount\":2635,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/factory.gif\",\"articleSection\":[\"Design Patterns\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/\",\"url\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/\",\"name\":\"Factory Method - DaedTech\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/factory.gif\",\"datePublished\":\"2012-11-30T07:03:18+00:00\",\"dateModified\":\"2015-06-30T06:37:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#primaryimage\",\"url\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/factory.gif\",\"contentUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/factory.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/factory-method\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/daedtech.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Factory Method\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#website\",\"url\":\"https:\\\/\\\/daedtech.com\\\/\",\"name\":\"DaedTech\",\"description\":\"Stories about Software\",\"publisher\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/daedtech.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\",\"name\":\"DaedTech LLC\",\"url\":\"https:\\\/\\\/daedtech.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/daedtech.com\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/SmallLogo.jpg\",\"contentUrl\":\"https:\\\/\\\/daedtech.com\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/SmallLogo.jpg\",\"width\":82,\"height\":84,\"caption\":\"DaedTech LLC\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/person\\\/3dae63e91a0fa60c8051a2171fa687d2\",\"name\":\"Erik Dietrich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"caption\":\"Erik Dietrich\"},\"sameAs\":[\"https:\\\/\\\/daedtech.com\"],\"url\":\"https:\\\/\\\/daedtech.com\\\/author\\\/erik\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Factory Method - DaedTech","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/daedtech.com\/factory-method\/","twitter_card":"summary_large_image","twitter_title":"Factory Method - DaedTech","twitter_description":"Quick Information\/Overview Pattern Type Creational Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Moderate &#8212; slightly easier than Abstract Factory Up Front Definitions Creator:\u00a0This is the basic, abstract factory interface. Concrete Creator: Inheritor factory classes that implement some actual object creation scheme. Product: This is the base\/abstract polymorphic object that gets created by...","twitter_image":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif","twitter_misc":{"Written by":"Erik Dietrich","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/daedtech.com\/factory-method\/#article","isPartOf":{"@id":"https:\/\/daedtech.com\/factory-method\/"},"author":{"name":"Erik Dietrich","@id":"https:\/\/daedtech.com\/#\/schema\/person\/3dae63e91a0fa60c8051a2171fa687d2"},"headline":"Factory Method","datePublished":"2012-11-30T07:03:18+00:00","dateModified":"2015-06-30T06:37:41+00:00","mainEntityOfPage":{"@id":"https:\/\/daedtech.com\/factory-method\/"},"wordCount":2635,"commentCount":5,"publisher":{"@id":"https:\/\/daedtech.com\/#organization"},"image":{"@id":"https:\/\/daedtech.com\/factory-method\/#primaryimage"},"thumbnailUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif","articleSection":["Design Patterns"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/daedtech.com\/factory-method\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/daedtech.com\/factory-method\/","url":"https:\/\/daedtech.com\/factory-method\/","name":"Factory Method - DaedTech","isPartOf":{"@id":"https:\/\/daedtech.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/daedtech.com\/factory-method\/#primaryimage"},"image":{"@id":"https:\/\/daedtech.com\/factory-method\/#primaryimage"},"thumbnailUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif","datePublished":"2012-11-30T07:03:18+00:00","dateModified":"2015-06-30T06:37:41+00:00","breadcrumb":{"@id":"https:\/\/daedtech.com\/factory-method\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/daedtech.com\/factory-method\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/daedtech.com\/factory-method\/#primaryimage","url":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif","contentUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/factory.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/daedtech.com\/factory-method\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/daedtech.com\/"},{"@type":"ListItem","position":2,"name":"Factory Method"}]},{"@type":"WebSite","@id":"https:\/\/daedtech.com\/#website","url":"https:\/\/daedtech.com\/","name":"DaedTech","description":"Stories about Software","publisher":{"@id":"https:\/\/daedtech.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/daedtech.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/daedtech.com\/#organization","name":"DaedTech LLC","url":"https:\/\/daedtech.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/daedtech.com\/#\/schema\/logo\/image\/","url":"https:\/\/daedtech.com\/wp-content\/uploads\/2015\/07\/SmallLogo.jpg","contentUrl":"https:\/\/daedtech.com\/wp-content\/uploads\/2015\/07\/SmallLogo.jpg","width":82,"height":84,"caption":"DaedTech LLC"},"image":{"@id":"https:\/\/daedtech.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/daedtech.com\/#\/schema\/person\/3dae63e91a0fa60c8051a2171fa687d2","name":"Erik Dietrich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","caption":"Erik Dietrich"},"sameAs":["https:\/\/daedtech.com"],"url":"https:\/\/daedtech.com\/author\/erik\/"}]}},"_links":{"self":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts\/2117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/comments?post=2117"}],"version-history":[{"count":0,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts\/2117\/revisions"}],"wp:attachment":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/media?parent=2117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/categories?post=2117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/tags?post=2117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}