<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ketki Ambekar</title>
    <description>The latest articles on Forem by Ketki Ambekar (@ketkiambekar).</description>
    <link>https://forem.com/ketkiambekar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F550902%2F5b52c991-919d-45a6-ad94-cd952ffaca08.jpeg</url>
      <title>Forem: Ketki Ambekar</title>
      <link>https://forem.com/ketkiambekar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ketkiambekar"/>
    <language>en</language>
    <item>
      <title>An Enum Alternative to the Factory Pattern: The Pros, Cons, and Hidden Dangers (in the voice of Rita Skeeter)</title>
      <dc:creator>Ketki Ambekar</dc:creator>
      <pubDate>Thu, 04 Sep 2025 02:37:21 +0000</pubDate>
      <link>https://forem.com/ketkiambekar/an-enum-alternative-to-the-factory-pattern-the-pros-cons-and-hidden-dangers-in-the-voice-of-boj</link>
      <guid>https://forem.com/ketkiambekar/an-enum-alternative-to-the-factory-pattern-the-pros-cons-and-hidden-dangers-in-the-voice-of-boj</guid>
      <description>&lt;p&gt;I wrote &lt;a href="https://dev.toAn%20Enum%20Alternative%20to%20the%20Factory%20Pattern:%20The%20Pros,%20Cons,%20and%20Hidden%20Dangers"&gt;a blog post&lt;/a&gt; earlier today. During my usual AI checks, I asked Gemini if it could reframe my article in the voice of &lt;a href="https://harrypotter.fandom.com/wiki/Rita_Skeeter" rel="noopener noreferrer"&gt;Rita Skeeter&lt;/a&gt;'s quill. &lt;/p&gt;

&lt;p&gt;The result was way too cool not to publish. So here's the same article in the voice of Rita Skeeter's quill: &lt;/p&gt;

&lt;h1&gt;
  
  
  Unmasking the Enigma of Object Creation: A Glimpse Behind the Program's Veil
&lt;/h1&gt;

&lt;p&gt;One often wonders, in the hallowed halls of coding, what dark arts or cunning sorcery truly govern the birth of objects. We speak, of course, of the very essence of a program: its data ingestion. From the most mundane text dumps to the clandestine whispers from XML gateways, or even the sprawling, often scandalous, SQL data dumps – how precisely does a program select its next meal, its very source of truth?&lt;/p&gt;

&lt;p&gt;It is whispered, among those who claim to know, that an &lt;code&gt;IDataReader&lt;/code&gt; interface serves as a mere disguise, a super-type behind which myriad concrete classes hide their true nature. But how does one truly choose which masked player takes the stage to gather the precious data? Ah, dear reader, therein lies a tale...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Grand Old Factory:&lt;/strong&gt; A Rather Obvious, Yet Pervasive, Method&lt;br&gt;
For decades, the engineering world has clung to a rather unimaginative approach: the Factory Pattern. A concept so straightforward, it barely warrants the title of "pattern." Imagine, if you will, a bustling (or perhaps, rust-covered and grimy) factory floor, where a designated "foreman" – a Factory class – is tasked with the rather pedestrian job of deciding which specific &lt;code&gt;IDataReader&lt;/code&gt; to churn out.&lt;/p&gt;

&lt;p&gt;A simple &lt;code&gt;readerType&lt;/code&gt; variable, perhaps a whisper from an API call, or even a coded decree, dictates the foreman's action. Observe the rather blunt instrument of its logic below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//C# (One shudders to think how many such simple constructs exist)&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FactoryPatternEnumDemo.DataReaders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FactoryPatternEnumDemo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="nf"&gt;GetDataReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;readerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"CSV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CSVReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"XML"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XMLReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"JSON"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JSONReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"DBReader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DBReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AnyTextReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderClient&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;   
        &lt;span class="c1"&gt;//A rather uninspired creation via a Factory Class&lt;/span&gt;
        &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="n"&gt;dataReader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataReaderFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDataReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A switch statement! One almost expects a polite curtsy with such predictability. This "Factory" merely serves as a glorified sorting hat, dispatching objects with a minimum of flair. And yet, its proponents claim it has its virtues...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Enigmatic Enum:&lt;/strong&gt; A Whisper of Modernity, a Promise of Terse Elegance&lt;br&gt;
