简体   繁体   中英

Simple factory VS Factory Method (why use factory method at all)

Im trying to learn patterns and got to Factory, I understand the concept of simple factory and factory method, I know how they work, what I cant understand is what is the benefit of factory method over the simple factory. Example:

//We have our clients here
public class Animal {}
public class Dog extends Animal{}
public class Cat extends Animal{}

In a simple factory we will have this thing:

public Animal getAnimal(String type) {
    switch (type) {
    case "cat": 
      return new Cat;
    case "dog":
      return new Dog;
    }
    return null;
}

Now we go for the factory method:

public abstract class AnimalFactory {
   public Animal createAnimal() {
       Animal animal = getAnimal();
       animal.pet();
       return animal;
   }
  
   protected abstract Animal getAnimal();

}
public class DogFactory extends AnimalFactory{
   public Animal getAnimal(){
      //some logic
      return new Dog;
   }
}
public class CatFactory extends AnimalFactory{
   public Animal getAnimal(){
      //some logic
      return new Cat;
   }
}

So here comes the interesting part, for the factory method we will need to use polymorphism but we will still need to instantiate depending on what type we need so I imagine we will have something like this:

public Animal getAnimal(String type) {
    AnimalFactory animalFactory;
    switch (type) {
    case "cat": 
      animalFactory = new CatFactory();  //polymorphism     
      return animalFactory.getAnimal();
    case "dog":
       animalFactory = new DogFactory();  //polymorphism     
      return animalFactory.getAnimal();
    }
    return null;
}

So as far as I know the main idea behing design patterns is to make code more reusable and easier to extend, so imagine we need to add a new animal, say a Parrot. In both cases we create the Parrot class that extends the Animal class and in both cases we will have to go into that switch statement and add a new case "Parrot" For the simple factory we will just instantiate new Parrot directly and for the factory method we will instantiate the ParrotFactory. My question is what is the difference and why do we need the factory method pattern?

The only benefit I can see is that in the factory method you can define common logic for the factories that will extend it (is that it?)

The benefit of a Factory method is, typically, to contain the logic for a complex class (or class-hierarchy setup you require) that you don't want to obfuscate code or you don't want to create from scratch if they're used frequently. Eg. a car engine. So you extract away the messy code into a Factory to make the class-hierarchy more accessible/more reusable and to make the rest of your code more readable by hiding complex detail.

A critical difference in the GoF Factory Method Pattern as opposed to most other factory patterns is the identity of the client. In most factory patterns, the client is the caller of the factory.

class Client {
    Product p = someFactoryObject.method();
}

But in the Factory Method Pattern, the client is the (concrete) factory.

class Client extends Factory {
    @Override
    Product factoryMethod() {
        return new ConcreteProduct();
    }
}

The easiest way to think about why this factory subclassing relationship would make sense is to imagine the parent Factory as part of a framework. The framework must be compatible with any Product implementation, and it expects each client to define its own concrete product. These concrete products probably don't exist at the time the framework is written.

When the Client plugs itself into the framework (via inheritance) it defines a ConcreteProduct for the framework to use. In contrast to previous answers, this has nothing to do with encapsulating creational complexity. Indeed, the factory method implementation is one line of code.

The purpose is,

Factory Method lets a class defer instantiation to subclasses. (page 107)

Defer is the key. Factory Method allows you to implement an API in terms of an unknown product. Inheritance is the vehicle it uses to do that. Simple Factory was published (later) in Head First Design, as a teaching aid, not really intended for production code.

Confusion arises from the assumption that a factory method must be parameterized. This assumption leads to the conclusion that the purpose of a factory is to allow clients to pick and choose amongst multiple product implementations at runtime. Note the factoryMethod() here takes no parameters.

To understand the Factory Method Pattern, consider the scenario in which there is only one concrete product, it simply doesn't exist at the time the factory method API is defined, and isn't owned by the author of the API.

the benefit is it encapsulates the logic to create dogs for example. Any modification about creational of dog only happens on DogFactory (Single Responsibility). It's a good choice when you're going to do any setup about the object, like there are any codes before you return the dog object. If you do it on simple factory it would be messed up and make the method longer. But since on your example it's only do a simple new Dog() or new Cat() I prefer simple factory. IMHO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM