I'm not a native speaker, but it's the best explanation I've found. Neither the book nor refactoring guru couldn't explain better. After watching this video I immediately subscribed to this channel and set a thumb up!
This is the best way to demonstrate the design patterns. 1. Not showing the stupid UML (no junior will understand them) 2. Not diving into coding after UML (no junior will understand them), 3. Rather show some real case scenario 4. Than show the code implementation 5. And finally translate the clear picture and idea into UML. My friend you are a true teacher, everyone else is naaaah.....
Also, for others more advanced. You can combine Factory patter with Strategy pattern and get different versions of GPU (GTX, RTX, Radeon etc) during runtime. In your factory class you can make something like public T manufactureGPU(Class gpuType){ return gpuType.getConstructor().newInstance(); } And then you can pass any type of gpu you want. ### NVIDIA ### Manufacturer nvidia = new NvidiaGpuManufacturer(); NvidiaGtx1060 gtx1060 = nvidia.manufactureGPU(NvidiaGtx1060.class); NvidiaRtx4090 rtx4090 = nvidia.manufactureGPU(NvidiaRtx4090.class); ### RADEON ### Manufacturer radeon = new RadeonGpuManufacturer(); RadeonRx600 rx600 = radeon.manufactureGPU(RadeonRx600.class); RadeonVega8 vega8= radeon.manufactureGPU(RadeonVega8.class); and so on and so forth
The best Abstract factory design pattern explanation on TH-cam, you nailed a subscriber I'm going to watch your design patterns playlist, thanks a lot.
Thank you very much. Two questions: 1. The handling of all the if statements is at the client code right? 2. From my understanding, if the abstract class is responsible for the creation of multiple interface (multiple factory methods), then it is abstract factory pattern. But if abstract class is responsible for creation of only one interface(one factory method), then it is factory method pattern. Basically you will have as many factory methods in the abstract class as interfaces right? Am I correct?
@@geekific Should we add static string name to each factory implementation for choosing which one to use? If not we will have to have hardcoded if else in client code
Thank you for video!!!! I have a question from previous video. In previous video you said that our restaurant boomed and now we make italian burgers also. Does it mean that we have to create 3 interfaces ("BeefBurger", "VegieBurger" and "Restaurant" with "createBeefBurger" and " createVegieBurger" methods) then 4 burger classes which implement "BeefBurger" and "VegieBurger" and 2 factory classes which implement "Restaurant" ("AmericanBeefBurger", "AmericanVegieBurger", "ItalianBeefBurger", "ItalianVegieBurger" and "ItalianRestaurant" , "AmericanRestaurant") ? Please answer .
Welcome! CPUs and GPUs are your burgers and the Company is the restaurant. So, yes I guess if you want to apply the same approach you will obtain the classes you mentioned!
Hi Geekific I don't quite understand; if a new type of product, such as ProductC, is added, it appears that it might violate the Open-Closed Principle. 3:19 Factory method pattern violate the Open-Closed Principle when new type of Product added, It just appears the Abstract Factory Pattern doesn't solve this problem. (we should modifiy all the factory class to add a third createProduct method.) @Grrkific
main function is client code. Factory method should not do the object instantiation inside client code. Factory should be the only place which is responsible to create these objects.
What happens if you add a third manufacturer named NVIDIA that manufactures GPUs but not Monitor? I tried to do it and can't make it work without violating the Liskov Substitution Principle (due to be constrained to override the assembleMonitor() method from the abstract class) by throwing an exception since they don't manufacture monitors (based on the example, don't know if they do it in real life). Your videos are amazing, by the way! Would be great if you could give me an insight on how to workaround this problem of related objects that don't have precisely all the capabilities by design (the NVIDIA case with monitors). Thanks a lot in advance and keep up with the great work @geekific.
Glad to read this am happy I could help :) Well in these cases you're going to have to choose the pros and cons of your current design and take a step back to check the requirements. You see, maybe what you really need is two factories and not one, because why is this new factory not producing the same products as the others? (That's what I would have done in this very specific example) Does it fall into some different category (maybe brand categories in this example)? What if the products that where associated with the first design should actually be split into two? What if after answering these questions you realized that this new producer isn't actually what you had in mind and shouldn't be sided with the others in the first place? In other words I can't give a definitive answer to this, because each case is specific to the functional requirements at this point, do not always try to solve the problems in the technical way by overengineering the design, sometimes, it is the other way around :) Hope this helps!
@@geekific My initial thought was about making two Manufacturer class and that way somehow solving the issue. But wouldn't that be sad? I mean, it makes me scratch that part of the head regarding the "what if" we could find a way. If Java could allow inheritance from two class that could have helped greatly. Anyway, I am learning a lot with your videos and keep rocking it! Honestly, it's one of the best Java-related channels I have seen here on TH-cam.
In that case, the most appropriate thing is to create interfaces that are dedicated to creating each component. public interface GpuCreator{ GPU createGpu(); } public interface MonitorCreator { Monitor createMonitor(); } public interface AllComponentCreator extends GpuCreator, MonitorCreator { } The Company class will no longer make much sense, unless it has more methods in common, but that depends on the business rules of each application. Then AsusManufacturer and MsiManufacturer will implement AllComponentCreator while Nvidia only GpuCreator. Example: public class MsiManufacturer implements AllComponentCreator { @Override public Gpu createGpu() { return new MsiGpu(); } @Override public Monitor createMonitor() { return new MsiMonitor(); } } public class NvidiaManufacturer implements GpuCreator { @Override public Gpu createGpu() { return new NvidiaGpu(); } } Even though the base class does not exist, it still respects the abstract factory pattern because you have a class that creates a family of related objects. On the other hand, your client code must know when it needs to create both components and when only GPUs: AllComponentCreator msi = new MsiManufacturer(); AllComponentCreator asus = new AsusManufacturer(); GpuCreator nvidia = new NvidiaManufacturer(); You can always create an interface to group behaviors, but it is essential that the business rules are clear and your client code must know when it needs to create one type and when another type.
Thanks very much. I've been coming back to this playlist for all the different patterns... that means it's really good playlist. I would like to ask: If ASUS only produces CPU and not monitors, then it will not implement the abstract monitor method ? How to handle this ? Another pattern ? Is it possible to combine factory pattern with build pattern ?
In case the object you are attempting to create is very complex, you could combine both yes. The Factory Pattern could be used to create instances of a builder class, which in turn could be used to construct complex objects step by step. This approach provides flexibility in object creation and allows for the construction of objects with different configurations based on specific requirements.
Yeah, I´ve already read the book and compare diagrams, and could be notice that if a Factory Method add more functión and one of more Component, that is when change into AbstractFactoryMethod. Could you tell me if i rignth understanding?
First thanks for the videos dude, well explained one of TH-cams programming pearls. How ever i have a question regarding this one, how could we say that open closed principle is respected as in case we add a new product for example laptop. We will violate oc principle as we will add new abstract attributes in company class ?
@Geekific if there is another product like mouse which we need to add to a abstract factory... we are violationg open closed principle ryt. I didnt get how it avoids that condition?
In summary, Factory Pattern for 1 type of product, Abstract Factory Pattern for > 1 type of product ? I look at it, looks like I just have to make sure I have different abstract methods and interface for different products, that would create a AF pattern ?
I have a doubt. Will the open closed principle still be maintained if we do not know the type type of all the products beforehand, thus cannot explicitly create interfaces for each of them from start?
That's exactly the point! If you don't know all your products, all you have to do is add a new class for your product when you know what it is, thus extending your app instead of opening it :)
Isn't the Company-Class (Abstract Factory) still open for modification since one needs to add another createX statement if another product type is to be implemented?
nice observation! See we can create Factory classes based on Component(GPU/Monitor) or brand but we chose brand for creating Factory classes to follow open/closed principle.New Components are rarely added whereas Brand under a component can increase frequently.For every new brand, we create a new factory class with methods for GPU & Monitor.We don't have to modify Factory class of this new brand unless there is a new component added.
great video. But I still have the problem of how to create the manufacturer object without breaking the code. In the main method, you have to decide what manufacture object should be created. You may use the if else condition to determine. Does it break the open close principle ?
Thanks! As long as it is on the client side you are fine. For example if you had a UI where you click on stuff that forwards you to the needed object, you won't even need the conditional if's because that UI construct will immediately make use of the appropriate logic! We will be uploading a video on how to make use of these patterns, so stay tuned!
If I want to add a new company, Apple, with only one product, AppleMonitor, and extended Company to create a concrete factory, AppleManifacturer, it's forcing me to implement an unnecessary method to createGPU. How to solve this?
You need specialized factories or multiple specialized interfaces to keep using the pattern or you'll have to change the pattern. Hope this answers it!
How would this still apply to the Interface Segregation principle? Suppose the MSI or the ASUS factory does not produce one of these products. Is not this forceing the concrete factories to implement methods that they might not need?
Then maybe this pattern is not the best choice for your particular use-case! Additionally, feel free to watch our video on SOLID principles here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html! Cheers :)
I am confused, where will the actual decision to create which concrete product takes place? Like there need to some conditionals somewhere, like interpreting the customer request and deciding whether he needs an ASUS GPU or MSI monitor, right? Where would that conditional if-else block be placed?
@@geekific But I keep reading this phrase about Factory method, goes like : "It helps in centralising the decision making part, so that if we later want to change something in that decision process, we only have to do it at one place". So if the client gets to write their own conditions, then is it the responsibility of the client to keep the decision making centralized?
So if the types of components extends to hundreds and thouands, which is very likely to happen in real life, how is the Company class going to handle? And if we go back to last class, why can’t we just implement createBeefBurger, createVeggieBurger like we did here?
Doesn't this still violate the open/close principle, since you need to edit the abstract factory class every time you add a new product? Like imagine adding a new product "headset", you'll have to modify all three classes Company, AsusManufacturer, MsiManufacturer. Even though creating some new methods is better than dealing with messy if-else statements, it is a compromise one needs to accept.
From Wikipedia: "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". So, in your example we do not violate the OCP, as Open-Closed means you are allowed to modify the way a system works without modifying the code that already exists, so, you can extend the existing code, but the *old code is still intact and doesn't need to be re-tested* .
Splitting hairs. Technically you’re not modify the actual code but you are modifying the class by adding new code. If someone fat fingers something or copy/pastes the wrong thing you’ve broken it. A true not open model would use reflection and inputs from an xml or json file that can be changed without touching any code at all.
A code cannot be closed for "modification" if it doesn't exist in the first place. The idea behind the principle is making any *new* functionality you add open for extension. Besides all the code is and will rely on the interfaces, hence other parts of our application will not even feel the addition you mentioned, but that's another principle :P Please check our SOLID video for a more detailed explanation: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html Cheers!
@@geekific Well what I mean is, say a company can now make CPUs and Fans as well. We have to add the abstract methods "createCPU()" and "createFan()" inside the company class. Then override those methods inside each manufacture class. Wouldn't that be what we are trying to avoid?
@@shadowwatcher5042 This is what I am not getting either. The IF statements can't seem to be taken out. SOLID isn't as solid as it wants to be. I don't think its possible to completely adhere to Open-closed. I keep trying to think of a dynamic way it could be done by using external data files or mapping.
@@drcl7429 Perhaps each factory can be extended. So say we have factory1 that makes shoes and socks. The company expands and wants to make pants and shirts. So the second factory is simply called factory2 that extends factory1 and makes the clothes. That way in the main function, factory2 can be used and still call factory1 methods. Factory3 extends factory2 and makes jackets and hats. Then just use factory3 to get methods of 1 and 2
@@geekific Thx for your comment. I actually mean, what if we have 3 factory methods, Gpu/Monitor/Cpu... and we have 3 Factory Creators, like MSI/Asus/Dell... but it does not make sense for the "Gpu" factory method for MSI, cuz MSI does not actually manufacture Gpu at all... how to deal with this? in this case is the Abstract Factory Pattern will not be suitable? Since it defines "a family of objects" so all factory method should be applicable to all factory creators? Or is it ok to just throw exception "Does not have Gpu" for MSI and it would not be a bad design?
There is nothing written in stone, you can mold these designs to suit your needs and in this case, in my opinion, the cleanest way to make the factory work is by applying the Interface Segregation Principle discussed here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html. So, you will have multiple specific abstract factories or interfaces, and you can pick which concrete factory implements which. However, during the creation you'll need to be aware of the one you'll be using.
Hi, i'm wondering do you think java is still relevant? won't kotlin replace it? I really like java and I think that it needs to be improved, and not switched to other languages
ISP SOLID principal violation This design assumes that company abstract methods must be implemented by all manufacturers. What if a company doesn't want to manufacture some product it doesn't find value in. You will end up overriding methods which violate ISP.
You can create separate GPU and Monitor companies interfaces and let manufacturers implement the ones they need for ISP. This pattern answers a particular question and I didn't want to overwhelm everyone by overengineering the code, but yes, if that's what you are looking for, this works. You can check our SOLID video here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html. Cheers!
This is so much better than people who show tutorial by typing up the code live. This gives you a much better big picture view of everything
I'm not a native speaker, but it's the best explanation I've found. Neither the book nor refactoring guru couldn't explain better. After watching this video I immediately subscribed to this channel and set a thumb up!
Am getting closer and closer to mastering Design Patterns all because of you!
me too
Why didn't you continue with the Italian restaurant from the previous video? I was really looking forward to it :(
This is the best way to demonstrate the design patterns.
1. Not showing the stupid UML (no junior will understand them)
2. Not diving into coding after UML (no junior will understand them),
3. Rather show some real case scenario
4. Than show the code implementation
5. And finally translate the clear picture and idea into UML.
My friend you are a true teacher, everyone else is naaaah.....
Also, for others more advanced. You can combine Factory patter with Strategy pattern and get different versions of GPU (GTX, RTX, Radeon etc) during runtime.
In your factory class you can make something like
public T manufactureGPU(Class gpuType){
return gpuType.getConstructor().newInstance();
}
And then you can pass any type of gpu you want.
### NVIDIA ###
Manufacturer nvidia = new NvidiaGpuManufacturer();
NvidiaGtx1060 gtx1060 = nvidia.manufactureGPU(NvidiaGtx1060.class);
NvidiaRtx4090 rtx4090 = nvidia.manufactureGPU(NvidiaRtx4090.class);
### RADEON ###
Manufacturer radeon = new RadeonGpuManufacturer();
RadeonRx600 rx600 = radeon.manufactureGPU(RadeonRx600.class);
RadeonVega8 vega8= radeon.manufactureGPU(RadeonVega8.class);
and so on and so forth
You just made my day! Thank you!
Thanks! I have been using your videos so much to prepare for my exams
Thank YOU for the support, I am so glad the videos are helping you! Good luck with your exams :)
I saw many many videos today about this topic, and this is clearly the BEST EXPLAINED. Thanks man, I finally get it!
Awesome, thank you! Glad to read it :)
I've watched many videos on design patterns, your videos have the best examples and have helped me wrap my head around patterns. Thank you!
Wow, thank you! Glad they're helpful :)
totaly agree
Welp, this is the only video that has helped me fully understand Abstract Factory Pattern, thank you!!
Happy to help! Glad it did!
Geekific..You are my recent best Find!!!
Thank you for this video, you’ve helped me solidify this concept. Your explanations are crystal clear and coherent. Keep up the good work!
Very good explanation, i can finally understand both factories, thanks bro!
your series is the best to explain design pattern, thank you so much
You are doing an amazing job ! thank you so much for your time and for the effort you toke to simplify complexe design patterns.
The best tutorial for the design patterns
your channel is so professional, I wonder why you only have that number of subscribers, your channels helped me so much so I'm subscribing
Only video at least helped me to touch the surface of abstract factory. Thank you!
damn you're a G. Better than most of the paid courses on Udemy.
Thank you so much for your splendid easy-to understand explanation for design patterns
The best gof patterns explanations ever 👍👍
The best Abstract factory design pattern explanation on TH-cam, you nailed a subscriber I'm going to watch your design patterns playlist, thanks a lot.
Thank you very much.
Two questions:
1. The handling of all the if statements is at the client code right?
2. From my understanding, if the abstract class is responsible for the creation of multiple interface (multiple factory methods), then it is abstract factory pattern. But if abstract class is responsible for creation of only one interface(one factory method), then it is factory method pattern. Basically you will have as many factory methods in the abstract class as interfaces right? Am I correct?
1- Yup.
2- You got the comparison right, and if by interfaces you mean products, then yes you are correct.
Well done!
@@geekific Should we add static string name to each factory implementation for choosing which one to use? If not we will have to have hardcoded if else in client code
Thank you for video!!!! I have a question from previous video. In previous video you said that our restaurant boomed and now we make italian burgers also. Does it mean that we have to create 3 interfaces ("BeefBurger", "VegieBurger" and "Restaurant" with "createBeefBurger" and " createVegieBurger" methods) then 4 burger classes which implement "BeefBurger" and "VegieBurger" and 2 factory classes which implement "Restaurant" ("AmericanBeefBurger", "AmericanVegieBurger", "ItalianBeefBurger", "ItalianVegieBurger" and "ItalianRestaurant" , "AmericanRestaurant") ? Please answer .
Welcome! CPUs and GPUs are your burgers and the Company is the restaurant. So, yes I guess if you want to apply the same approach you will obtain the classes you mentioned!
@@geekific Thank you!
You are the best. This videoand the previous one clearly helped me understand the difference between factory method and abstract factory.
Nice job
Hi Geekific
I don't quite understand; if a new type of product, such as ProductC, is added, it appears that it might violate the Open-Closed Principle.
3:19 Factory method pattern violate the Open-Closed Principle when new type of Product added, It just appears the Abstract Factory Pattern doesn't solve this problem. (we should modifiy all the factory class to add a third createProduct method.)
@Grrkific
At 3:19 is not the final implementation, we are progressively shaping up and evolving the implementation throughout the video, keep watching!
main function is client code.
Factory method should not do the object instantiation inside client code. Factory should be the only place which is responsible to create these objects.
This is a great explanation and demo of this pattern
What happens if you add a third manufacturer named NVIDIA that manufactures GPUs but not Monitor? I tried to do it and can't make it work without violating the Liskov Substitution Principle (due to be constrained to override the assembleMonitor() method from the abstract class) by throwing an exception since they don't manufacture monitors (based on the example, don't know if they do it in real life).
Your videos are amazing, by the way! Would be great if you could give me an insight on how to workaround this problem of related objects that don't have precisely all the capabilities by design (the NVIDIA case with monitors). Thanks a lot in advance and keep up with the great work @geekific.
Glad to read this am happy I could help :) Well in these cases you're going to have to choose the pros and cons of your current design and take a step back to check the requirements. You see, maybe what you really need is two factories and not one, because why is this new factory not producing the same products as the others? (That's what I would have done in this very specific example) Does it fall into some different category (maybe brand categories in this example)? What if the products that where associated with the first design should actually be split into two? What if after answering these questions you realized that this new producer isn't actually what you had in mind and shouldn't be sided with the others in the first place?
In other words I can't give a definitive answer to this, because each case is specific to the functional requirements at this point, do not always try to solve the problems in the technical way by overengineering the design, sometimes, it is the other way around :) Hope this helps!
@@geekific My initial thought was about making two Manufacturer class and that way somehow solving the issue. But wouldn't that be sad? I mean, it makes me scratch that part of the head regarding the "what if" we could find a way. If Java could allow inheritance from two class that could have helped greatly.
Anyway, I am learning a lot with your videos and keep rocking it! Honestly, it's one of the best Java-related channels I have seen here on TH-cam.
In that case, the most appropriate thing is to create interfaces that are dedicated to creating each component.
public interface GpuCreator{
GPU createGpu();
}
public interface MonitorCreator {
Monitor createMonitor();
}
public interface AllComponentCreator extends GpuCreator, MonitorCreator
{ }
The Company class will no longer make much sense, unless it has more methods in common, but that depends on the business rules of each application.
Then AsusManufacturer and MsiManufacturer will implement AllComponentCreator while Nvidia only GpuCreator. Example:
public class MsiManufacturer implements AllComponentCreator {
@Override
public Gpu createGpu() {
return new MsiGpu();
}
@Override
public Monitor createMonitor() {
return new MsiMonitor();
}
}
public class NvidiaManufacturer implements GpuCreator {
@Override
public Gpu createGpu() {
return new NvidiaGpu();
}
}
Even though the base class does not exist, it still respects the abstract factory pattern because you have a class that creates a family of related objects.
On the other hand, your client code must know when it needs to create both components and when only GPUs:
AllComponentCreator msi = new MsiManufacturer();
AllComponentCreator asus = new AsusManufacturer();
GpuCreator nvidia = new NvidiaManufacturer();
You can always create an interface to group behaviors, but it is essential that the business rules are clear and your client code must know when it needs to create one type and when another type.
The abstract factory is the object with the abstract methods, each method is implement in the subclass thus the method is factory method
great tutorial, thanks!
Excellent.
Thanks very much. I've been coming back to this playlist for all the different patterns... that means it's really good playlist. I would like to ask: If ASUS only produces CPU and not monitors, then it will not implement the abstract monitor method ? How to handle this ? Another pattern ?
Is it possible to combine factory pattern with build pattern ?
In case the object you are attempting to create is very complex, you could combine both yes. The Factory Pattern could be used to create instances of a builder class, which in turn could be used to construct complex objects step by step. This approach provides flexibility in object creation and allows for the construction of objects with different configurations based on specific requirements.
@@geekific thanks very much... appreciated.
Yeah, I´ve already read the book and compare diagrams, and could be notice that if a Factory Method add more functión and one of more Component, that is when change into AbstractFactoryMethod. Could you tell me if i rignth understanding?
you're great!
Lovely, made it real easy!
short video, but good explanation!
First thanks for the videos dude, well explained one of TH-cams programming pearls.
How ever i have a question regarding this one, how could we say that open closed principle is respected as in case we add a new product for example laptop.
We will violate oc principle as we will add new abstract attributes in company class ?
Glad it was helpful! We are not changing existing functionalities, and the main work will be shifted to new classes.
Awesome explanation!! keep up the good work brother
Thank you so much mister
@Geekific if there is another product like mouse which we need to add to a abstract factory... we are violationg open closed principle ryt. I didnt get how it avoids that condition?
Factory Method scope is classified as class and Absrtact Factory scope as object. Can you please tell me , How it came into that conclusion?
Thank you so much !
In summary, Factory Pattern for 1 type of product, Abstract Factory Pattern for > 1 type of product ? I look at it, looks like I just have to make sure I have different abstract methods and interface for different products, that would create a AF pattern ?
I have a doubt. Will the open closed principle still be maintained if we do not know the type type of all the products beforehand, thus cannot explicitly create interfaces for each of them from start?
That's exactly the point! If you don't know all your products, all you have to do is add a new class for your product when you know what it is, thus extending your app instead of opening it :)
Isn't the Company-Class (Abstract Factory) still open for modification since one needs to add another createX statement if another product type is to be implemented?
nice observation! See we can create Factory classes based on Component(GPU/Monitor) or brand but we chose brand for creating Factory classes to follow open/closed principle.New Components are rarely added whereas Brand under a component can increase frequently.For every new brand, we create a new factory class with methods for GPU & Monitor.We don't have to modify Factory class of this new brand unless there is a new component added.
Great video! Thanks!
Glad you liked it!
this is so good
Glad it was helpful :)
great explained
this is gold
great video. But I still have the problem of how to create the manufacturer object without breaking the code. In the main method, you have to decide what manufacture object should be created. You may use the if else condition to determine. Does it break the open close principle ?
Thanks! As long as it is on the client side you are fine. For example if you had a UI where you click on stuff that forwards you to the needed object, you won't even need the conditional if's because that UI construct will immediately make use of the appropriate logic! We will be uploading a video on how to make use of these patterns, so stay tuned!
How can I find the code from your video ?
Please refer to the description for our GitHub repository!
If I want to add a new company, Apple, with only one product, AppleMonitor, and extended Company to create a concrete factory, AppleManifacturer, it's forcing me to implement an unnecessary method to createGPU. How to solve this?
You need specialized factories or multiple specialized interfaces to keep using the pattern or you'll have to change the pattern. Hope this answers it!
How would this still apply to the Interface Segregation principle? Suppose the MSI or the ASUS factory does not produce one of these products. Is not this forceing the concrete factories to implement methods that they might not need?
Then maybe this pattern is not the best choice for your particular use-case! Additionally, feel free to watch our video on SOLID principles here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html! Cheers :)
I am confused, where will the actual decision to create which concrete product takes place? Like there need to some conditionals somewhere, like interpreting the customer request and deciding whether he needs an ASUS GPU or MSI monitor, right? Where would that conditional if-else block be placed?
That is the whole point! This decision is now moved to the client side :)
@@geekific But I keep reading this phrase about Factory method, goes like : "It helps in centralising the decision making part, so that if we later want to change something in that decision process, we only have to do it at one place".
So if the client gets to write their own conditions, then is it the responsibility of the client to keep the decision making centralized?
thnk you !!
No worries!
Nice vid
Thank you
So if the types of components extends to hundreds and thouands, which is very likely to happen in real life, how is the Company class going to handle? And if we go back to last class, why can’t we just implement createBeefBurger, createVeggieBurger like we did here?
Doesn't this still violate the open/close principle, since you need to edit the abstract factory class every time you add a new product? Like imagine adding a new product "headset", you'll have to modify all three classes Company, AsusManufacturer, MsiManufacturer. Even though creating some new methods is better than dealing with messy if-else statements, it is a compromise one needs to accept.
From Wikipedia: "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". So, in your example we do not violate the OCP, as Open-Closed means you are allowed to modify the way a system works without modifying the code that already exists, so, you can extend the existing code, but the *old code is still intact and doesn't need to be re-tested* .
@@geekific Thanks a lot for the clarification. Adding something to a class file doesn't necessarily have to mean "modifying existing code", got it.
Splitting hairs. Technically you’re not modify the actual code but you are modifying the class by adding new code. If someone fat fingers something or copy/pastes the wrong thing you’ve broken it. A true not open model would use reflection and inputs from an xml or json file that can be changed without touching any code at all.
But wouldnt each new product that is not a monitor or GPU mean you ha e to open the company code to add the abstract method?
A code cannot be closed for "modification" if it doesn't exist in the first place. The idea behind the principle is making any *new* functionality you add open for extension. Besides all the code is and will rely on the interfaces, hence other parts of our application will not even feel the addition you mentioned, but that's another principle :P Please check our SOLID video for a more detailed explanation: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html Cheers!
@@geekific Well what I mean is, say a company can now make CPUs and Fans as well. We have to add the abstract methods "createCPU()" and "createFan()" inside the company class. Then override those methods inside each manufacture class. Wouldn't that be what we are trying to avoid?
@@shadowwatcher5042 This is what I am not getting either. The IF statements can't seem to be taken out. SOLID isn't as solid as it wants to be. I don't think its possible to completely adhere to Open-closed.
I keep trying to think of a dynamic way it could be done by using external data files or mapping.
@@drcl7429 Perhaps each factory can be extended. So say we have factory1 that makes shoes and socks. The company expands and wants to make pants and shirts. So the second factory is simply called factory2 that extends factory1 and makes the clothes.
That way in the main function, factory2 can be used and still call factory1 methods.
Factory3 extends factory2 and makes jackets and hats. Then just use factory3 to get methods of 1 and 2
@@shadowwatcher5042 what about he IS-A principle?
Please check my other comment.
Umm, what if you have a manufacturer than have a GPU but not a monitor?
If you only have one, then I believe you are referring to the Factory Method Pattern: th-cam.com/video/EdFq_JIThqM/w-d-xo.html. Hope this helps!
@@geekific Thx for your comment. I actually mean, what if we have 3 factory methods, Gpu/Monitor/Cpu... and we have 3 Factory Creators, like MSI/Asus/Dell... but it does not make sense for the "Gpu" factory method for MSI, cuz MSI does not actually manufacture Gpu at all... how to deal with this? in this case is the Abstract Factory Pattern will not be suitable? Since it defines "a family of objects" so all factory method should be applicable to all factory creators? Or is it ok to just throw exception "Does not have Gpu" for MSI and it would not be a bad design?
There is nothing written in stone, you can mold these designs to suit your needs and in this case, in my opinion, the cleanest way to make the factory work is by applying the Interface Segregation Principle discussed here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html. So, you will have multiple specific abstract factories or interfaces, and you can pick which concrete factory implements which. However, during the creation you'll need to be aware of the one you'll be using.
@@geekific Appreciated
Hi, i'm wondering do you think java is still relevant? won't kotlin replace it? I really like java and I think that it needs to be improved, and not switched to other languages
Hey, I am actually cooking a video to discuss this topic! Stay Tuned :)
me salvaste las papas
ISP SOLID principal violation This design assumes that company abstract methods must be implemented by all manufacturers. What if a company doesn't want to manufacture some product it doesn't find value in. You will end up overriding methods which violate ISP.
You can create separate GPU and Monitor companies interfaces and let manufacturers implement the ones they need for ISP. This pattern answers a particular question and I didn't want to overwhelm everyone by overengineering the code, but yes, if that's what you are looking for, this works. You can check our SOLID video here: th-cam.com/video/HoA6aZPR5K0/w-d-xo.html. Cheers!