But what if, dear reader, there was another way? A path less trodden, where the very names of our data readers hold the key to their own creation? Imagine an Enum, seemingly innocent, adorned with secret annotations, each a cryptic clue to the true identity of the class it represents. A method so terse, so... modern, that it bypasses the need for an entire dedicated Factory class!&lt;/p&gt;

&lt;p&gt;One simply invokes a generic, reusable extension method – a mere incantation – to pry open the enum's hidden truths and summon forth the desired &lt;code&gt;IDataReader&lt;/code&gt;. Let us gaze upon this audacious display of object conjuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//C# (One must admit, a certain theatricality in this approach)&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;DataReadersEnum&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.CsvReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Csv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumEnumDemo.DataReaders.JsonReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.XmlReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.DbReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.AnyTextReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;AnyText&lt;/span&gt;    
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;DataReadersEnum&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;FieldInfo&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;()?.&lt;/span&gt;&lt;span class="nf"&gt;GetField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCustomAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderClient&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;   
        &lt;span class="c1"&gt;//Oh, the intrigue! Object creation using the secrets hidden within the Enum's annotations&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dataReaderClassName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataReadersEnum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetClassName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Note the fix to DataReadersEnum&lt;/span&gt;
        &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataReaderClassName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="n"&gt;dataReader2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDataReader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Activator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A slight correction in the code snippet above, as the infamous quill often errs in its haste to reveal a juicy detail.&lt;/p&gt;

&lt;p&gt;This method, so deceptively simple, promises dynamic object creation through the arcane art of Reflection. But, dear reader, does brevity truly equate to brilliance? Or does a more sinister truth lurk beneath its gleaming surface? We shall now compare these two contenders, exposing their strengths and weaknesses for all to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Factory Pattern:&lt;/strong&gt; Its Unflappable Virtues (And its Mundane Flaws)
&lt;/h2&gt;

&lt;p&gt;Let us not be entirely dismissive of the old guard. The Factory Pattern, despite its lack of dramatic flourish, offers certain undeniable advantages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Cloak of Decoupling:&lt;/strong&gt; It shrewdly separates the client from the nitty-gritty of object instantiation. One need not dirty one's hands with the specifics, leaving the main code blissfully ignorant of how its data readers are truly born.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Unbreakable Vows of SOLID:&lt;/strong&gt; This pattern, it is said, adheres to the sacred principles:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single Responsibility:&lt;/strong&gt; The client merely uses objects; the factory creates them. A clear division of labor, one might say, quite unlike some of the more... multitasking individuals we've encountered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open/Closed:&lt;/strong&gt; One merely adds another case to the venerable switch statement to extend its functionality. No need to disturb the existing, established order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Injection:&lt;/strong&gt; It plays rather nicely with this concept, allowing for a more controlled environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Economy of Repetition:&lt;/strong&gt; Why repeat oneself when a single factory can handle the chorus of object creation? The DRY principle, they call it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Predictable Pedigree:&lt;/strong&gt; Objects are born in a centralized, almost clinical, environment. One can ascertain their behavior at compile time, eliminating any "sudden surprises" that might disrupt a well-ordered program. All in all, rather easy to maintain and, dare I say, test.&lt;/p&gt;

&lt;p&gt;But even the most steadfast of institutions have their detractors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Unnecessary Extra Class:&lt;/strong&gt; For those who prefer minimalist elegance, an entire extra class just for creation seems... superfluous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Shadow of Modern DI:&lt;/strong&gt; While it supports Dependency Injection, some whisper that it's a tad old-fashioned compared to the sleek, automated offerings of modern DI frameworks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Looming 'God' Factory:&lt;/strong&gt; A terrifying prospect indeed! As an application expands, this single factory can balloon into a monstrous entity, a central nexus of change that becomes an unbearable burden. A maintenance nightmare, pure and simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Enum Technique: A Dazzling Promise, A Hidden Peril?
&lt;/h2&gt;

