建造者设计模式

发布于 2024-10-07 10:44:14 字数 69 浏览 1 评论 0原文

最近在研究设计模式。我正在努力寻找一个可以为该场景实现构建器模式的场景。有人有例子吗?

任何答案将不胜感激。

I have been studying design patterns lately. I am struggling with finding a scenario that I can implement builder pattern for that scenario. Has anyone got any example?

Any answer will be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

青衫儰鉨ミ守葔 2024-10-14 10:44:14

SQLOrm 是一个很好的例子,它将构建器模式与一组适当的方法名相结合,从而构建SQL 感觉就像使用 DSL。

例如

private String getPersonAndmaybePet_JavaStr(boolean personName, boolean isAdult, int[] petTypes) {
  StringBuilder sb = new StringBuilder();
  // do SELECT
  sb.append("SELECT ");
  if(personName) 
    sb.append("person.name,");
  if(petTypes != null) 
    sb.append("pet.*,");

  // do FROM
  sb.delete(sb.length() - 1, sb.length()); // remove last comma
  sb.append(" FROM person,");
  if(petTypes != null) 
    sb.append(" Pet,");

  // do WHERE
  sb.delete(sb.length() - 1, sb.length()); // remove last comma
  sb.append(" WHERE ");
  if(isAdult) 
    sb.append(" person.age >= 18");
  else 
    sb.append(" person.age < 18");

  if(petTypes != null) {
    StringBuilder commaList = new StringBuilder();
    for(int id : petTypes) {
        commaList.append(id);
        commaList.append(",");
    }
    commaList.delete(commaList.length() - 1, commaList.length());
    sb.append(" AND person.pet_id = pet.id AND pet.pettype IN (" + commaList.toString() + ")");
  }
  return sb.toString();
}

变成

private String getPersonAndmaybePet(boolean personName, boolean isAdult, int[] petTypes) {
  SelectBuilder qry = new SelectBuilder();

  if(personName) 
    qry.select("person.name").from("person");    

  if(isAdult) 
    qry.from("person").where().and("person.age >= 18");
  else 
    qry.from("person").where().and("person.age < 18");

  if(petTypes != null) {
    qry.select("pet.*").from("Pet") //
            .where() //
            .and("person.pet_id = pet.id") //
            .and("pet.pettype IN (#)", QueryBuilderHelper.numbers(petTypes));
  }
  return qry.toSql();
}

SQLOrm serves as a nice example of combining the builder pattern with a proper set of methodnames making the construction of SQL feel like working with a DSL.

eg

private String getPersonAndmaybePet_JavaStr(boolean personName, boolean isAdult, int[] petTypes) {
  StringBuilder sb = new StringBuilder();
  // do SELECT
  sb.append("SELECT ");
  if(personName) 
    sb.append("person.name,");
  if(petTypes != null) 
    sb.append("pet.*,");

  // do FROM
  sb.delete(sb.length() - 1, sb.length()); // remove last comma
  sb.append(" FROM person,");
  if(petTypes != null) 
    sb.append(" Pet,");

  // do WHERE
  sb.delete(sb.length() - 1, sb.length()); // remove last comma
  sb.append(" WHERE ");
  if(isAdult) 
    sb.append(" person.age >= 18");
  else 
    sb.append(" person.age < 18");

  if(petTypes != null) {
    StringBuilder commaList = new StringBuilder();
    for(int id : petTypes) {
        commaList.append(id);
        commaList.append(",");
    }
    commaList.delete(commaList.length() - 1, commaList.length());
    sb.append(" AND person.pet_id = pet.id AND pet.pettype IN (" + commaList.toString() + ")");
  }
  return sb.toString();
}

becomes

private String getPersonAndmaybePet(boolean personName, boolean isAdult, int[] petTypes) {
  SelectBuilder qry = new SelectBuilder();

  if(personName) 
    qry.select("person.name").from("person");    

  if(isAdult) 
    qry.from("person").where().and("person.age >= 18");
  else 
    qry.from("person").where().and("person.age < 18");

  if(petTypes != null) {
    qry.select("pet.*").from("Pet") //
            .where() //
            .and("person.pet_id = pet.id") //
            .and("pet.pettype IN (#)", QueryBuilderHelper.numbers(petTypes));
  }
  return qry.toSql();
}
独留℉清风醉 2024-10-14 10:44:14

