{"id":251,"date":"2011-07-01T00:19:19","date_gmt":"2011-07-01T00:19:19","guid":{"rendered":"https:\/\/daedtech.wpenginepowered.com\/?p=251"},"modified":"2015-06-30T03:45:40","modified_gmt":"2015-06-30T08:45:40","slug":"abstract-factory","status":"publish","type":"post","link":"https:\/\/daedtech.com\/abstract-factory\/","title":{"rendered":"Abstract Factory"},"content":{"rendered":"<h3>Introduction<\/h3>\n<p>This is going to be the first post in a new series that I\u2019m doing on design patterns.  Now, I\u2019m certainly not the first person to post a taxonomy of design patterns and explain them, but I would like to put a different spin on the usual.  Normally, I see postings that contain a UML diagram and then verbiage like \u201cencapsulates indirection in a creational paradigm between concrete implementers and\u2026.\u201d  To put it another way, I see definitions that are useful if and only if you already know the definition.  So, my idea here is to relate the design patterns in the context of a sto<!--more-->ry rather than a stuffy-sounding taxonomy.  Why do people do this?  What problem does it solve?  Why is my code potentially worse if I don\u2019t do this?  <\/p>\n<p>Toward that end, my tone will tend toward the narrative and conversational here, and I\u2019m hoping that people will find this useful.  I will also tend to favor the practical over the pedantically\/academically correct.  This is a field guide to design patterns.<\/p>\n<h3>Quick Information\/Overview<\/h3>\n<table>\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>Hard to wrap your head around at first, easy enough to implement<\/td>\n<\/table>\n<h3>Up Front Definitions<\/h3>\n<p>I\u2019m going to define a few terms in advance that will make this post easier to understand.  These apply to the remainder of this post.<\/p>\n<ol>\n<li>Context&#8211;A broad scenario in an application, such as, \u201care we using a MySQL or SQL Server database?\u201d or, \u201care we logging on errors or exiting the application?\u201d<\/li>\n<li>Polymorph&#8211;In this post, I\u2019ll use this term specifically to mean an interface implementer or a subclass of a base.<\/li>\n<\/ol>\n<h3>The Problem<\/h3>\n<p>Let\u2019s say that you\u2019re gearing up for a new car purchase, and, because you\u2019re a coder by identity and not by job description, you write a little utility to track average purchase price of recent sales.  Like most car purchasers, you\u2019re not sure what car you want to buy, or even what manufacturer and form factor.  That is, you may decide to go with a Ford Explorer, but you might also want a Honda Civic or a smart car.  You\u2019re keeping your options open.<\/p>\n<p>As a good C# and object-oriented programmer, you realize that there is a lot of commonality in cars that can be shared in a polymorphic object structure.  So, in design and prototyping, you create an abstract Automobile base class and abstract inheritors like \u201cSUV\u201d, \u201cSports\u201d, and \u201cSedan\u201d.  Now, with this object structure, Explorer is going to inherit from SUV and, let\u2019s say, have a property called \u201cManufacturer\u201d that initializes to \u201cFord.\u201d<\/p>\n<pre lang=\"C#\">\r\n\r\npublic class Explorer : Suv\r\n{\r\n    private const int DefaultPrice = 25000;\r\n\r\n    public Explorer()\r\n    {\r\n        Manufacturer = \"Ford\";\r\n        Price = DefaultPrice;\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>For your purposes, car is an entity that represents concepts like \u201cprice,\u201d \u201cwarranty,\u201d \u201cConsumer Reports Rating,\u201d etc.  That is, the abstraction for this application\u2019s purposes does not represent things like \u201cStart()\u201d or \u201cChangeOil()\u201d.  The reason I mention this is that having, say, \u201cEscape\u201d by Ford and \u201cTribute\u201d by Mazda be two different classes is important in this abstraction where it wouldn\u2019t be in the physical one since those two cars are more or less the same, physically.<\/p>\n<p>Now, let\u2019s think in terms of the application how these objects get created.  Presumably, you write some web crawling utility that looks for sale prices and other information and collects them in local persistence such as a file or a database.  From there, when you launch the utility, you have some kind of service that reads the file\/db and massages the data into a format that interests you (average price, standard warranty duration, etc.)  Let\u2019s also say that one of the screens offered is one in which you first choose a make of car and then are able to see all models of that manufacturer.  Your context is car manufacturer, and, based on that context, you create a different set of polymorphs.<\/p>\n<p>Think of the most basic way that might go.  Somewhere in the presentation tier (ViewModel, code-behind, etc), we\u2019re going to receive information from the service and build our objects:<\/p>\n<pre lang=\"C#\">\r\n\r\npublic partial class MainWindow : Window\r\n{\r\n    ICarFactory _factory;\r\n        \r\n    private List<Automobile> _cars = new List<Automobile>();\r\n\r\n\r\n    public MainWindow()\r\n    {\r\n        InitializeComponent();\r\n        BuildCar(\"Ford\"); \/\/Use ford by default until\/unless user changes it\r\n    }\r\n\r\n    private void BuildCar(string makerName)\r\n    {\r\n        _cars.Add(BuildCar(makerName, ModelType.Sedan));\r\n        _cars.Add(BuildCar(makerName, ModelType.Sports));\r\n        _cars.Add(BuildCar(makerName, ModelType.Sports));\r\n    }\r\n\r\n    public Automobile BuildCar(string makerName, ModelType type)\r\n    {\r\n        switch (makerName)\r\n        {\r\n            case \"Ford\":\r\n                switch (type)\r\n                {\r\n                    case ModelType.Sedan: return new Focus();\r\n                    case ModelType.Sports: return new Mustang();\r\n                    case ModelType.Suv: return new Explorer();\r\n                    default: return null;\r\n                }\r\n            case \"Chevy\":\r\n                switch (type)\r\n                {\r\n                    case ModelType.Sedan: return new Malibu();\r\n                    case ModelType.Sports: return new Camaro();\r\n                    case ModelType.Suv: return new Tahoe();\r\n                    default: return null;\r\n                }\r\n            default:\r\n                return null;\r\n        }\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>You might think that we could just have one giant, non-nested switch over model, but we\u2019re allowing for the (albeit remote) possibility that two auto manufacturers have the same model name.  Also, I&#8217;m not passing in information about price or anything like that here, for the sake of clarity.  In this example, assume that whoever calls the build method fills in those details.<\/p>\n<p>So what\u2019s wrong with this code?  Well, for starters, it\u2019s ugly, but aesthetics is hardly grounds for a refactoring or reconsideration.  But in this case, the ugliness represents a code smell.  And the code smell in question is brittleness.  This is a piece of code in code-behind or a ViewModel, and the design here is such that, each and every time we want to add a new model of car, we have to open this class up and modify it.  Presentation tier classes should change when the logic for managing the GUI state changes, not when the application receives more data.  What we have here is an egregious violation of the open\/closed principle.  <\/p>\n<h3>So, What to Do?<\/h3>\n<p>The first thing we could do is pull this code out of the code-behind\/ViewModel and put it into a class called \u201cCarFactory\u201d.  The code-behind\/ViewModel would then have a reference to a car factory and would not need to change as a result of the logic for constructing cars changing.  With that in place, let\u2019s think about potential inefficiencies.  What we have is a factory class with two levels of switch statements.  So, every time you add a car model, you have to change the factory method, and every time you add a car make, such as when Kia comes into existence, you have to add a whole bunch of code to the factory (an outer case and a bunch of inner cases).  You&#8217;re picking your poison between adding a little code to a lot of statements or a lot of code to one statement.<\/p>\n<pre lang=\"C#\">\r\n\r\npublic class CarFactory\r\n{\r\n    public Automobile BuildCar(string makerName, ModelType type)\r\n    {\r\n        switch (makerName)\r\n        {\r\n            case \"Ford\":\r\n                switch (type)\r\n                {\r\n                    case ModelType.Sedan: return new Focus();\r\n                    case ModelType.Sports: return new Mustang();\r\n                    case ModelType.Suv: return new Explorer();\r\n                    default: return null;\r\n                }\r\n            case \"Chevy\":\r\n                switch (type)\r\n                {\r\n                    case ModelType.Sedan: return new Malibu();\r\n                    case ModelType.Sports: return new Camaro();\r\n                    case ModelType.Suv: return new Tahoe();\r\n                    default: return null;\r\n                }\r\n            default:\r\n                return null;\r\n        }\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>Now, let\u2019s improve it by using some polymorphism on the context instead of just on the polymorphs.  I\u2019m going to write a new class called ICarFactory and define implementers FordFactory and ChevyFactory.  In the ICarFactory, we\u2019re going to define a contract for building an SUV, a Sedan, and a Sports.  So Ford\u2019s implementation will return an Explorer, Focus, and a Mustang, while Chevy will return Tahoe, Malibu, and Camaro, respectively.  <\/p>\n<pre lang=\"C#\">\r\n\r\npublic interface ICarFactory\r\n{\r\n    public Automobile GetCar(ModelType type);\r\n}\r\n\r\n<\/pre>\n<pre lang=\"C#\">\r\n\r\npublic class FordFactory : ICarFactory\r\n{\r\n    public Automobile GetCar(ModelType type)\r\n    {\r\n        switch (type)\r\n        {\r\n            case ModelType.Sedan: return new Focus();\r\n            case ModelType.Sports: return new Mustang();\r\n            case ModelType.Suv: return new Explorer();\r\n            default: return null;\r\n        }\r\n    }\r\n}\r\n\r\n<\/pre>\n<pre lang=\"C#\">\r\n\r\npublic class ChevyFactory : ICarFactory\r\n{\r\n    public Automobile GetCar(ModelType type)\r\n    {\r\n        switch (type)\r\n        {\r\n            case ModelType.Sedan: return new Malibu();\r\n            case ModelType.Sports: return new Camaro();\r\n            case ModelType.Suv: return new Tahoe();\r\n            default: return null;\r\n        }\r\n    }\r\n}\r\n\r\n<\/pre>\n<pre lang=\"C#\">\r\n\r\npublic partial class MainWindow : Window\r\n{\r\n    ICarFactory _factory;\r\n        \r\n    private List<Automobile> _cars = new List<Automobile>();\r\n\r\n\r\n    public MainWindow()\r\n    {\r\n        InitializeComponent();\r\n        BuildFactory(\"Ford\"); \/\/Default to Ford until the user selects something else\r\n        BuildCars();\r\n    }\r\n\r\n    public void BuildFactory(string makerName)\r\n    {\r\n\r\n        if (makerName == \"Ford\")\r\n        {\r\n            _factory = new FordFactory();\r\n        }\r\n        else if (makerName == \"Chevy\")\r\n        {\r\n            _factory = new ChevyFactory();\r\n        }\r\n    }\r\n\r\n    public void BuildCars()\r\n    {\r\n        _cars.Add(_factory.GetCar(ModelType.Sedan));\r\n        _cars.Add(_factory.GetCar(ModelType.Sports));\r\n        _cars.Add(_factory.GetCar(ModelType.Suv));\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>The power of this is that we can figure out which make we want and let the manufacturer implementations define what objects they\u2019re going to create.  By having context polymorphism, we separate context creation from polymorph creation.  This implementation is far less brittle than what we had before.  The factories change only when their particular versions of the model change.  If I add a new model called &#8220;Crossover&#8221; and only Chevy has one, I don&#8217;t have to edit the Ford factory.  If I add an entirely new manufacturer, like Mazda, I just create the Mazda classes and a new Mazda factory.  The only existing code I need to touch is in the BuildFactory() method where I add a case.  (BuildFactory() should probably be its own class or somehow settable\/injectable into our class here, but I&#8217;m trying to condense a bit for illustration purposes.)<\/p>\n<h3>A More Official Explanation<\/h3>\n<p>Abstract Factory gives us the power to partition object (polymorph) creation that is hierarchical in nature.  You have one place that context creation is done and another that polymorph creation is done.  In our example, when we create cars, we first decide who the maker is and then we decide, based on the maker, what the model is.  That hierarchical, context-based creation paradigm is the first requisite element for the Abstract Factory pattern.  The second requisite element is that our decision hierarchy results in the same type of object, depending on the first decision. In our example, whether you pick Ford, Chevy, etc., all will have a Sports object and an SUV object (or null).<\/p>\n<p>In other words, the Abstract Factory pattern is appropriate when you have object families, and, in different contexts, you want different families.  Chevy context corresponds to one set of {SUV, Coupe, Sports} polymorphs and Ford to another one.  You cannot encapsulate, say, Toshiba in this Abstract Factory implementation and return polymorphs of type {VCR, Television}.  The returned objects have to be familial variations on the same object.  The general form of this is that you have some set of contexts (say, c1, c2\u2026 cn) and some set of polymorphs (foo, bar, baz, etc), and for each context\/polymorph pair, you have some concrete inheritor.  So, you have c1Foo, c2Foo \u2026 cnFoo, c1Bar, c2Bar, cnBar, c1Baz, c2Baz, \u2026 cnBaz.  <\/p>\n<p>A good, quick way to think of this is that Abstract Factory is suitable for situations where groups of inheritors are always found together or not at all in the context in which you are operating.  In our case, in a window displaying Fords, you wouldn\u2019t randomly find a Toyota Corolla.  You\u2019re getting a Focus or you\u2019re getting null.  Logically, this constraint already exists in the design spec.  The Abstract Factory pattern simply puts this form into class-method form instead of case statement-nested case statement form.<\/p>\n<h3>Other Quick Examples<\/h3>\n<p>To cement the understanding here, let\u2019s consider a few other scenarios in which Abstract Factory would be appropriate:<\/p>\n<ol>\n<li>You are reading and writing to persistent storage from an application, and you have two abstract entities, Reader and Writer.  You might define MySqlReader, MySqlWriter, SqlServerReader, SqlServerWriter, and FileReader, FileWriter.  Then, you\u2019d define IPersistenceFactory with GetReader() and GetWriter() methods and your MySqlPersistenceFactory, SqlServerPersistenceFactory, and FilePersistenceFactory would all return their respective objects from their two-member families.<\/li>\n<li>You have a GUI that you want to display different color buttons, text boxes, etc., depending on the gender of the person logged in.  Everything should be blue for males and pink for females.  You define IControlFactory with inheritors MaleControlFactory and FemaleControlFactory that return inheritors of Button, TextBox, etc.  So, depending on the gender of the user, you select that gender\u2019s factory and depend on it for supplying the appropriate controls.<\/li>\n<\/ol>\n<h3>A Good Fit \u2013 When to Use<\/h3>\n<p>Now that we\u2019ve identified a few examples of when this might be a reasonable pattern to use, let\u2019s generalize a bit.  Here are some heuristics for when you can or should use the Abstract Factory pattern.<\/p>\n<ol>\n<li>\nThe Abstract Factory pattern is a good one to keep in mind any time you find yourself creating one set of inheritors in one context and another set in another context.  Usually, you can see a good opportunity to use this when you have large switch blocks and\/or nested switch blocks inside of which you\u2019re mainly creating object polymorphs.<\/li>\n<li>In addition, you might consider this pattern preemptively rather than as a refactoring when you\u2019ve got requirements and\/or a design that implies making the same creational decision over and over when creating subclassed objects.  That is, you\u2019re looking at a design and seeing that you need A-related objects a third of the time, B-related objects a third of the time, and C-related objects a third of the time because broader contexts A, B, and C happen a third of the time each.  This is appropriate when your requirements practically guarantee that you&#8217;re going to be adding more contexts later.  We&#8217;re going to revisit this in the &#8220;don&#8217;t use&#8221; section with a subtle distinction.<\/li>\n<\/ol>\n<h3>Square Peg, Round Hole \u2013 When Not to Use<\/h3>\n<p>I think it\u2019s just as important to address when not to use a pattern as when to use it.  A lot of people encounter a design pattern or a technique for solving problems in general and get the \u201cgolden hammer\u201d syndrome&#8211;every problem looks like a nail because of the expensive new hammer.  So when is Abstract Factory not appropriate?<\/p>\n<ol>\n<li>\nI touched on it a bit earlier, but you do not want to use the Abstract Factory creational pattern when the contexts are not related.   You wouldn\u2019t create an Abstract Factory to encapsulate creation of televisions and VCRs if the manufacturer was Toshiba and SUVs and Sports cars if the manufacturer was Ford.  Even if you did create an inheritance structure that had television and SUV inheriting from the same base class in order to make this work (after all, in C#, they both technically inherit from object), the abstraction would be an incomprehensible nightmare.  The result would be that when you got this \u201cobject\u201d that might be either a television or a car, you would invariably use the \u201cis\u201d or \u201cas\u201d operator to figure out which it was, and that defeats the entire purpose of the pattern.  The context polymorphism is designed to allow you to perform operations on the objects returned from the factory without caring which specific objects they are.\n<\/li>\n<li>\nYou also don\u2019t want to use this pattern if you don&#8217;t have any context.  Imagine that we decided we had narrowed our search down to only Fords and were choosing between Ford models.  The context becomes pointless and the Abstract Factory an unnecessary abstraction.  We gain nothing with Abstract Factory that we couldn&#8217;t get by simply having FordFactory.  This is another, distinct pattern that I&#8217;ll get to later called Factory Method.  In the &#8220;good fit&#8221; section, I suggested using Abstract Factory if you&#8217;re pretty sure you&#8217;re going to need it.  But, if you don&#8217;t think you will, or you aren&#8217;t sure, you&#8217;re better off following the <a href=\"http:\/\/en.wikipedia.org\/wiki\/You_ain't_gonna_need_it\">YAGNI <\/a> principle.\n<\/li>\n<li>\nFinally, don&#8217;t use this if you don&#8217;t have a polymorphic structure.  You can try setting it all up, but you&#8217;ll find that you won&#8217;t be able to implement this pattern if your created objects don&#8217;t have a common ancestor or interface.  You could, theoretically, return object or create some interface that the objects inherit just to create them this way, but I promise you that will be a headache.  If they don&#8217;t naturally share functionality, you don&#8217;t want to create them this way, as you&#8217;ll just wind up casting them back to their original state to figure out how to use them.  And that defeats the entire purpose of polymorphism.  Don&#8217;t try to create things with an Abstract Factory just to use one.\n<\/li>\n<\/ol>\n<h3>So What?  Why is this Better?<\/h3>\n<p>I&#8217;ve touched on this throughout, but I&#8217;ll summarize it here.  Without Abstract Factory, you&#8217;ll have either inline creation logic or creation logic that makes more decisions in one place than it should.  The <a href=\"http:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\">single responsibility principle <\/a> advises that classes should only have one reason to change: for the purposes of easy maintainability.  <\/p>\n<p>Inlining object creation is a subject unto itself, but suffice it to say that it comes with problems.  Good luck testing a class that creates a bunch of objects and then uses them.  And good luck maintaining it.  In our example, once your ViewModel class starts keeping track of the UI and also keeping track of car creation, it will get messy.  You&#8217;ll change the view model to accommodate a growing UI.  You&#8217;ll change the view model to accommodate a growing corpus of data.  The two functionalities will start blending together in the one place, and changes for the sake of one will start to break the other functionality&#8211;not to mention that, if you want to swap in a new object creation scheme or UI scheme, you&#8217;ll have to detangle the two.<\/p>\n<p>And, in the same vein, Abstract Factory versus plain factory, when there are multiple contexts, decouples even further.  The logic for car context is separate from the logic for individual car creation.  You could employ different factory creation schemes if you decide you want multiple ways of generating Fords without loading the factories down with conditionals.<\/p>\n<p>Generally speaking, decoupling the code is good for a number of reasons.  The Abstract Factory pattern is simply a well-recognized and tried-and-true way of doing this.  Used properly, it will help you have maintainable code and code in which new requirements being added means adding classes\/methods rather than editing existing ones and opening yourself up to regressions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This is going to be the first post in a new series that I\u2019m doing on design patterns. Now, I\u2019m certainly not the first person to post a taxonomy of design patterns and explain them, but I would like to put a different spin on the usual. Normally, I see postings that contain a&#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":[67,25],"tags":[10,3],"class_list":["post-251","post","type-post","status-publish","format-standard","hentry","category-net","category-design-patterns","tag-c","tag-software-engineering"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Abstract Factory - 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\/abstract-factory\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Abstract Factory - DaedTech\" \/>\n<meta name=\"twitter:description\" content=\"Introduction This is going to be the first post in a new series that I\u2019m doing on design patterns. Now, I\u2019m certainly not the first person to post a taxonomy of design patterns and explain them, but I would like to put a different spin on the usual. Normally, I see postings that contain a...\" \/>\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=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/\"},\"author\":{\"name\":\"Erik Dietrich\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/person\\\/3dae63e91a0fa60c8051a2171fa687d2\"},\"headline\":\"Abstract Factory\",\"datePublished\":\"2011-07-01T00:19:19+00:00\",\"dateModified\":\"2015-06-30T08:45:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/\"},\"wordCount\":2733,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\"},\"keywords\":[\"C#\",\"Software Engineering\"],\"articleSection\":[\".NET\",\"Design Patterns\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/\",\"url\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/\",\"name\":\"Abstract Factory - DaedTech\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#website\"},\"datePublished\":\"2011-07-01T00:19:19+00:00\",\"dateModified\":\"2015-06-30T08:45:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/abstract-factory\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/daedtech.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Abstract Factory\"}]},{\"@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":"Abstract Factory - 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\/abstract-factory\/","twitter_card":"summary_large_image","twitter_title":"Abstract Factory - DaedTech","twitter_description":"Introduction This is going to be the first post in a new series that I\u2019m doing on design patterns. Now, I\u2019m certainly not the first person to post a taxonomy of design patterns and explain them, but I would like to put a different spin on the usual. Normally, I see postings that contain a...","twitter_misc":{"Written by":"Erik Dietrich","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/daedtech.com\/abstract-factory\/#article","isPartOf":{"@id":"https:\/\/daedtech.com\/abstract-factory\/"},"author":{"name":"Erik Dietrich","@id":"https:\/\/daedtech.com\/#\/schema\/person\/3dae63e91a0fa60c8051a2171fa687d2"},"headline":"Abstract Factory","datePublished":"2011-07-01T00:19:19+00:00","dateModified":"2015-06-30T08:45:40+00:00","mainEntityOfPage":{"@id":"https:\/\/daedtech.com\/abstract-factory\/"},"wordCount":2733,"commentCount":2,"publisher":{"@id":"https:\/\/daedtech.com\/#organization"},"keywords":["C#","Software Engineering"],"articleSection":[".NET","Design Patterns"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/daedtech.com\/abstract-factory\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/daedtech.com\/abstract-factory\/","url":"https:\/\/daedtech.com\/abstract-factory\/","name":"Abstract Factory - DaedTech","isPartOf":{"@id":"https:\/\/daedtech.com\/#website"},"datePublished":"2011-07-01T00:19:19+00:00","dateModified":"2015-06-30T08:45:40+00:00","breadcrumb":{"@id":"https:\/\/daedtech.com\/abstract-factory\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/daedtech.com\/abstract-factory\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/daedtech.com\/abstract-factory\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/daedtech.com\/"},{"@type":"ListItem","position":2,"name":"Abstract Factory"}]},{"@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\/251","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=251"}],"version-history":[{"count":0,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts\/251\/revisions"}],"wp:attachment":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/media?parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/categories?post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/tags?post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}