&lt;p&gt;Now, for the dazzling newcomer. The Enum technique, with its air of effortless grace, certainly makes a grand entrance:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Illusion of Open/Closed:&lt;/strong&gt; Ah, here's the true allure! One simply adds a new entry to the enum, whispers a new class name into its description, and voilà! No messy switch statements to disturb. The core creation logic remains untouched, seemingly "closed for modification." A truly elegant sleight of hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Promise of Terse Code:&lt;/strong&gt; The sheer lack of explicit case statements does indeed present an image of reduced boilerplate, particularly for those who admire conciseness above all else.&lt;/p&gt;

&lt;p&gt;But, dear reader, peel back the layers of this dazzling façade, and a more troubling truth emerges:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fragile Threads of Type Safety:&lt;/strong&gt; This delicate dance relies on the precarious string matching of data annotations. A simple rename, a careless typo in a class name, and your program descends into chaos—not with a reassuring compile-time shriek, but with a silent, insidious runtime failure. A bug, perhaps, that will only reveal itself when the lights go out, and the clients begin to scream. The IDE, that trusty sentinel, remains utterly oblivious to this impending doom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Performance Bog of Reflection:&lt;/strong&gt; To peer into the soul of an assembly, to pluck class names from the ether, requires Reflection. A technique whispered about with caution, for it is notoriously slow. Like wading through treacle while others fly, it can cause a "quadratic runtime" when least expected. Though some claim modern .NET has polished this particular dark art, the experienced will tell you: when in doubt, assume Reflection is slow. Especially when dealing with collections; one shudders to contemplate the potential for sluggish, unresponsive applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Labyrinth of Debugging:&lt;/strong&gt; When things inevitably go awry, tracing the ethereal path of Reflection is no task for the faint of heart, or indeed, the less seasoned eye. It demands a dry-run, a careful prodding of the beast, often leading to the inadvertent activation of sensitive code. Imagine, if you dare, an intern, brimming with naive curiosity, accidentally unleashing a torrent of ill-timed emails upon the entire production user base! A reputational catastrophe, all for the sake of a "terse" solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Conclusion: The Unvarnished Truth
&lt;/h3&gt;

&lt;p&gt;After this candid exposé, you, dear reader, will have undoubtedly arrived at the inescapable truth. While the Enum technique presents a tempting allure of brevity and dynamic flair, it is, in its essence, a treacherous anti-pattern. It sacrifices the robust predictability of type safety and the swift efficiency of direct instantiation for a fleeting illusion of simplicity.&lt;/p&gt;

&lt;p&gt;The Factory Pattern, though perhaps less dramatic, remains the recommended and dependable stalwart. It may introduce an extra class, it may require the occasional tweak to a switch statement, but it grants you the invaluable gifts of compile-time safety, predictable performance, and a codebase that won't send your debugging efforts into a reflective, quadratic spiral. One might even call it... responsible.&lt;/p&gt;

&lt;p&gt;One should, therefore, regard the dynamic object creation using Enums with the utmost suspicion. To use it is to invite chaos, to flirt with disaster. Practicality dictates: you can safely and practically read that as 'never'.&lt;/p&gt;

&lt;p&gt;The working demo of the code discussed in this rather enlightening article can be obtained, for your own investigations, at &lt;a href="https://github.com/ketkiambekar/FactoryPatternEnumDemo" rel="noopener noreferrer"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Got thoughts? I'd love to hear from you in the comment section below. And do bring your own scandalous revelations!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;© Ketki Ambekar 2025&lt;/p&gt;