如果您有一个非常复杂的对象(例如需要 3、4 个或更多不同的其他对象才能操作),您将使用 Builder 来正确构造该对象。

If you have a very complex object (say something that requires 3, 4 or more different other objects in order to operate), you would use a Builder to construct this object correctly.

要走就滚别墨迹 2024-10-14 10:44:14

我喜欢在这里引用 Joshua Bloch 和他的书 Effective Java

在设计类时,构建器模式是一个不错的选择
构造函数或静态工厂将有多个
参数。

您肯定会遇到像这样的伸缩构造函数:

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }

它的问题是,在某些时候,很难记住所需参数的正确顺序以及所有构造函数之间的关系。

作为替代方案(还不是构建器),您可以在此处执行经典的 POJO

Pizza pizza = new Pizza(10);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);

但是,它不被认为是线程安全的。

怎么解决呢?是的,构建器模式。考虑一下:

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

    public Pizza build() {
      return new Pizza(this);
    }
  }

  private Pizza(Builder builder) {
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
}

您现在将创建的 Pizza 实例将是不可变的,并且它的构建将是简单而简洁的。

Pizza pizza = new Pizza.Builder(12)
                       .cheese(true)
                       .pepperoni(true)
                       .bacon(true)
                       .build();

查看更多 Java Builder 模式示例。

I love to refer here Joshua Bloch and his book Effective Java.

The builder pattern is a good choice when designing classes whose
constructors or static factories would have more than a handful of
parameters.

You surely encounter telescopic constructors such as this one:

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }

The problem with it is that at some point, it's hard to remember the right order of the arguments you need and what the relation between all the constructors.

As an alternative (not yet a builder), you can do a classic POJO here:

Pizza pizza = new Pizza(10);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);

But, it's not considered thread safe.

How to solve it? Yes, builder pattern. Consider this:

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

    public Pizza build() {
      return new Pizza(this);
    }
  }

  private Pizza(Builder builder) {
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
}

The instance of Pizza you will create now will be immutable and the constructing of it would be easy and concise.

Pizza pizza = new Pizza.Builder(12)
                       .cheese(true)
                       .pepperoni(true)
                       .bacon(true)
                       .build();

Check it out for more Java Builder pattern examples.

≈。彩虹 2024-10-14 10:44:14

构建器模式通常用于构造 HTML 和 XML 文档。例子:

require 'markaby' # Markaby is an HTML builder library for Ruby

builder = Markaby::Builder.new

builder.html {
  head {
    title 'Sample Title'
    link href: 'style.css', rel: 'stylesheet'
  }

  body {
    h1 'Sample Title'
    ul {
      li 'Item 1'
      li 'Item 2'
    }
  }
}

print builder

The Builder Pattern is often used to construct HTML and XML documents. Example:

require 'markaby' # Markaby is an HTML builder library for Ruby

builder = Markaby::Builder.new

builder.html {
  head {
    title 'Sample Title'
    link href: 'style.css', rel: 'stylesheet'
  }

  body {
    h1 'Sample Title'
    ul {
      li 'Item 1'
      li 'Item 2'
    }
  }
}

print builder
夜未央樱花落 2024-10-14 10:44:14

当面临许多构造函数参数时,请考虑使用构建器。以下链接详细解释也将消除所有疑虑。

http://www.drdobbs.com /jvm/creating-and-destroying-java-objects-par/208403883?pgno=2

简而言之,当构造函数参数很多而不是记住每个参数的顺序和含义时;构建器模式可用于简化参数传递,从而简化编程、提高可读性、增强参数按预期传递的信心。

Consider a builder when faced with many constructor parameters. The following link explains in good detail will clear all doubts as well.

http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=2

In a nutshell when there are many constructor parameters instead of remembering the order and the meaning of each parameter; builder pattern can be used to simplify parameter passing thereby simplifying programming, improved readability, increased confidence that parameters are passed as intended.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文