【问题标题】:Under Certain Circumstances is Using the Factory or Builder Pattern Nessesary在某些情况下需要使用工厂模式或生成器模式
【发布时间】:2016-05-02 01:26:24
【问题描述】:

我正在阅读以下链接:

Link 1

Link 2

Link 3

我注意到在使用工厂模式时,我看到的所有示例都使用工厂中的无参数构造函数。在最后一个链接中,建议如果参数增长,请考虑使用构建器模式。我了解何时以及如何使用构建器模式,但工厂模式让我感到困惑。如果你的子类有参数,其中一些是子类独有的,会发生什么?在这种情况下你会怎么做?

举个例子:

假设您有以下抽象类:

public abstract class Client {

    private String clientID;
    private String clientFirstName;
    private String clientLastName;

    public Client(String ID, String firstname, String lastname)
    {
        this.clientID = ID;
        this.clientFirstName = firstname;
        this.clientLastName  = lastname;

    }
}

以及以下子类:

public class Domestic extends Client {
    public Domestic(String ID, String firstname, String lastname) {
        super(ID, firstname, lastname);

    }
}


public class International extends Client {

  private List<String> documents;

  public International(String ID, String firstname, String lastname, List<String> documents) {
    super(ID, firstname, lastname);

       this.documents = documents;

    }

现在,参数不足以使用构建器模式是吗?这样做有什么问题吗:

Client international = new International(id, firstname, lastname, documents); 

International internationalObj = new International(id, firstname, lastname, documents);

【问题讨论】:

    标签: java design-patterns


    【解决方案1】:

    当你决定你实际上需要一棵树时会发生什么:

    Client
     |
     -- Domestic Client
     |
     -- International_client
        |
        |_ APAC Client
        |
        |_ EMEA client
        |
        |_ South America Client
        |
        |_ I'm not very creative, but imagine there are a bunch more.
    

    突然,当你需要实例化对象时,你的代码会变成这样:

    if (domestic) {
      client = new DomesticClient(...);
    } else if (international) {
      if (apac) {
        client = new APACClient(); 
      } else if (emea) {
        client = new EMEAClient();
      } else if (sa) {
        client = new SouthAmericaClient();
      } 
    ...
    }
    

    随着可能性数量的增加,您希望在代码库中散布这种杂物的可能性会下降。无论如何,也许您甚至不希望呼叫者需要知道他们拥有什么样的客户。抽象应该隐藏不同的实现,对吧?作为客户,我为什么要知道 John Smith 客户 ID 1234 是 International。也许我希望能够调用类似的东西:

     Client c = Client.ForCustomerId(id);
    

    或者

     Client c = Client.Build(id, firstname, lastname, documents);
    

    并神奇地获得适当的客户类型,而无需预知他们真正的客户类型。

    当您查看一个小问题时,许多设计模式在实用性方面并没有多大意义。当问题变得相当复杂时,它们就会发光。例如。 IMO 构建器模式在这里不会太有用 - 如果您 A)有大量选项,或者 B)根据不同的用例有不同/可选的选项,它会更有用。你所描述的有一组固定的小参数。

    现在,如果您开始添加一堆参数 - 也许您需要美国客户的 SSN 或欧盟客户的增值税信息等 - 当您拥有这些参数时,迁移到包含这些参数的 Builder 可能是有意义的,并最终生成对象。

    【讨论】:

      猜你喜欢
      • 2011-04-20
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多