在以下示例中使用抽象工厂而不是工厂方法有什么好处?

时间:2017-09-23 21:17:03

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

在写这个问题之前,我读了以下参考文献:

  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
  6. 我看到像我这样的很多人都遇到了困难"抓住"抽象工厂与工厂模式的具体区别。 我不熟悉设计模式,我遇到了这个例子http://www.oracle.com/technetwork/java/dataaccessobject-138824.html,我试图深化这个主题。

    通过比较,我看到3 DTO我们有:

    1)抽象工厂

    • 1个抽象类(有3个抽象方法和3个switch-cases);
    • 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?

    现在我只看到使用抽象工厂的美学概念上的区别,是否还有一个实用的好处,我无法掌握我对软件设计的无知?

2 个答案:

答案 0 :(得分:1)

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

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

    保持此通用计算是开放的,以便客户端根据其Shape定义重用。客户可以通过

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

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

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

    abstract class ShapeCreator{
         abstract Square createSquare();
         abstract Circle createCircle();
         // ...
    }
    
  4. 同样的界面可以由两个具体的工厂实现 1.FilledShapeCreator 2. HollowShapeCreator 具体的创建者都实现了从Square / Circle扩展的具体形状的方法,如下所示

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

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

答案 1 :(得分:1)

前一篇文章的一个注释您可以在Efecrive Java第二版中阅读工厂方法。 但是想象一下现实世界之间的差异,请看: 例如

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

抽象工厂

现在,考虑窗口的相同示例。你可以去木匠,或者你可以去窗口商店或PVC商店。他们都是窗户工厂。根据具体情况,您可以决定需要接近哪种工厂。

如此结论 - 这取决于你解决的问题。