What are the differences between Abstract Factory and Factory design patterns?

后端 未结 17 1177
醉话见心
醉话见心 2020-11-22 01:57

I know there are many posts out there about the differences between these two patterns, but there are a few things that I cannot find.

From what I have been reading,

相关标签:
17条回答
  • 2020-11-22 02:44

    The Difference Between The Two

    The main difference between a "factory method" and an "abstract factory" is that the factory method is a method, and an abstract factory is an object. I think a lot of people get these two terms confused, and start using them interchangeably. I remember that I had a hard time finding exactly what the difference was when I learnt them.

    Because the factory method is just a method, it can be overridden in a subclass, hence the second half of your quote:

    ... the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.

    The quote assumes that an object is calling its own factory method here. Therefore the only thing that could change the return value would be a subclass.

    The abstract factory is an object that has multiple factory methods on it. Looking at the first half of your quote:

    ... with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition ...

    What they're saying is that there is an object A, who wants to make a Foo object. Instead of making the Foo object itself (e.g., with a factory method), it's going to get a different object (the abstract factory) to create the Foo object.

    Code Examples

    To show you the difference, here is a factory method in use:

    class A {
        public void doSomething() {
            Foo f = makeFoo();
            f.whatever();   
        }
    
        protected Foo makeFoo() {
            return new RegularFoo();
        }
    }
    
    class B extends A {
        protected Foo makeFoo() {
            //subclass is overriding the factory method 
            //to return something different
            return new SpecialFoo();
        }
    }
    

    And here is an abstract factory in use:

    class A {
        private Factory factory;
    
        public A(Factory factory) {
            this.factory = factory;
        }
    
        public void doSomething() {
            //The concrete class of "f" depends on the concrete class
            //of the factory passed into the constructor. If you provide a
            //different factory, you get a different Foo object.
            Foo f = factory.makeFoo();
            f.whatever();
        }
    }
    
    interface Factory {
        Foo makeFoo();
        Bar makeBar();
        Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
    }
    
    //need to make concrete factories that implement the "Factory" interface here
    
    0 讨论(0)
  • 2020-11-22 02:44

    abstract factory design pattern with realtime example: what is an abstract factory design pattern? It is similar to the factory method design pattern. we need to use this pattern when we have multiple factories. there will be a grouping of factories defined in this pattern. factory method pattern is a subset of abstract factory design pattern. They have the same advantages as factory patterns. abstract factory relies on object composition whereas the factory method deals with inheritance. factory design pattern in java with a realtime example: what is the factory design pattern? it is mostly used design in object-oriented programming. It is one of the creational patterns. it is all about creating instances. Clients will create the object without exposed to object creational logic. it is widely used in different frameworks ex: the spring framework. we use this pattern when the class doesn’t know the objects of another it must create. Realtime example: when our car breaks down on the road. We need to inform the repairman about what type of vehicle we are using so that repairman will carry tools to fix the repair. as per our input, the repairman will fix the issue and make it ready for us to travel again. There are a few built-in methods that use these patterns. example getInstance() method in JavaUtilcalendar class. With help of getInstance(), we can get objects whenever we execute this method. Javautilcalendar : getInstance() is method return object. https://trendydevx.com/factory-design-pattern-in-java-with-realtime-example/

    0 讨论(0)
  • 2020-11-22 02:48

    The main difference between Abstract Factory and Factory Method is that Abstract Factory is implemented by Composition; but Factory Method is implemented by Inheritance.

    Yes, you read that correctly: the main difference between these two patterns is the old composition vs inheritance debate.

    UML diagrams can be found in the (GoF) book. I want to provide code examples, because I think combining the examples from the top two answers in this thread will give a better demonstration than either answer alone. Additionally, I have used terminology from the book in class and method names.

    Abstract Factory

    1. The most important point to grasp here is that the abstract factory is injected into the client. This is why we say that Abstract Factory is implemented by Composition. Often, a dependency injection framework would perform that task; but a framework is not required for DI.
    2. The second critical point is that the concrete factories here are not Factory Method implementations! Example code for Factory Method is shown further below.
    3. And finally, the third point to note is the relationship between the products: in this case the outbound and reply queues. One concrete factory produces Azure queues, the other MSMQ. The GoF refers to this product relationship as a "family" and it's important to be aware that family in this case does not mean class hierarchy.
    public class Client {
        private final AbstractFactory_MessageQueue factory;
    
        public Client(AbstractFactory_MessageQueue factory) {
            // The factory creates message queues either for Azure or MSMQ.
            // The client does not know which technology is used.
            this.factory = factory;
        }
    
        public void sendMessage() {
            //The client doesn't know whether the OutboundQueue is Azure or MSMQ.
            OutboundQueue out = factory.createProductA();
            out.sendMessage("Hello Abstract Factory!");
        }
    
        public String receiveMessage() {
            //The client doesn't know whether the ReplyQueue is Azure or MSMQ.
            ReplyQueue in = factory.createProductB();
            return in.receiveMessage();
        }
    }
    
    public interface AbstractFactory_MessageQueue {
        OutboundQueue createProductA();
        ReplyQueue createProductB();
    }
    
    public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
        @Override
        public OutboundQueue createProductA() {
            return new AzureMessageQueue();
        }
    
        @Override
        public ReplyQueue createProductB() {
            return new AzureResponseMessageQueue();
        }
    }
    
    public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
        @Override
        public OutboundQueue createProductA() {
            return new MsmqMessageQueue();
        }
    
        @Override
        public ReplyQueue createProductB() {
            return new MsmqResponseMessageQueue();
        }
    }
    

    Factory Method

    1. The most important point to grasp here is that the ConcreteCreator is the client. In other words, the client is a subclass whose parent defines the factoryMethod(). This is why we say that Factory Method is implemented by Inheritance.
    2. The second critical point is to remember that the Factory Method Pattern is nothing more than a specialization of the Template Method Pattern. The two patterns share an identical structure. They only differ in purpose. Factory Method is creational (it builds something) whereas Template Method is behavioral (it computes something).
    3. And finally, the third point to note is that the Creator (parent) class invokes its own factoryMethod(). If we remove anOperation() from the parent class, leaving only a single method behind, it is no longer the Factory Method pattern. In other words, Factory Method cannot be implemented with less than two methods in the parent class; and one must invoke the other.
    public abstract class Creator {
        public void anOperation() {
            Product p = factoryMethod();
            p.whatever();
        }
    
        protected abstract Product factoryMethod();
    }
    
    public class ConcreteCreator extends Creator {
        @Override
        protected Product factoryMethod() {
            return new ConcreteProduct();
        }
    }
    

    Misc. & Sundry Factory Patterns

    Be aware that although the GoF define two different Factory patterns, these are not the only Factory patterns in existence. They are not even necessarily the most commonly used Factory patterns. A famous third example is Josh Bloch's Static Factory Pattern from Effective Java. The Head First Design Patterns book includes yet another pattern they call Simple Factory.

    Don't fall into the trap of assuming every Factory pattern must match one from the GoF.

    0 讨论(0)
  • 2020-11-22 02:51

    A lot of the previous answers do not provide code comparisons between Abstract Factory and Factory Method pattern. The following is my attempt at explaining it via Java. I hope it helps someone in need of a simple explanation.

    As GoF aptly says: Abstract Factory provides an interface for creating families of related or dependent objects without specifying their concrete classes.

    public class Client {
        public static void main(String[] args) {
            ZooFactory zooFactory = new HerbivoreZooFactory();
            Animal animal1 = zooFactory.animal1();
            Animal animal2 = zooFactory.animal2();
            animal1.sound();
            animal2.sound();
    
            System.out.println();
    
            AnimalFactory animalFactory = new CowAnimalFactory();
            Animal animal = animalFactory.createAnimal();
            animal.sound();
        }
    }
    

    public interface Animal {
        public void sound();
    }
    
    public class Cow implements Animal {
    
        @Override
        public void sound() {
            System.out.println("Cow moos");
        }
    }
    
    public class Deer implements Animal {
    
        @Override
        public void sound() {
            System.out.println("Deer grunts");
        }
    
    }
    
    public class Hyena implements Animal {
    
        @Override
        public void sound() {
            System.out.println("Hyena.java");
        }
    
    }
    
    public class Lion implements Animal {
    
        @Override
        public void sound() {
            System.out.println("Lion roars");
        }
    
    }
    

    public interface ZooFactory {
        Animal animal1();
    
        Animal animal2();
    }
    
    public class CarnivoreZooFactory implements ZooFactory {
    
        @Override
        public Animal animal1() {
            return new Lion();
        }
    
        @Override
        public Animal animal2() {
            return new Hyena();
        }
    
    }
    
    public class HerbivoreZooFactory implements ZooFactory {
    
        @Override
        public Animal animal1() {
            return new Cow();
        }
    
        @Override
        public Animal animal2() {
            return new Deer();
        }
    
    }
    

    public interface AnimalFactory {
        public Animal createAnimal();
    }
    
    public class CowAnimalFactory implements AnimalFactory {
    
        @Override
        public Animal createAnimal() {
            return new Cow();
        }
    
    }
    
    public class DeerAnimalFactory implements AnimalFactory {
    
        @Override
        public Animal createAnimal() {
            return new Deer();
        }
    
    }
    
    public class HyenaAnimalFactory implements AnimalFactory {
    
        @Override
        public Animal createAnimal() {
            return new Hyena();
        }
    
    }
    
    public class LionAnimalFactory implements AnimalFactory {
    
        @Override
        public Animal createAnimal() {
            return new Lion();
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:53

    Real Life Example. (Easy to remember)

    Factory

    Imagine you are constructing a house and you approach a carpenter for a door. You give the measurement for the door and your requirements, and he will construct a door for you. In this case, the carpenter is a factory of doors. Your specifications are inputs for the factory, and the door is the output or product from the factory.

    Abstract Factory

    Now, consider the same example of the door. You can go to a carpenter, or you can go to a plastic door shop or a PVC shop. All of them are door factories. Based on the situation, you decide what kind of factory you need to approach. This is like an Abstract Factory.

    I have explained here both Factory method pattern and abstract factory pattern beginning with not using them explaining issues and then solving issues by using the above patterns https://github.com/vikramnagineni/Design-Patterns/tree/master

    0 讨论(0)
提交回复
热议问题