</description>
      <category>programming</category>
      <category>designpatterns</category>
      <category>factorypattern</category>
      <category>csharp</category>
    </item>
    <item>
      <title>An Enum Alternative to the Factory Pattern: The Pros, Cons, and Hidden Dangers</title>
      <dc:creator>Ketki Ambekar</dc:creator>
      <pubDate>Wed, 03 Sep 2025 21:31:09 +0000</pubDate>
      <link>https://forem.com/ketkiambekar/an-enum-alternative-to-the-factory-pattern-the-pros-cons-and-hidden-dangers-41e5</link>
      <guid>https://forem.com/ketkiambekar/an-enum-alternative-to-the-factory-pattern-the-pros-cons-and-hidden-dangers-41e5</guid>
      <description>&lt;p&gt;The Factory Pattern is a go-to solution for creating objects, but what if there were a way to make it more flexible and scalable? Let's explore how an enum can be used to drive a dynamic object creation process.&lt;/p&gt;

&lt;p&gt;Say you have a program that wants to ingest some data. The said data could be read from a variety of sources and formats, like text dumps, PDF files, XML gateways, SQL data dumps, text scraped from websites, etc.&lt;/p&gt;

&lt;p&gt;With an interface &lt;code&gt;IDataReader&lt;/code&gt; as our super type, we could create a separate concrete class for reading each type of data. Let's talk about selecting the right concrete class for reading data in the calling client class.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Factory Pattern Technique:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Typically, you'd go about implementing this by creating a Factory class. To put it simply, it is a class that takes care of the logic by which we determine which object to create.  In the example below, we determine which concrete object of the &lt;code&gt;IDataReader&lt;/code&gt; type needs to be returned using a factory class that employs a switch logic. The driving variable of the switch statement, called &lt;code&gt;readerType&lt;/code&gt; could be configured or received through an API call, among other ways.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//C#&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FactoryPatternEnumDemo.DataReaders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FactoryPatternEnumDemo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="nf"&gt;GetDataReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;readerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"CSV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CSVReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"XML"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XMLReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"JSON"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JSONReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"DBReader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DBReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AnyTextReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderClient&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="c1"&gt;//Example of object creation via a Factory Class&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="n"&gt;dataReader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataReaderFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDataReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; 

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Enum Technique:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Another, and a comparatively terse technique for object creation, is the Enum method. We could achieve this using only the &lt;code&gt;DataReaderClient&lt;/code&gt; class, an Enum, and an extremely generic and reusable extension method to read the data annotations in an enum, without needing to create a separate Factory class. &lt;/p&gt;

&lt;p&gt;Let's see the implementation of that approach in the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//C#&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;DataReadersEnum&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.CsvReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Csv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt;  &lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.JsonReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt;  &lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.XmlReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt;  &lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.DbReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FactoryPatternEnumDemo.DataReaders.AnyTextReader"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;AnyText&lt;/span&gt; &lt;span class="err"&gt;  &lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;DataReadersEnum&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;FieldInfo&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;()?.&lt;/span&gt;&lt;span class="nf"&gt;GetField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCustomAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DescriptionAttribute&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataReaderClient&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;
          &lt;span class="c1"&gt;//Object creation using the data annotations in the Enum&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dataReaderClassName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DataReaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetClassName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataReaderClassName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;IDataReader&lt;/span&gt; &lt;span class="n"&gt;dataReader2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDataReader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Activator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: We could have used a placeholder type &amp;lt;T&amp;gt; in our extension method to make it more and truly generic, but for the sake of clarity and simplicity, we've kept it specific to the &lt;code&gt;DataReaderEnum&lt;/code&gt; in this article. &lt;/p&gt;

&lt;p&gt;This method allows us to create objects dynamically using reflection. Let's compare the two techniques along with their pros and cons. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Factory Pattern: The Pros&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Decoupling the calling class from concrete implementations.&lt;/strong&gt; By separating the logic of actually creating the classes from the rest of the flow of the code, we ensure that if we ever need to add more types &lt;code&gt;IDataReader&lt;/code&gt; classes, we need not touch the main calling code logic. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A SOLID-proof technique.&lt;/strong&gt; This structure of code upholds the relevant SOLID principles - the  &lt;em&gt;Single Responsibility Principle&lt;/em&gt; (the caller code is separated from object creation logic), the &lt;em&gt;Open/Closed Principle&lt;/em&gt; (we only need to add more cases to the switch statement to extend without modifying the existing statements), and the &lt;em&gt;Dependency Injection Principle&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DRY? Check!&lt;/strong&gt; DRY refers to the 'Don't Repeat Yourself' principle. The logic of object creation (the switch statement in our case) need not be repeated in multiple places where we need to create the &lt;code&gt;IDataReader&lt;/code&gt; object(s). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralized object creation&lt;/strong&gt; means that we are easily able to keep track of the objects that are created at runtime if we need to. The program runs in a highly controlled manner, and we can ascertain the behavior of the code at compile time to ensure there are no sudden surprises during runtime. &lt;/p&gt;

