Chuyển đến nội dung chính

Effective Java 02 - Consider a builder when faced with many constructor parameters

 Khi một Object có thể được tạo từ nhiều attributes khác nhau thì chúng ta nên consider sử dụng Builder Pattern thay cho Static factories hoặc Constructors.

Ví dụ sử dụng Builder Pattern:

// Builder Pattern
public class NutritionFacts {
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;
  private final int sodium;
  private final int carbohydrate;
  public static class Builder {
  // Required parameters
  private final int servingSize;
  private final int servings;
  // Optional parameters - initialized to default values
  private int calories = 0;
  private int fat = 0;
  private int sodium = 0;
  private int carbohydrate = 0;
  public Builder(int servingSize, int servings) {
    this.servingSize = servingSize;
    this.servings = servings;
  }
  public Builder calories(int val) {
    calories = val;
    return this; 
  }
  public Builder fat(int val) {
    fat = val;
    return this; 
  }
  public Builder sodium(int val) { 
    sodium = val;
    return this; 
  }
  public Builder carbohydrate(int val) {
    carbohydrate = val;
    return this;
  }
  public NutritionFacts build() {
    return new NutritionFacts(this);
  }
}
  private NutritionFacts(Builder builder) {
    servingSize = builder.servingSize;
    servings = builder.servings;
    calories = builder.calories;
    fat = builder.fat;
    sodium = builder.sodium;
    carbohydrate = builder.carbohydrate;
  }
}

Client tạo instance:

NutritionFacts cocaCola = new NutritionFacts
  .Builder(240, 8)
  .calories(100)
  .sodium(35)
  .carbohydrate(27).build();

Ưu điểm

  • Code ở client dễ đọc.
  • Có thể validate các parameters trước khi tạo instance bằng cách implement trong method build.
  • Kỹ thuật kế thừa Abstract class với Builder

    // Builder pattern for class hierarchies
    public abstract class Pizza {
      public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
      final Set<Topping> toppings;
      abstract static class Builder<T extends Builder<T>> {
        EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
        public T addTopping(Topping topping) {
          toppings.add(Objects.requireNonNull(topping));
          return self();
        }
        abstract Pizza build();
        // Subclasses must override this method to return "this"
        protected abstract T self();
        }
      }
      Pizza(Builder<?> builder) {
        toppings = builder.toppings.clone();
      }
    }
    

  • Mỗi parameter tương ứng với một method builder và Object được tạo khi invoke method build làm cho Builder Pattern flexible hơn so với các cách tạo Object khác.

Nhược điểm

  • Chỉ hiệu quả đối với trường hợp class có nhiều optional attributes và việc sử dụng static factories hay constructor gây khó khăn cho client. Do vậy không nên quá lạm dụng Builder Pattern.
  • Việc sử dụng Builder Pattern có thể gây ảnh hưởng performance vì mỗi lần tạo object sẽ phải tạo builder cho nó.

Tổng kết

In summary, the Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if many of the parameters are optional or of identical type. Client code is much easier to read and write with builders than with telescoping constructors, and builders are much safer than JavaBeans.

Hy vọng bạn có được thêm kiến thức mới.
Keep learning 💪

Nhận xét

Bài đăng phổ biến từ blog này

Effective Java 01 - Consider static factory methods instead of constructors

Ở bài viết này, chúng ta sẽ bàn về cách để tạo Object trong Java. Để tạo mới một Object trong Java thì cách truyền thống là provide một public constructor và sử dụng keyword new ở client. Có một cách khác mà chúng ta nên biết và consider để sử dụng thay cho cách truyền thống đó là provide static factory methods . Vậy ưu điểm và nhược điểm của static factory methods là gì, chúng ta sẽ cùng tìm hiểu trong bài viết này. Cách truyền thống: Provide a public constructor Ví dụ: Class Student.java public class Student { private long id ; private String name ; public Student ( long id , String name ) { this . id = id ; this . name = name ; } } Client có thể tạo instance bằng cách sử dụng new keyword: Student student = new Student ( 1 , "Nguyễn Văn A" ); Sử dụng Static Factory Methods Ví dụ: Class Student.java public class Student { private long id ; private String name ; private Student ( long id , Strin...

CS-101 Network

Network là gì? Trong bài viết này chúng ta sẽ tìm hiểu các kiến thức về mạng căn bản như LAN, IP Address, Internet - TCP/IP Standards. Khái niệm về Network? Network là một tập hợp các máy tính, server, mainframe, thiết bị mạng, thiết bị ngoại vi hoặc các thiết bị khác được kết nối để cho phép chia sẻ dữ liệu, trao đổi tệp và giao tiếp với nhau. Hiểu đơn giản là các thiết bị được kết nối để cho phép chia sẻ dữ liệu với nhau được gọi là network (mạng). LAN (Local Area Network) Có thể giải thích một cách dễ hiểu:      Network ➡ tập hợp các thiết bị được kết nối để cho phép chia sẻ dữ liệu với nhau.      Local Area ➡ khu vực nội bộ (khu vực địa lý giới hạn như văn phòng, quán cafe, trong nhà,...) Ví dụ:      Trong một phòng máy tính ở trường, các máy tính kết nối với nhau để chia sẻ dữ liệu (gửi file, chơi game,...) được gọi là một mạng LAN.     Trong văn phòng công ty, các máy tính cũng được kết nối với nhau để chia sẻ dữ liệu cũng đượ...