What are the real benefits of using the Abstract F

2020-02-02 00:59发布

问题:

Before writing the question I read the following references:

  1. Factory Method Vs Abstract Factory
  2. Abstract Factory vs Factory Method (scope)
  3. Abstract Factory, Factory Method, Builder
  4. Factory, Abstract Factory and Factory Method
  5. Differences between Abstract Factory Pattern and Factory Method

I see that many like me have had difficulty "grasping" the concrete differences between Abstract Factory and Factory Pattern. I'm not familiar with the design patterns, I came across this example http://www.oracle.com/technetwork/java/dataaccessobject-138824.html and I'm trying to deepen the topic.

By comparing, I see that for 3 DTO we have:

1) Abstract Factory

  • 1 abstract class (with 3 abstract methods and 3 switch-cases);
  • 3 factory classes for persistence type (each with 3 methods for obtaining DTO DAOs)
  • 3 interfaces and 9 DAOs.

2) Factory Method:

  • 3 factory classes, one for each interface (each with 3 switch-case);
  • Possibly I can create 3 superclasses from which to extend the DAO classes to not duplicate the code, such as that for connecting to the database;
  • 3 interfaces and 9 DAOs.

From the point of view of the quantity of code I do not see any substantial differences. In cases where you need to add a new persistence support or a new interface / DTO, the differences are minimal (and complementary).

From the client's point of view:

1) Abstract Factory:

public static final int PERSISTENCE_TYPE = DAOFactory.ORACLE;

DAOFactory daoFactory = DAOFactory.getDAOFactory(PERSISTENCE_TYPE);

CustomerDAO cDAO = daoFactory.getCustomerDAO();
AccountDAO aDAO = daoFactory.getAccountDAO();
OrderDAO oDAO = daoFactory.getOrderDAO();

2) Factory Method:

public static final int PERSISTENCE_TYPE = DAOFactory.ORACLE;

CustomerDAO cDAO = CustomerDAOFactory.getCustomerDAO(PERSISTENCE_TYPE);
AccountDAO aDAO = AccountDAOFactory.getAccountDAO(PERSISTENCE_TYPE);
OrderDAO oDAO = OrderDAOFactory.getOrderDAO(PERSISTENCE_TYPE);

Is there an advantage in using a DAOFactory regarding the persistence type and returns all DAOs related to that support instead of using multiple DAOFactory for each DTO to get the DAO for the type of persistence used?

For now I see only aesthetic-conceptual difference in using the Abstract Factory, is there also a utility benefit that I can not grasp for my ignorance about software design??

回答1:

One note to previous answear You can read factory method in Efecrive Java 2nd edition . But to imagin difference in real world between patterns please see : For example

Factory

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

Abstract Factory

Now, consider the same example of the window. You can go to a carpenter, or you can go to a window shop or a PVC shop. All of them are window factories. Based on the situation, you decide what kind of factory you need to approach.

So conclution - It depend on problem which you solve .



回答2:

When we say Factory design pattern, there are three versions under the umbrella. namely

  1. Static Factory : where we have method of kind

    Product getConcreteProduct(Key key){
        if (key.equals(key1) then {
            return ConcreteProduct1();
        } else {
            //... so on
        }
    

    It is useful to collect together creation of objects in hierarchy.

  2. Factory Method : This pattern is little difficult to appreciate, but the key is that we complete the business logic (e.g. computing parameters for shape) in an Abstract class in terms of only Abstract product (e.g. Shapes). we purposely keep an abstract method in this class for getting concrete product.

    abstract class GeometryMethod{
        void computeArea(){
            Shape shape getShape();
            // compute are
        }
        abstract Shape getShape();
    }
    

    It is useful to keep this generic computation open for clients to reuse as per their Shape definitions. Client can extend by

    Class CircleGeometry extends GeometryMethod{
        Shape getShape(){ // Factory Method
            return new Square(); // extending Shape
        }
    }
    

    Remember the client code has been written afterwards to suite Square type which was not existing when base class (giving area computation based on say coordinates) was not written. This pattern is generally used for frameworks.

  3. Abstract Factory : This is a general case of Factory method. Say we have Factory class which can create Shapes and has abstract methods to create family of shapes as follows

    abstract class ShapeCreator{
         abstract Square createSquare();
         abstract Circle createCircle();
         // ...
    }
    

Same interface can be implemented by two concrete Factories namely 1. FilledShapeCreator 2. HollowShapeCreator both the concrete creators implement methods for concrete Shapes extending from Square/ Circle as follows

    class FilledShapeCreator{
         Square createSquare(){
             return new FilledSquare(); // extends Square
         }
         // ...
    }

Based on specific key Choosing a specif Concrete factory helps in providing full range of product in different flavor. Again this also is more useful in defining business logic without specifying a specific flavor of family of product.