&lt;p&gt;All this makes our code super easy to maintain and test. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Factory Pattern: The Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;We end up creating extra classes.&lt;/strong&gt; There are some cases where this might be overkill. This can make the code harder to follow for someone new to the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Injection can be more complicated&lt;/strong&gt; and outdated than what is offered by modern DI frameworks (eg, Unity Containers), which often handle object creation and dependency management automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can lead to a 'God' factory.&lt;/strong&gt;  As an application grows, there's a risk of creating a single, massive factory class responsible for creating many different types of objects. This "God" factory becomes a central point of change and a maintenance nightmare. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Enum technique: The Pros&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Adherence to the Open/Closed Principle (in a different way):&lt;/strong&gt; This approach can be seen as highly "open for extension." You can add a new reader type simply by adding a new entry to the enum and creating the corresponding class. There is no question of modifying the factory's switch statement, which means the core creation logic remains "closed for modification."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduced Boilerplate for Simple Cases:&lt;/strong&gt; When the object creation logic is a straightforward one-to-one mapping from an identifier to a class, this approach can seem less verbose than a full-fledged factory. You avoid the explicit case statement for each type in the factory.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Enum Technique: The Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Loss of Type safety:&lt;/strong&gt; Making sure the data annotation descriptions do correspond to an actual module in the assembly is a delicate operation and requires thorough testing. The IDE fails to automatically refactor any renaming operations. Any renaming operations can result in bugs that are not immediately obvious and can take some time to track down. In contrast, errors of a similar nature can be caught during compile time while using the factory class. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Issues:&lt;/strong&gt; Anytime we use reflection in any scenario, we must exercise caution. Because reflection loops through all members of an assembly, we can inadvertently and often cause a quadratic runtime. The mantra is 'reflection is slow'. Although the reflection library was refactored in the .NET 8 release and is supposed to have made the operation speedier, when in doubt, stick to the aforementioned mantra. Especially when using it with any sort of collections. Much can be said about reflection; please be on the lookout for subsequent articles where we benchmark reflection libraries from different .NET frameworks and discuss use cases and best practices for it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hard to debug:&lt;/strong&gt; This is another side effect of using reflection. It's not straightforward to dry-run the code, especially for a less seasoned eye. Sometimes we are compelled to run the code to understand the flow of the code. We may inadvertently end up running some sensitive lines of code.  This can potentially escalate into a reputational nightmare for an organization, think of an intern accidentally sending an email to the production user base. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;In Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might have rightly concluded by now that the factory pattern is the recommended approach over dynamic object creation using Enums. The latter is actually an anti-pattern and should not be used unless there is a dire situation. While the Enum technique may look neat in trivial cases, in production scenarios, it usually creates more problems than it solves.&lt;/p&gt;

&lt;p&gt;The working demo of the code included in this article can be obtained at &lt;a href="https://github.com/ketkiambekar/FactoryPatternEnumDemo" rel="noopener noreferrer"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Got thoughts? I'd love to hear from you in the comment section below.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Found the article too boring? Read it here in the voice of &lt;a href="http://dev.to/ketkiambekar/an-enum-alternative-to-the-factory-pattern-the-pros-cons-and-hidden-dangers-in-the-voice-of-boj"&gt;Rita Skeeter&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt; © Ketki Ambekar 2025&lt;/p&gt;

</description>
      <category>oop</category>
      <category>programming</category>
      <category>designpatterns</category>
    </item>
  </channel>
</rss>
