2015-12-26 10 views
-1

У меня есть шаблон строителя, в котором, скорее всего, все мои параметры будут обязательными, поэтому я создал длинный конструктор, как показано ниже в коде.Как использовать шаблон строителя со всеми параметрами как обязательный?

public final class ResponseHolder { 

    // all below six are related to response information 
    private final String response; 
    private final boolean isLinking; 
    private final TypeHold typeOfId; 
    private final long userTimeInMs; 
    private final long userLmdInDays; 
    private final String maskInfo; 

    // below two are related to error handling 
    private final ErrorCode error; 
    private final StatusCode status; 

    private ResponseHolder(Builder builder) { 
     this.response = builder.response; 
     this.isLinking = builder.isLinking; 
     this.typeOfId = builder.typeOfId; 
     this.userTimeInMs = builder.userTimeInMs; 
     this.userLmdInDays = builder.userLmdInDays; 
     this.maskInfo = builder.maskInfo; 
     this.error = builder.error; 
     this.status = builder.status; 
    } 

    public static class Builder { 
     protected final String response; 
     protected final TypeHold typeOfId; 
     protected final String maskInfo; 
     protected final ErrorCode error; 
     protected final StatusCode status; 
     protected final boolean isLinking; 
     protected final long userTimeInMs; 
     protected final long userLmdInDays; 


     public Builder(String response, TypeHold typeOfId, String maskInfo, ErrorCode error, 
       StatusCode status, boolean isLinking, long userTimeInMs, long userLmdInDays) { 
      this.response = response; 
      this.typeOfId = typeOfId; 
      this.maskInfo = maskInfo; 
      this.error = error; 
      this.status = status; 
      this.isLinking = isLinking; 
      this.userTimeInMs = userTimeInMs; 
      this.userLmdInDays = userLmdInDays 
     } 

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

    // getters here 
} 

Теперь я смущаюсь, когда все параметры являются обязательными, то как это может быть полезно? Есть ли лучший способ представить мой шаблон выше Builder? Может ли логическая группировка параметров передаваться в их собственные классы, чтобы уменьшить количество параметров, передаваемых конструктору строителя?

Несмотря на то, что отдельные объекты упрощают вещи совсем немного, это также затрудняет работу, если вы не знакомы с кодом. Единственное, что я могу сделать, это переместить все параметры в свои собственные методы addParam(param), а затем выполнить проверку по требуемым параметрам в методе build() во время выполнения?

Что мне лучше всего подходит, и есть ли лучший подход, который я могу использовать здесь?

+3

Вы задали тот же вопрос вчера, я не уверен, почему бы его попросить снова. – YoungHobbit

+0

Я бы даже не назвал это шаблоном строителя. Ответ @Andreas, как строители, как правило, пишут. –

+3

Дэвид, если бы мой ответ не удовлетворял вас (ссылаясь на ваш предыдущий вопрос, на который я ответил), вы можете прокомментировать мой ответ, позволив мне обновить свой ответ, чтобы он лучше соответствовал вашей ситуации. Но вы не прокомментировали мой ответ, вы не обратили на него внимания, затем решили написать новый вопрос. Не круто –

ответ

3

Строитель освещал, когда есть много различных допустимых перестановок параметров, которые позволяют создать объект. Без шаблона Builder вам придется создавать множество уродливых и запутанных конструкторов для обработки всех возможных допустимых комбинаций параметров.

Но в вашем случае, есть только один действительный набор параметров, который позволяет создать объект. Для этого и нужен конструктор. Использование шаблона Builder здесь не только избыточно, оно просто не подходит.

Просто используйте обычный конструктор для вашего класса ResponseHolder.

+0

с обычным конструктором с большой линией для ResponseHolder также будет выглядеть уродливым? Есть ли какой-либо другой способ, которым я могу выполнить декомпозицию, может быть либо в шаблоне конструктора, либо в конструкторе, который может сделать его простым? – john

+0

@ david Да, см. Мой ответ. – Andreas

+2

Конструктор с несколькими параметрами не должен выглядеть уродливым, это зависит от вашего форматирования кода. Моя рекомендация в этот момент состоит в том, чтобы поместить первый параметр в ту же строку, что и конструктор, а затем выровнять остальные параметры под ним. Это может помочь как с удобочитаемостью (поскольку вы можете прокомментировать после каждой части), но и упростить код, так как вам не нужно добавлять дополнительную логику/код «builder» в ваш класс и т. Д., И конечный пользователь может использовать функции автозаполнения их IDE, чтобы помочь заполнить конструктор.) – mawalker

3

Цель шаблона построителя состоит в том, чтобы иметь конструктор no-arg, многие методы с именем именования, и метод окончательного завершения, который проверяет правильность указанной комбинации значений, прежде чем конструировать целевой объект.

В вашем случае, поскольку все значения требуются, основная цель шаблона построителя - предоставить форму поддержки именованных параметров.

Кроме того, ваш целевой объект должен иметь много-Arg конструктор, а не не принимать объект строитель в качестве аргумента)

Таким образом, ваш строитель должен быть (при условии отсутствия нулевых значений разрешено):

public static class Builder { 
    private String  response; 
    private TypeHold typeOfId; 
    private String  maskInfo; 
    private ErrorCode error; 
    private StatusCode status; 
    private Boolean isLinking; 
    private Long  userTimeInMs; 
    private Long  userLmdInDays; 

    public Builder setResponse(String response) { 
     this.response = response; 
     return this; 
    } 
    public Builder setTypeOfId(TypeHold typeOfId) { 
     this.typeOfId = typeOfId; 
     return this; 
    } 
    public Builder setMaskInfo(String maskInfo) { 
     this.maskInfo = maskInfo; 
     return this; 
    } 
    public Builder setError(ErrorCode error) { 
     this.error = error; 
     return this; 
    } 
    public Builder setStatus(StatusCode status) { 
     this.status = status; 
     return this; 
    } 
    public Builder setIsLinking(boolean isLinking) { 
     this.isLinking = isLinking; 
     return this; 
    } 
    public Builder setUserTimeInMs(long userTimeInMs) { 
     this.userTimeInMs = userTimeInMs; 
     return this; 
    } 
    public Builder setUserLmdInDays(long userLmdInDays) { 
     this.userLmdInDays = userLmdInDays; 
     return this; 
    } 
    public ResponseHolder build() { 
     if (this.response == null || 
      this.typeOfId == null || 
      this.maskInfo == null || 
      this.error == null || 
      this.status == null || 
      this.isLinking == null || 
      this.userTimeInMs == null || 
      this.userLmdInDays == null) { 
      throw new IllegalStateException("Not all required values given"); 
     } 
     return new ResponseHolder(this.response, 
            this.typeOfId, 
            this.maskInfo, 
            this.error, 
            this.status, 
            this.isLinking, 
            this.userTimeInMs, 
            this.userLmdInDays); 
    } 
} 

You теперь можете использовать его следующим образом:

ResponseHolder holder = new ResponseHolder.Builder() 
         .setResponse(response) 
         .setTypeOfId(typeOfId) 
         .setMaskInfo(maskInfo) 
         .setError(error) 
         .setStatus(status) 
         .setIsLinking(isLinking) 
         .setUserTimeInMs(userTimeInMs) 
         .setUserLmdInDays(userLmdInDays) 
         .build(); 
+0

Я вижу, мы делаем проверку проверки в методе сборки, которая будет выполняться во время выполнения? Можем ли мы обеспечить это во время компиляции случайно? – john

+0

@ david, нет, вы не можете. –

+0

@ Мне кажется, я предпочел бы более конкретное сообщение, поднятое из 'build()', но это, вероятно, витрина ;-) – Betlista