Abstract factory on the fingers

I was forced to write this article for two reasons. Most recently, I met with the Abstract Factory pattern. As they say - "Do not know how to do it yourself, teach a friend." It is known that one of the best ways to consolidate material is to explain to someone previously studied. The second reason - in the process of studying this pattern, I did not come across material that for me personally would clearly state the essence of the Abstract Factory (at least on Habré).



So let's get started. The very first question that you need to answer yourself by studying this pattern: "What is an Abstract factory." The simplest and most accurate answer is that the Abstract Factory is a "factory of factories." But here a second question appears: “Why would anyone even need a“ factory of factories ”? To answer it, consider an example from real life.



Suppose you decide to take complete control of the car market. How to do it? You can create your car brand, your production, conduct a large-scale advertising company, etc. But, in this case, you have to fight with such giants of the car market as Toyota or Ford. It is not a fact that you will emerge victorious from this struggle. A much better solution would be to buy up the factories of all these companies, continue to produce cars under their own brands, and put the profit in your pocket. If I'm not mistaken, such a structure in the economy is called - holding. This holding will be the Abstract Factory or “Factory of Factories”. In our program, the Abstract factory (holding) will be represented by an interface or an abstract class. The enterprises included in the holding are represented by classes that implement this interface.



public interface CarsFactory { } public class ToyotaFactory implements CarsFactory {} public class FordFactory implements CarsFactory {}
      
      





Next, you gather the managers of your factories and say: “From now on, we will make cars with 2 types of body in our factories - a sedan and a coupe. For example, the Japanese will do ToyotaSedan and ToyotaCoupe, the Americans will do FordSedan and FordCoupe. ” And so that the factories do not forget what exactly needs to be done, and do not start, for example, SUVs, we will hang up the general drawings of the sedan and coupe in the office of our holding in the most visible place (at the particular factory, the engineers will figure out how to make the cars they need). Thus, 2 methods appear in our CarsFactory interface:



 public interface CarsFactory { Sedan createSedan(); Coupe createCoupe(); }
      
      





Accordingly, in the child classes of the CarsFactory interface, these methods must also be implemented.



 public class ToyotaFactory implements CarsFactory { @Override public Sedan createSedan() { return new ToyotaSedan(); } @Override public Coupe createCoupe() { return new ToyotaCoupe(); } } public class FordFactory implements CarsFactory { @Override public Sedan createSedan() { return new FordSedan(); } @Override public Coupe createCoupe() { return new FordCoupe(); } }
      
      





Note that the type of the return value in the methods will be exactly the type common to the return values ​​- sedan and coupe. Returning to our analogy - you told the factory to make a sedan - you got a sedan. Features, such as a Ford sedan, are not of interest to you.



As you can easily guess from the above code, some entities should appear in our program that describe specific body types - a sedan and a coupe. These entities will be interfaces.



 public interface Sedan {} public interface Coupe {}
      
      





And of course, these drawings should have a specific embodiment in the form of cars created in a particular factory.



 public class ToyotaCoupe implements Coupe { public ToyotaCoupe() { System.out.println("Create ToyotaCoupe"); } } public class ToyotaSedan implements Sedan { public ToyotaSedan() { System.out.println("Create ToyotaSedan"); } } public class FordCoupe implements Coupe { public FordCoupe () { System.out.println("Create FordCoupe"); } } public class FordSedan implements Sedan { public FordSedan() { System.out.println("Create FordSedan"); } }
      
      





That's all, our "factory of factories" capable of producing cars of any make and any type is ready. In the future, you may decide that it would be nice to start producing SUVs. You will need to create another interface, and hang a drawing of an SUV in the holding’s office (add the required method to CarsFactory and implement it in subsidiary factories). It is also possible that you decide to capture another piece of the market and buy, for example, all Nissan plants. This means that you need to create another class that implements CarsFactory - NissanFactory, and start producing your cars under this brand (NissanCoupe, NissanSedan, etc.)



But how will a specific user (car buyer) interact with our holding? The buyer generally does not know that you have captured all the automobile factories in the world. He comes to the small modest office of the holding and says: “I need a car!” “Excellent!” - we tell him, “you came to the address! A factory of factories is what you need! ”



 CarsFactory factory;
      
      





“Which company cars do you prefer at this time of day?”, We ask. Suppose a customer wants to purchase a Toyota. No problems!



 factory = new ToyotaFactory();
      
      





“And what type of body would you like?” Let's say a sedan. “Great choice!”



 factory.createSedan();
      
      





The car is ready, you can go!



All Articles