Design Patterns : Abstract Factory
Learn design patterns in C# : factory design pattern
Introduction
In this tutorial, we will look at the abstract factory design pattern, and we will have a detailed example on how to use this design pattern.
All you need to follow along this article is some knowledge of the C# language, object-oriented programming and to have Visual Studio installed.
What is Abstract Factory Design Pattern :
The Abstract Factory Pattern is a Creational pattern in which interfaces are defined for creating families of related objects without specifying their actual implementations. When using this pattern, you create factories which return many kinds of related objects. This pattern enables larger architectures such as Dependency Injection.
The Participants
The AbstractFactory declares an interface for operations which will create AbstractProduct objects.
The ConcreteFactory objects implement the operations defined by the AbstractFactory.
The AbstractProduct declares an interface for a type of product.
The Products define a product object that will be created by the corresponding ConcreteFactory.
The Client uses the AbstractFactory and AbstractProduct interfaces.
A Simple Project :
Now, let's create a simple application where the user has to choose a package to hire a machine-learning freelancer. All classes will be in the namespace HireFreelancer :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace HireFreelancer
{
}
Abstract Product
The abstract product declares an interface for a type of product, here, for example, we have mainly three types of products: Model, Dataset and Report.
Now, let's first create our abstract products.
/// <summary>
/// The Model is the first type of product
/// </summary>
abstract class Model
{
public abstract void PrintTraining();
}
abstract class Dataset
{
public abstract void ConstructingDataset();
}
abstract class Report
{
public abstract void WritingReport();
}
Concrete products
Now, that we defined the three types of products: Model, Dataset and Report, let's create the concrete products. Concrete products define a product object that will be created by the corresponding ConcreteFactory.
/// <summary>
/// Concrete Product
/// </summary>
class RESNET18 : Model
{
public override void PrintTraining()
{
Console.WriteLine("Starting training Resnet 18 ...");
Thread.Sleep(10000);
Console.WriteLine("Training finished succusfully!");
}
}
class RESNET34 : Model
{
public override void PrintTraining()
{
Console.WriteLine("Starting training Resnet 34 ...");
Thread.Sleep(15000);
Console.WriteLine("Training finished succusfully!");
}
}
class RESNET50 : Model
{
public override void PrintTraining()
{
Console.WriteLine("Starting training Resnet 50 ...");
Thread.Sleep(20000);
Console.WriteLine("Training finished succusfully!");
}
}
class DatasetType1 : Dataset
{
public override void ConstructingDataset()
{
Console.WriteLine("Starting Constructing dataset ...");
Thread.Sleep(10000);
Console.WriteLine("Dataset constructed succusfully!");
}
}
class DatasetType2 : Dataset
{
public override void ConstructingDataset()
{
Console.WriteLine("Starting Constructing dataset ...");
Thread.Sleep(15000);
Console.WriteLine("Dataset constructed succusfully!");
}
}
class DatasetType3 : Dataset
{
public override void ConstructingDataset()
{
Console.WriteLine("Starting Constructing dataset ...");
Thread.Sleep(20000);
Console.WriteLine("Dataset constructed succusfully!");
}
}
class Article : Report
{
public override void WritingReport()
{
Console.WriteLine("Writing the article ...");
Thread.Sleep(5000);
Console.WriteLine("Finished writing the article!");
}
}
class SchoolReport : Report
{
public override void WritingReport()
{
Console.WriteLine("Writing the report ...");
Thread.Sleep(5000);
Console.WriteLine("Finished writing the report!");
}
}
class ResearchPaper : Report
{
public override void WritingReport()
{
Console.WriteLine("Writing the research paper ...");
Thread.Sleep(5000);
Console.WriteLine("Finished writing the research paper!");
}
}
Abstract Factory
The abstract factory declares an interface for operations which will create AbstractProduct objects :
/// <summary>
/// The AbstractFactory class
/// </summary>
abstract class PackageFactory
{
public abstract Model TrainModel();
public abstract Dataset ConstructDataset();
public abstract Report WriteReport();
};
Concrete Factories
The ConcreteFactory objects implement the operations defined by the AbstractFactory. Now, let's create some concrete factories that implement the previous abstract factory :
/// <summary>
/// Concrete Factories
/// </summary>
class BasicPackage : PackageFactory
{
public override Model TrainModel()
{
return new RESNET18();
}
public override Dataset ConstructDataset()
{
return new DatasetType1();
}
public override Report WriteReport()
{
return new Article();
}
}
class StandardPackage : PackageFactory
{
public override Model TrainModel()
{
return new RESNET34();
}
public override Dataset ConstructDataset()
{
return new DatasetType2();
}
public override Report WriteReport()
{
return new SchoolReport();
}
}
class PremiumPackage : PackageFactory
{
public override Model TrainModel()
{
return new RESNET50();
}
public override Dataset ConstructDataset()
{
return new DatasetType3();
}
public override Report WriteReport()
{
return new ResearchPaper();
}
}
Main function
Now let's ask the user to choose a specific package and then create it in the main function :
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello ! Please choose the package : (B) Basic (S) Standard (P) Premium");
var input = Console.ReadKey().KeyChar;
Console.WriteLine(input);
PackageFactory package;
switch(input)
{
case ('B'):
package = new BasicPackage();
break;
case ('S'):
package = new StandardPackage();
break;
case ('P'):
package = new PremiumPackage();
break;
default:
throw new NotImplementedException();
}
Dataset dataset = package.ConstructDataset();
Model model = package.TrainModel();
Report report = package.WriteReport();
// Step1 : Construct the dataset
dataset.ConstructingDataset();
model.PrintTraining);
report.WritingReport;
Console.WriteLine("Finished !");
Console.ReadLine();
}
}
Thanks for reading this article! If you liked it, leave a thumbs up and follow me to learn more.
Thank you for reading, and let's connect! ๐ค
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Twitter
If you like this article! Don't miss the upcoming ones, follow me and subscribe to my newsletter to receive more!
See you soon :)