Introduction
In Software Development, design patterns are used to solve common architectural problems when designing an application or system. They must be used carefully and in the right situations for the right reasons.
If correctly used, design patterns may save developers a lot of time because they offer simple algorithms to solve complex problems. But, if not correctly used, they can bring a huge boost of complexity to your project, increasing the problem's difficulty. Understanding design patterns and their behavior is crucial to using their biggest advantages.
Design patterns are organized into three main groups, as follows.
- Creational, focused to solve problems regarding object creation mechanisms.
- Structural, creating a stable structure by designing the relationship between entities.
- Behavioral, improving objects behavior applying patterns on how they should communicate.
Benefits of using Design Patterns
- Increased maintainability with standardized algorithms
- Easy to apply, solving complex problems with best-practice solutions
- More efficiency, do more with less code.
Related Articles
Check my previous articles about design patterns with .NET Core.
What is the Abstract Factory method design pattern?
The Abstract Factory Design Pattern gives us a way to encapsulate the creation of a group of common objects without exposing the type of objects that will be returned. In short, the abstract factory design pattern is a factory of factories in which the client selects the factory that would best fit his needs.
With the Abstract Factory Design Pattern, the concrete group of classes returned is completely abstracted for the client, where the client's only concern is to select the factory and call its methods to return their specific objects.
In our practical example, the client is going to request vehicles for a tourism group that is going to travel by land and sea. So, the client selects the group size, large or small, and then picks the vehicles for land and sea where the factory will return specific objects for each of their options.
Why use the Abstract factory method Design Pattern?
The main benefit here is when using a group, or family, of common objects that going to be used in the same context. So you only need to instantiate this specific factory in a single place and call the other methods from the factory superclass and manipulate the objects created in the same way.
Saying that we have, among others, these benefits
- The client knows which group of objects solves his needs;
- Each object factory may have its algorithms to apply while creating the object;
- One factory does not need to know the other;
Implementation Step-by-Step With .NET Core
Use Case
In this example, we are going to have a C# with a .NET Core Console Application responsible for selecting the groups of vehicles( land and sea) according to the user group size.
The abstract factory will hold the logic to pick the vehicle that suits best the group according to the group size.
Superclass
The Vehicle class that will be used as a base for the Car, Boat, Cruise and Bus classes
public abstract class Vehicle
{
internal int capacity;
public string GetData()
{
return this.GetType().Name;
}
public int GetCapacity()
{
return capacity;
}
}
Subclasses
Car, boat, cruise, and bus classes that inherit from the vehicle class.
class Car : Vehicle
{
public Car()
{
this.capacity = 5;
}
}
class Bus : Vehicle
{
public Bus()
{
this.capacity = 60;
}
}
class Boat : Vehicle
{
public Boat()
{
this.capacity = 50;
}
}
class Cruise : Vehicle
{
public Cruise()
{
this.capacity = 250;
}
}
Factory Superclass
The class that will be inherited from the Large Group and Small Group factory classes.
abstract class AbstractFactory
{
public abstract Vehicle CreateLandVehicle();
public abstract Vehicle CreateSeaVehicle();
}
Large Group and Small Group factory classes
The factory class is responsible for creating his objects.
class LargeGroupFactory : AbstractFactory
{
public override Vehicle CreateLandVehicle()
{
return new Bus();
}
public override Vehicle CreateSeaVehicle()
{
return new Cruise();
}
}
class SmallGroupFactory : AbstractFactory
{
public override Vehicle CreateLandVehicle()
{
return new Car();
}
public override Vehicle CreateSeaVehicle()
{
return new Boat();
}
}
Client code
The code runs in the client, picking up the vehicle that the desires but without exposing the returning object type.
static void Main(string[] args)
{
AbstractFactory factory = null;
Console.WriteLine("Hello. How many passengers do you need?");
int passengers = Convert.ToInt32(Console.ReadLine());
if (passengers > 15)
factory = new LargeGroupFactory();
else
factory = new SmallGroupFactory();
var landVehicle = factory.CreateLandVehicle();
var seaVehicle = factory.CreateSeaVehicle();
Console.WriteLine("Land Vehicle: " + landVehicle.GetData() + ". With capacity of: " + landVehicle.GetCapacity());
Console.WriteLine("Sea Vehicle: " + seaVehicle.GetData() + ". With capacity of: " + seaVehicle.GetCapacity());
}
Conclusion
Congratulations, you have successfully applied the Abstract Factory Method Design Pattern using C# with .NET Core.