4

我知道这个问题被问了很多次,看起来这个问题是重复的,但我试图理解 SO、Google、GoF 上的帖子,但没有找到适合我的答案......

我了解工厂方法和生成器之间的区别:工厂方法 - 创建从特定基类派生的对象,将具体实现与客户端解耦

Builder Method - 隐藏客户端创建对象的复杂性

现在我看到了我在互联网上找到的示例(依赖注入的抽象工厂设计模式),它是关于抽象工厂的,但这对我的问题无关紧要。这只是我查看的众多文章之一

//Abstract Factory for Dependency Injection
//Factory interface
public interface Module1ServiceFactory {
 ComponentA getComponentA();
 ComponentB getComponentB();
}

//Concrete factory
public class Module1ServiceFactoryImpl {
 private Module1ServiceFactory instance;

 private Module1ServiceFactoryImpl() {}

 public static synchronized Module1ServiceFactory getInstance() {
  if (null == instance) {
   instance = new Module1ServiceFactoryImpl();
  }

return instance;
 }

*** SUBJECT METHOD ***
 public ComponentA getComponentA() {
  ComponentA componentA = new ComponentAImpl();
  ComponentB componentB = getComponentB();
  componentA.setComponentB(componentB);
  return componentA;
 }

 public ComponentB getComponentB() {
  return new ComponentBImpl();
 }
}

我在该示例中看到, ComponentA 是一种复杂类型, getComponentA() 方法用于构建它。

  1. 那么为什么这被称为工厂而不是建造者???或者这意味着 Module1ServiceFactoryImpl 实现了 Factory AND Builder 模式?
  2. 在软件架构设计中创建实现多个设计模式的类/对象是否正确(常用)?

对不起我的英语:)

4

3 回答 3

1

工厂模式基本上隐藏了实例化具体对象(与构造函数不同),而是强调创建对象的接口

相反,构建器模式通常有助于实现多步骤构建行为,其中某些步骤也可能是可选的。它强调将对象创建拆分为逻辑单元,而不是立即在语义上创建它,这与构造函数(或工厂方法)不同。

我希望以下示例可能更清楚地表达差异。

public class ComponentABuilder {
  private ComponentB componentB;
  private ComponentC componentC;

  public ComponentABuilder BuildComponentB(ComponentB b) {
    this.componentB = b;
  }

  public ComponentABuilder BuildComponentC(ComponentC c) {
    // Added another ComponentC, since just building B would
    // be pointless
    this.componentC = c;
  }

  public ComponentA Build() {
    // Might also be implemented via setters or whatever, the
    // point is that build now returns an object that is fully
    // built according to the steps the consumer performed via
    // the builder's methods, whereas a Factory Method would
    // do all the stuff by theirself.
    return new ComponentA(this.componentB, this.componentC);
  }
}

// Consumer sticks together his very own ComponentA
// in (usually) multiple steps
ComponentA c = new ComponentABuilder()
  .BuildComponentB(new ComponentBImpl()) // step 1
  .BuildComponentB(new ComponentCImpl()) // step 2
  .Build();

// Factory builds their ComponentA according to their
// own internal application, and getInstance is exposed
// as an "atomic" step to the consumer
ComponentA c2 = new ComponentAFactory().getInstance();

Builder Sample 是一个相当具体的案例,应用它是有意义的。但是,它也应该可用于不同的应用程序。

于 2012-06-19T10:14:10.253 回答
1

那么为什么这被称为工厂而不是建造者???或者这意味着 Module1ServiceFactoryImpl 实现了 Factory AND Builder 模式?

之所以叫工厂,是因为它是工厂,也是唯一的工厂

*** SUBJECT METHOD ***
 public ComponentA getComponentA() {
  ComponentA componentA = new ComponentAImpl();
  ComponentB componentB = getComponentB();
  componentA.setComponentB(componentB);
  return componentA;
 }

 public ComponentB getComponentB() {
  return new ComponentBImpl();
 }

我在这里没有看到建设者。当然,这不是最简单的方法,但如果引入构建器模式,它绝对不会那么复杂。这更像是 JavaBean 方式并在新创建的对象上使用 setter。Builder模式要求在最后一步创建对象,使创建对象不可能处于ready-to-use和not-ready-yet之间的状态。

在软件架构设计中创建实现多个设计模式的类/对象是否正确(常用)?

是的,它是正确的并且有时被使用。不是很常见,因为每种模式都会增加一些复杂性,而多种模式会增加多种复杂性 :) 但是,当然,您可以将 builder 与 factory 混合(builder 需要一些被分解的部分), facory 与 builder (工厂封装了创建对象的用法与建设者)。模式很好地协同工作。MVC 是很好的示例:

GoF(Gang of Four)并不将 MVC 称为设计模式,而是将其视为“一组用于构建用户界面的类”。在他们看来,它实际上是其他三种经典设计模式的变体:观察者(Pub/Sub)、策略和复合模式。根据 MVC 在框架中的实现方式,它也可能使用工厂模式和装饰器模式。

http://addyosmani.com/blog/understanding-mvc-and-mvp-for-javascript-and-backbone-developers/

于 2012-06-19T20:10:48.853 回答
0

这只是我的两分钱:

  1. Module1ServiceFactoryImpl 似乎正在实现单例模式,所有字段和构造函数都是私有的,并且 getInstance() 用于获取 self 的新实例。
  2. 如果 Module1ServiceFactoryImpl 实现了 Module1ServiceFactory,它可能是工厂模式。然后客户端代码可以使用工厂实现,如下所示。
class Client {
    public static void main(String[] args) {
        Module1ServiceFactory factory = Module1ServiceFactoryImpl.getInstance();
        ComponentA compA = factory.getComponentA();
        compA.printComponentA();

        ComponentB compB = factory.getComponentB();
        compB.printComponentB();
    }
}

class Module1ServiceFactoryImpl implements Module1ServiceFactory {
    private static Module1ServiceFactory instance;

    private Module1ServiceFactoryImpl() {
    }

    public static synchronized Module1ServiceFactory getInstance() {
        if (null == instance) {
            instance = new Module1ServiceFactoryImpl();
        }

        return instance;
    }

    public ComponentA getComponentA() {
        ComponentA componentA = new ComponentAImpl();
        ComponentB componentB = getComponentB();
        componentA.setComponentB(componentB);
        return componentA;
    }

    public ComponentB getComponentB() {
        return new ComponentBImpl();
    }
}

interface Module1ServiceFactory {
    ComponentA getComponentA();

    ComponentB getComponentB();
}

interface ComponentA {
    void setComponentB(ComponentB componentB);

    void printComponentA();
}

class ComponentAImpl implements ComponentA {
    ComponentB componentB;

    @Override
    public void setComponentB(ComponentB componentB) {
        this.componentB = componentB;
    }

    @Override
    public void printComponentA() {
        System.out.println("ComponentA");
    }
}

interface ComponentB {
    public void printComponentB();
}

class ComponentBImpl implements ComponentB {
    @Override
    public void printComponentB() {
        System.out.println("ComponentB");
    }
}
于 2018-06-07T15:24:01.190 回答