【问题标题】:What are the real benefits of using the Abstract Factory in the following example, instead of the factory method?在以下示例中使用抽象工厂而不是工厂方法的真正好处是什么?
【发布时间】:2018-03-05 04:37:14
【问题描述】:

在写问题之前,我阅读了以下参考资料:

  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

我看到许多像我一样的人很难“掌握”抽象工厂和工厂模式之间的具体区别。 我不熟悉设计模式,我遇到了这个例子http://www.oracle.com/technetwork/java/dataaccessobject-138824.html,我正在尝试加深这个话题。

通过比较,我发现对于 3 个 DTO,我们有:

1) 抽象工厂

  • 1 个抽象类(带有 3 个抽象方法和 3 个 switch-case);
  • 3 个持久化类型的工厂类(每个都有 3 种获取 DTO DAO 的方法)
  • 3 个接口和 9 个 DAO。

2) 工厂方法:

  • 3 个工厂类,每个接口一个(每个都有 3 个开关案例);
  • 可能我可以创建 3 个超类来扩展 DAO 类以不重复代码,例如用于连接到数据库的代码;
  • 3 个接口和 9 个 DAO。

从代码数量的角度来看,我没有看到任何实质性差异。 在您需要添加新的持久性支持或新接口/DTO 的情况下,差异很小(并且是互补的)。

从客户的角度来看:

1) 抽象工厂:

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) 工厂方法:

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);

在持久性类型方面使用 DAOFactory 并返回与该支持相关的所有 DAO,而不是为每个 DTO 使用多个 DAOFactory 来获取所用持久性类型的 DAO,是否有优势?

目前我只看到使用抽象工厂的美学概念差异,是否还有我对软件设计的无知无法掌握的实用优势?

【问题讨论】:

    标签: java design-patterns dao abstract-factory factory-method


    【解决方案1】:

    对先前答案的注释您可以阅读 Efecrive Java 2nd edition 中的工厂方法。 但是要想象现实世界中模式之间的差异,请参阅: 例如

    工厂

    想象一下,你正在建造一座房子,然后你找一个木匠找一扇窗户。你提出你的要求,他会建造一个窗口。在这种情况下,木匠是窗户工厂。您的规格是工厂的输入,窗口是工厂的输出。

    抽象工厂

    现在,考虑相同的窗口示例。你可以去木匠那里,也可以去橱窗店或PVC店。他们都是窗户工厂。根据情况,你决定你需要接近什么样的工厂。

    所以结论 - 这取决于你解决的问题。

    【讨论】:

      【解决方案2】:

      当我们说工厂设计模式时,共有三个版本。即

      1. 静态工厂:我们有一种方法

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

        在层次结构中收集对象的创建很有用。

      2. 工厂方法:这种模式不太难理解,但关键是我们在抽象类中仅根据抽象产品(例如形状)来完成业务逻辑(例如计算形状的参数)。我们特意在这个类中保留一个抽象方法来获取具体的产品。

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

        保持这种通用计算开放以供客户根据其形状定义重用是有用的。客户端可以扩展

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

        请记住,客户端代码后来被写入套件 Square 类型,当基类(根据坐标给出区域计算)未编写时,该类型不存在。这种模式通常用于框架。

      3. 抽象工厂:这是工厂方法的一般情况。 假设我们有可以创建形状的工厂类,并具有创建形状系列的抽象方法,如下所示

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

      相同的接口可以由两个具体的工厂实现,即 1. FilledShapeCreator 2. HollowShapeCreator 两位具体的创建者都实现了从 Square/Circle 扩展的具体形状的方法,如下所示

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

      基于特定的关键选择特定的混凝土工厂有助于提供不同风味的全系列产品。同样,这在不指定特定产品系列的情况下定义业务逻辑时也更有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-05
        • 2013-09-21
        • 1970-01-01
        • 1970-01-01
        • 2014-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多