βœ… Factory Method Pattern

Does someone have a good explanation or perhaps a link to somewhere where i can learn this? Been trying to find a video or similar but it just doesn't stick :(
81 Replies
Pobiega
Pobiegaβ€’4w ago
so you know how constructors work right?
Merineth πŸ‡ΈπŸ‡ͺ
I think soooo
Pobiega
Pobiegaβ€’4w ago
var x = new Product("Apple", 15, 3.5); etc
Merineth πŸ‡ΈπŸ‡ͺ
We store an instance of Product inside var x ?
Pobiega
Pobiegaβ€’4w ago
sure, but the "constructor" here is the new Product("Apple", 15, 3.5) part
Merineth πŸ‡ΈπŸ‡ͺ
So the constructor is the one that instanciates the object?
Pobiega
Pobiegaβ€’4w ago
yes
Merineth πŸ‡ΈπŸ‡ͺ
Oki, then yeah i'm with you :cathype:
Pobiega
Pobiegaβ€’4w ago
a "factory" in OOP is a class/method that knows how to create something else. it knows the details needed to call the constructor properly, and maybe set some values on the object before returning it in this case, maybe you dont know what the 15 and 3.5 should be lets assume 15 is the "Product ID", and that should be an incremeneted number. It would be silly to expect the programmer to constantly keep track of the current ID and manually give it
Pobiega
Pobiegaβ€’4w ago
so we can make a "ProductFactory" instead that keeps track of it for us
Merineth πŸ‡ΈπŸ‡ͺ
Would that be an abstract class/interface?
Pobiega
Pobiegaβ€’4w ago
uh... probably not
Merineth πŸ‡ΈπŸ‡ͺ
Weird, i think our teacher specifies it as such 😭
Pobiega
Pobiegaβ€’4w ago
abstract things cant be created, so how would you create the factory? Ah, are you refering specifically to the "abstract factory" pattern?
Merineth πŸ‡ΈπŸ‡ͺ
I think so? GoF ?
Pobiega
Pobiegaβ€’4w ago
yeah
Merineth πŸ‡ΈπŸ‡ͺ
This is what she explains it as
Pobiega
Pobiegaβ€’4w ago
yeah GoF has an "abstract factory" in it FactoryBase here is your abstract factory check this out: https://refactoring.guru/design-patterns/abstract-factory
Merineth πŸ‡ΈπŸ‡ͺ
How do you know that is abstract
Pobiega
Pobiegaβ€’4w ago
their explanations are usually pretty good well it has a Base suffix and the title is in italics and there are other classes called ConcreteSomething concrete is the opposite of abstract...
Merineth πŸ‡ΈπŸ‡ͺ
So in my case the interface here would be Carfactory?
Pobiega
Pobiegaβ€’4w ago
? this is the first time you mention Car
Merineth πŸ‡ΈπŸ‡ͺ
Oh wait i might not have included everything
Merineth πŸ‡ΈπŸ‡ͺ
This is what i'm working on atm And i'm trying to implement the Factory method (which i'm currently learning)
Pobiega
Pobiegaβ€’4w ago
right In your case Car would be an abstract base class, not an interface, but otherwise it would fulfill the same role as "Chair" does in the above image
Merineth πŸ‡ΈπŸ‡ͺ
I see
namespace Creational.FactoryMethodPattern.Cars
{
public abstract class Car
{
}
}
namespace Creational.FactoryMethodPattern.Cars
{
public abstract class Car
{
}
}
We were provided an abstract class for Car in the project Hmm i’ll finish reading the page, one moment ^^
MODiX
MODiXβ€’4w ago
Merineth
Quoted by
<@577931037393420298> from #Factory Method Pattern (click here)
From Merineth
React with ❌ to remove this embed.
Merineth πŸ‡ΈπŸ‡ͺ
Would the "Client" be my main method?
Pobiega
Pobiegaβ€’4w ago
yeah
Merineth πŸ‡ΈπŸ‡ͺ
Client is missing in this? Would FactoryBase be a subclass interface of the client?
Pobiega
Pobiegaβ€’4w ago
you dont specifically need a client FactoryBase is AbstractFactory they do the same thing
Merineth πŸ‡ΈπŸ‡ͺ
I see So this Interface would be called from main in order to make the car? And then depending on what type of car we want different Concrete Factories are called? 😭 this is so confusing I don't even see the benefit of using this Factory method Not even gpt can explain it to me :I
public static void Main(string[] args)
{
// How can we apply the Factory Method Design Pattern,
// so that we don't explicitly create the cars below
// using the new operator and a constructor call?

Car car;

car = new HyundaiCoupe();
Console.WriteLine($"Type: {car.GetType()}");

car = new HyundaiI30();
Console.WriteLine($"Type: {car.GetType()}");

car = new MazdaMX5();
Console.WriteLine($"Type: {car.GetType()}");

car = new Mazda6();
Console.WriteLine($"Type: {car.GetType()}");
}
public static void Main(string[] args)
{
// How can we apply the Factory Method Design Pattern,
// so that we don't explicitly create the cars below
// using the new operator and a constructor call?

Car car;

car = new HyundaiCoupe();
Console.WriteLine($"Type: {car.GetType()}");

car = new HyundaiI30();
Console.WriteLine($"Type: {car.GetType()}");

car = new MazdaMX5();
Console.WriteLine($"Type: {car.GetType()}");

car = new Mazda6();
Console.WriteLine($"Type: {car.GetType()}");
}
Pobiega
Pobiegaβ€’4w ago
Well in this case there is no benefit
Merineth πŸ‡ΈπŸ‡ͺ
Like i fail to see what's wrong with this
Pobiega
Pobiegaβ€’4w ago
This is just a stupid example
Merineth πŸ‡ΈπŸ‡ͺ
:( 10/10 teacher
Pobiega
Pobiegaβ€’4w ago
eh, more like bad... kursplaner
Merineth πŸ‡ΈπŸ‡ͺ
(: yup
Pobiega
Pobiegaβ€’4w ago
its hard to understand why you'd need an abstract factory until you do
Merineth πŸ‡ΈπŸ‡ͺ
So they dont want me to instanciate cars with constructors in the main program
Pobiega
Pobiegaβ€’4w ago
and its not a pattern you use for simple apps traditionally
Merineth πŸ‡ΈπŸ‡ͺ
They want me to use a factory to do it for me So i instanciate them inside the factory instead
Pobiega
Pobiegaβ€’4w ago
I mean, the simplest implementation of a factory literally just calls the constructor... which is pretty silly
Merineth πŸ‡ΈπŸ‡ͺ
Welp i've been trying to figure out what it even is for a few hours now I'm surprised there aren't videos covering it under 20 min
Pobiega
Pobiegaβ€’4w ago
the link I gave above is... pretty good.
Merineth πŸ‡ΈπŸ‡ͺ
:{ Yeah for someone who already knows it 😭 The first thing the Abstract Factory pattern suggests is to explicitly declare interfaces for each distinct product of the product family So i create an interface for car? or rather an abstract class
Pobiega
Pobiegaβ€’4w ago
Well, you already have that, no?
Merineth πŸ‡ΈπŸ‡ͺ
Would that be the FactoryBase? Or do i need another abstract class for a total of two?
Pobiega
Pobiegaβ€’4w ago
you would indeed have two one for Car, one for AbstractCarFactory or CarFactoryBase whatever then you make one concrete factory for each car variant
Merineth πŸ‡ΈπŸ‡ͺ
Confusing considering there aren't two here
Pobiega
Pobiegaβ€’4w ago
you can make your factories in different ways that one has its example of the three kinds of furniture each factory knows how to make a chair, a sofa and a table the difference there is the style of the factory. In your case, you only have one "dimension" of difference
Merineth πŸ‡ΈπŸ‡ͺ
So in the example from the site we'd need 3 interfaces for each chair, sofa and table?
Pobiega
Pobiegaβ€’4w ago
yeah a baseclass for each type either interface or abstract class
Merineth πŸ‡ΈπŸ‡ͺ
Ok so why do iu need two interfaces when there is only one object, car (i just assume interface and abstract class are the same)
Pobiega
Pobiegaβ€’4w ago
because you have the BaseThing (car) and the FactoryBase thats two things but none are concrete
Merineth πŸ‡ΈπŸ‡ͺ
And what's the difference between those two iabstract classes?
Pobiega
Pobiegaβ€’4w ago
what one is a car the other is a factory ... .d
Merineth πŸ‡ΈπŸ‡ͺ
hahahah but i don't get it I don't even understand what they are mean to do
Pobiega
Pobiegaβ€’4w ago
in this case, NOTHING
Merineth πŸ‡ΈπŸ‡ͺ
I have 4 different types of cars, Oh
Pobiega
Pobiegaβ€’4w ago
they are literally just to tie the hierarchies together
Merineth πŸ‡ΈπŸ‡ͺ
I found the solution they provided As you said the Car abstract class is completely empty However the CarFactoryis not
using Creational.FactoryMethodPattern.Cars;

namespace Creational.FactoryMethodPattern.Factories
{
public abstract class CarFactory
{
public abstract Car CreateCar(string model);
}
}
using Creational.FactoryMethodPattern.Cars;

namespace Creational.FactoryMethodPattern.Factories
{
public abstract class CarFactory
{
public abstract Car CreateCar(string model);
}
}
Pobiega
Pobiegaβ€’4w ago
well, it provides the base implementation for CreateCar yeah however, no body so its effectively an interface
Merineth πŸ‡ΈπŸ‡ͺ
no body?
Pobiega
Pobiegaβ€’4w ago
yeah no body notice how the method has... no body
Merineth πŸ‡ΈπŸ‡ͺ
Oh, right iirc abstract classes can't have a body to their methods only the definitions
Pobiega
Pobiegaβ€’4w ago
abstract classes can abstract methods cant abstract classes can have non-abstract methods
Merineth πŸ‡ΈπŸ‡ͺ
using Creational.FactoryMethodPattern.Cars;
using Creational.FactoryMethodPattern.Factories;

namespace Creational.FactoryMethodPattern
{
public class Program
{
public static void Main(string[] args)
{
CarFactory factory;
Car car;

factory = new HyundaiCarFactory();

car = factory.CreateCar("coupe");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("i30");
Console.WriteLine($"Type: {car.GetType()}");

factory = new MazdaCarFactory();

car = factory.CreateCar("mx5");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("6");
Console.WriteLine($"Type: {car.GetType()}");
}
}
}
using Creational.FactoryMethodPattern.Cars;
using Creational.FactoryMethodPattern.Factories;

namespace Creational.FactoryMethodPattern
{
public class Program
{
public static void Main(string[] args)
{
CarFactory factory;
Car car;

factory = new HyundaiCarFactory();

car = factory.CreateCar("coupe");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("i30");
Console.WriteLine($"Type: {car.GetType()}");

factory = new MazdaCarFactory();

car = factory.CreateCar("mx5");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("6");
Console.WriteLine($"Type: {car.GetType()}");
}
}
}
So what's the difference between this ^and that?
Pobiega
Pobiegaβ€’4w ago
welllllll this uses the factories so uh.. yeah, as said this example sucks πŸ˜„ this example very much just shows you what the code looks like, it doesnt show you why or when this pattern makes sense
Merineth πŸ‡ΈπŸ‡ͺ
haha i juat have a really hard time understanding or relating to stuff when i’m not given concrete examples :( okay i took a quick nap D: If anyone sees this and wouldn't mind explaining Factory Method to me :sadcat: Anyone ? :/
namespace Creational.FactoryMethodPattern
{
public class Program
{
public static void Main(string[] args)
{
CarFactory factory;
Car car;

factory = new HyundaiCarFactory();

car = factory.CreateCar("coupe");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("i30");
Console.WriteLine($"Type: {car.GetType()}");

factory = new MazdaCarFactory();

car = factory.CreateCar("mx5");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("6");
Console.WriteLine($"Type: {car.GetType()}");
}
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public abstract class CarFactory
{
public abstract Car CreateCar(string model);
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public class HyundaiCarFactory : CarFactory
{
public override Car CreateCar(string model)
{
switch (model.ToLower())
{
case "coupe": return new HyundaiCoupe();
case "i30": return new HyundaiI30();
default: throw new ArgumentException("Invalid model", "model");
}
}
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public class MazdaCarFactory : CarFactory
{
public override Car CreateCar(string model)
{
switch (model.ToLower())
{
case "mx5": return new MazdaMX5();
case "6": return new Mazda6();
default: throw new ArgumentException("Invalid model", "model");
}
}
}
}
namespace Creational.FactoryMethodPattern
{
public class Program
{
public static void Main(string[] args)
{
CarFactory factory;
Car car;

factory = new HyundaiCarFactory();

car = factory.CreateCar("coupe");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("i30");
Console.WriteLine($"Type: {car.GetType()}");

factory = new MazdaCarFactory();

car = factory.CreateCar("mx5");
Console.WriteLine($"Type: {car.GetType()}");

car = factory.CreateCar("6");
Console.WriteLine($"Type: {car.GetType()}");
}
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public abstract class CarFactory
{
public abstract Car CreateCar(string model);
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public class HyundaiCarFactory : CarFactory
{
public override Car CreateCar(string model)
{
switch (model.ToLower())
{
case "coupe": return new HyundaiCoupe();
case "i30": return new HyundaiI30();
default: throw new ArgumentException("Invalid model", "model");
}
}
}
}

namespace Creational.FactoryMethodPattern.Factories
{
public class MazdaCarFactory : CarFactory
{
public override Car CreateCar(string model)
{
switch (model.ToLower())
{
case "mx5": return new MazdaMX5();
case "6": return new Mazda6();
default: throw new ArgumentException("Invalid model", "model");
}
}
}
}
This is the provided solution However it doesn't really bring me any closer in understand what factories do.
MutableString
MutableStringβ€’4w ago
i would use a factory for creating clients, for example
Merineth πŸ‡ΈπŸ‡ͺ
How would that work? The only rough idea i have around factories are that they are using to encapsulate outside of the main method? As in the constructor isn't done in the main?
TizzyT
TizzyTβ€’4w ago
static factory method <T> where T : WhatEverClassThisIs, new() πŸ˜›
MutableString
MutableStringβ€’4w ago
i would use for example as a helper to have some logic when instantiating a class
sealed class ClientFactory {
MySettings _settings;

static IClient CreateClient(SomePars somePars) {
var stuff = ProcessPars(somePars);
return new MyClient(_settings.ClientSettings, stuff);
}
}
sealed class ClientFactory {
MySettings _settings;

static IClient CreateClient(SomePars somePars) {
var stuff = ProcessPars(somePars);
return new MyClient(_settings.ClientSettings, stuff);
}
}
and then there could be other CreateClient methods with different parameters
Want results from more Discord servers?
Add your server