Design Pattern in .NET 101 – Factory Method Pattern (Creational Pattern)
By admin on Jan 12, 2008 in .NET, Creational, Programming
Factory Method Pattern defines an interface for creating an object, but let subclasses decide which class to instantiate. It lets a class defer instantiation to subclasses.
E.g., I defined a abstract News class.
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { abstract class News { } }
Different kinds of news are defined..
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class AdNews:News { } }
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class FashionNews:News { } }
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class FinanceNews:News { } }
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class SportsNews:News { } }
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class WorldNews:News { } }
I defined the abstract factory class, Publication
using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace FactoryPattern { abstract class Publication { private ArrayList publishedNews = new ArrayList(); // Constructor calls abstract Factory method public Publication() { this.PublishNews(); } public ArrayList PublishedNews { get { return publishedNews; } } // Factory Method public abstract void PublishNews(); } }
In the Publication class, the factory method is called, but it is not implemented yet.
Newspaper and FashionMagazine extends Publication class.
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class NewsPaper:Publication { public override void PublishNews() { this.PublishedNews.Add(new AdNews()); this.PublishedNews.Add(new FashionNews()); this.PublishedNews.Add(new WorldNews()); this.PublishedNews.Add(new SportsNews()); this.PublishedNews.Add(new FinanceNews()); } } }
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class FashionMagazine:Publication { public override void PublishNews() { this.PublishedNews.Add(new AdNews()); this.PublishedNews.Add(new FashionNews()); } } }
To test it
using System; using System.Collections.Generic; using System.Text; namespace FactoryPattern { class Program { static void Main(string[] args) { Publication newsPaper = new NewsPaper(); Console.WriteLine(newsPaper.GetType().Name); foreach (News news in newsPaper.PublishedNews) { Console.WriteLine("-" + news.GetType().Name); } Console.WriteLine(); Publication fashionMagazine = new FashionMagazine(); Console.WriteLine(fashionMagazine.GetType().Name); foreach (News news in fashionMagazine.PublishedNews) { Console.WriteLine("-" + news.GetType().Name); } Console.Read(); } } }
The output
NewsPaper -AdNews -FashionNews -WorldNews -SportsNews -FinanceNews FashionMagazine -AdNews -FashionNews
Software Architect | May 27, 2009 | Reply
Unfortunately, this is not the factory pattern. This example simply demonstrates inheritance. The factory pattern is meant to encapsulate object instantiation within a single class, typically a singleton. This pattern is best used in conjunction with a common interface.
The following is a code example written using version 3.5 of the .net framework.
using System;
namespace ConsoleTestBed {
//Define common interface
public interface INewsArticle {
void DisplayArticleContent();
}
//Define abstract base class
public abstract class NewsArticleBase : INewsArticle {
public abstract void DisplayArticleContent();
}
//Define four derived classes
public class WorldNewsArticle : NewsArticleBase {
public override void DisplayArticleContent() {
Console.WriteLine(“World news content.”);
}
}
public class SportsNewsArticle : NewsArticleBase {
public override void DisplayArticleContent() {
Console.WriteLine(“Sports news content”);
}
}
public class FinanceNewsArticle : NewsArticleBase {
public override void DisplayArticleContent() {
Console.WriteLine(“Finance news content”);
}
}
public class FashionNewsArticle : NewsArticleBase {
public override void DisplayArticleContent() {
Console.WriteLine(“Fashion news content”);
}
}
//Define the factory
//The factory pattern should always be implemented as a singleton
public sealed class NewsArticleFactory {
//Define a private class to hold the instance of the factory
private sealed class SingletonCreator {
//Static Constructor
static SingletonCreator() {
}
//Use the .net framework to hold a reference to single instance, rather than double locking
internal static readonly NewsArticleFactory instance = new NewsArticleFactory();
}
//Allow public access to the single instance
public static NewsArticleFactory Instance {
get { return SingletonCreator.instance; }
}
//Define the private constructor so only singleton creator can instantiate factory
private NewsArticleFactory() {
}
//Factory pattern implementation
//Return a concrete instance implementing the INewsArticle interface
public INewsArticle GetNewsArticle(string type) {
INewsArticle article;
switch(type) {
case “WorldNews”:
article = new WorldNewsArticle();
break;
case “SportsNews”:
article = new SportsNewsArticle();
break;
case “FinanceNews”:
article = new FinanceNewsArticle();
break;
case “FashionNews”:
article = new FashionNewsArticle();
break;
default:
throw new NotImplementedException(string.Format(“Article type {0} is not implemented.”, type));
}
return article;
}
}
class Program {
static void Main(string[] args) {
//Factory pattern usage
string[] newsArticles = new string[] { “WorldNews”, “FinanceNews”, “SportsNews”, “WorldNews”, “FashionNews” };
INewsArticle article;
foreach(string articleType in newsArticles) {
article = NewsArticleFactory.Instance.GetNewsArticle(articleType);
article.DisplayArticleContent();
}
Console.WriteLine(“Press ENTER to exit”);
Console.ReadLine();
}
}
}
Output:
World news content.
Finance news content
Sports news content
World news content.
Fashion news content
Press ENTER to exit