Сколько аргументов конструктора слишком многие?

Ну, лучший способ сделать это - не все. В целом модель обработки Искры не дает никаких гарантий относительно

  • , где
  • , когда
  • в каком порядке (исключая, конечно, порядок трансформации, определенные линией / DAG)
  • и сколько раз

задан фрагмент кода. Более того, любые обновления, которые напрямую зависят от архитектуры Spark, не являются деталями.

Это свойства, которые делают Spark масштабируемыми и устойчивыми, но в то же время это то, что делает очень сложным

Если все, что вам нужно, это простой кеш, то у вас есть несколько опций:

  • использовать один из методов, описанных в Tzach Zohar в Кэширование в Spark
  • использует локальное кэширование (за JVM или поток исполнителей) в сочетании с конкретным разделением приложений, чтобы сохранить локальные
  • для связи с внешними системами используют локальный кэш узла, не зависящий от Spark (например, прокси Nginx для http-запросов)

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

126
задан Aaronaught 7 August 2010 в 14:49
поделиться

14 ответов

Два подхода дизайна для рассмотрения

сущность шаблон

быстрый интерфейс шаблон

Они и подобны в намерении, в этом мы медленно создаем промежуточный объект и затем создаем наш целевой объект в одноэтапном.

пример быстрого интерфейса в действии был бы:

public class CustomerBuilder {
    String surname;
    String firstName;
    String ssn;
    public static CustomerBuilder customer() {
        return new CustomerBuilder();
    }
    public CustomerBuilder withSurname(String surname) {
        this.surname = surname; 
        return this; 
    }
    public CustomerBuilder withFirstName(String firstName) {
        this.firstName = firstName;
        return this; 
    }
    public CustomerBuilder withSsn(String ssn) {
        this.ssn = ssn; 
        return this; 
    }
    // client doesn't get to instantiate Customer directly
    public Customer build() {
        return new Customer(this);            
    }
}

public class Customer {
    private final String firstName;
    private final String surname;
    private final String ssn;

    Customer(CustomerBuilder builder) {
        if (builder.firstName == null) throw new NullPointerException("firstName");
        if (builder.surname == null) throw new NullPointerException("surname");
        if (builder.ssn == null) throw new NullPointerException("ssn");
        this.firstName = builder.firstName;
        this.surname = builder.surname;
        this.ssn = builder.ssn;
    }

    public String getFirstName() { return firstName;  }
    public String getSurname() { return surname; }
    public String getSsn() { return ssn; }    
}
import static com.acme.CustomerBuilder.customer;

public class Client {
    public void doSomething() {
        Customer customer = customer()
            .withSurname("Smith")
            .withFirstName("Fred")
            .withSsn("123XS1")
            .build();
    }
}
111
ответ дан 24 November 2019 в 00:54
поделиться

Если это не больше чем 1 аргумент, я всегда использую массивы или объекты как параметры конструктора и полагаюсь на проверку ошибок, чтобы удостовериться, что обязательные параметры там.

-1
ответ дан 24 November 2019 в 00:54
поделиться

Я договариваюсь о 7 пределах объекта упоминания Boojiboy. Кроме того, может стоить посмотреть на анонимный (или специализированный) типы, IDictionary или косвенность через первичный ключ к другому источнику данных.

1
ответ дан 24 November 2019 в 00:54
поделиться

Стиль имеет большое значение, и мне что кажется, если существует конструктор с 20 + аргументы, то дизайн должен быть изменен. Обеспечьте разумные значения по умолчанию.

2
ответ дан 24 November 2019 в 00:54
поделиться

Просто используйте параметры по умолчанию. На языке, который поддерживает аргументы метода по умолчанию (PHP, например), Вы могли сделать это в сигнатуре метода:

public function doSomethingWith($this = val1, $this = val2, $this = val3)

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

, Конечно, Вы могли также установить значения по умолчанию, когда Вы объявляете поля при размышлении соответствующим сделать так.

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

0
ответ дан 24 November 2019 в 00:54
поделиться

Я инкапсулировал бы подобные поля в собственный объект с его собственной логикой конструкции/проверки.

Говорят, например, если бы Вы имеете

  • BusinessPhone
  • BusinessAddress
  • HomePhone
  • HomeAddress

, я сделал бы класс, который хранит телефон и адрес вместе с тегом, указывающим, является ли это "домом" или "бизнес-" телефоном/адресом. И затем уменьшите эти 4 поля до просто массива.

ContactInfo cinfos = new ContactInfo[] {
    new ContactInfo("home", "+123456789", "123 ABC Avenue"),
    new ContactInfo("biz", "+987654321", "789 ZYX Avenue")
};

Customer c = new Customer("john", "doe", cinfos);

, Который должен заставить его меньше походить на спагетти.

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

И следующее также возможные решения:

  • Распространенный логика проверки вместо того, чтобы хранить его в едином классе. Проверьте, когда ввод данных пользователем их и затем проверяет снова на слое базы данных и т.д.
  • , Делают CustomerFactory класс, который помог бы мне создать Customer, решение s
  • @marcio также интересно...
1
ответ дан 24 November 2019 в 00:54
поделиться

Я думаю, что все это зависит от ситуации. Для чего-то как Ваш пример, клиентский класс, я не рискнул бы шансом наличия тех данных, являющихся неопределенным при необходимости. На обороте, передавая структуру разрешил бы список аргументов, но у Вас все еще будет много вещей определить в структуре.

3
ответ дан 24 November 2019 в 00:54
поделиться

Steve Mcconnell пишет в Коде, Завершенном, что люди испытывают затруднения при сохранении больше 7 вещами в их голове за один раз, таким образом, это было бы числом, я пытаюсь остаться под.

4
ответ дан 24 November 2019 в 00:54
поделиться

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

Затем сделайте метод считывания и функции метода set для каждого свойства так, чтобы значения по умолчанию могли быть изменены.

реализация Java:

public static void setEmail(String newEmail){
    this.email = newEmail;
}

public static String getEmail(){
    return this.email;
}

Это - также хорошая практика для хранения глобальных переменных безопасными.

3
ответ дан 24 November 2019 в 00:54
поделиться

Я думаю, что Ваш вопрос больше о дизайне Ваших классов, чем о количестве аргументов в конструкторе. Если бы мне были нужны 20 частей данных (аргументы) для успешной инициализации объекта, то я, вероятно, рассмотрел бы разбивание класса.

5
ответ дан 24 November 2019 в 00:54
поделиться

Я думаю, что "чистое ООП" ответ - то, что, если операции на классе недопустимы, когда определенные участники не инициализируются, затем эти участники должны быть установлены конструктором. Там всегда имеет место, где значения по умолчанию могут использоваться, но я предположу, что мы не рассматриваем тот случай. Это - хороший подход, когда API фиксируется, потому что, изменяя единственного допустимого конструктора после того, как API получает огласку, будет кошмар для Вас и всех пользователей Вашего кода.

В C#, что я понимаю о руководстве по проектированию, то, что это - не обязательно единственный способ обработать ситуацию. Особенно с объектами WPF, Вы найдете, что классы.NET имеют тенденцию способствовать конструкторам без параметров и выдадут исключения, если данные не были инициализированы к желательному состоянию прежде, чем назвать метод. Это, вероятно, главным образом характерно для компонентно-ориентированного дизайна хотя; я не могу придумать конкретный пример класса.NET, который ведет себя этим способом. В Вашем случае это определенно заставило бы увеличенную нагрузку при тестировании гарантировать, что класс никогда не сохраняется к хранилищу данных, если свойства не были проверены. Честно из-за этого я предпочел бы, чтобы "конструктор установил необходимые свойства" подход, если Ваш API или установлен в камне или не общедоступный.

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

5
ответ дан 24 November 2019 в 00:54
поделиться

В Вашем случае придерживайтесь конструктора. Информация принадлежит Клиента, и 4 поля прекрасны.

В случае у Вас есть много необходимых и дополнительных полей, конструктор не является лучшим решением. Как @boojiboy сказал, трудно читать, и также трудно написать клиентский код.

@contagious предложил использовать шаблон по умолчанию и методы set для дополнительного attributs. Это передает под мандат это, поля изменяемы, но это - незначительная проблема.

Joshua Block на Эффективном Java 2 говорит, что в этом случае необходимо рассмотреть разработчика. Пример взят из книги:

 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  
     private int calories         = 0;  
     private int fat              = 0;  
     private int carbohydrate     = 0;  
     private int sodium           = 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 carbohydrate(int val)  
       { carbohydrate = val;   return this; }  
     public Builder sodium(int val)  
       { sodium = 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;  
     soduim            = builder.sodium;  
     carbohydrate      = builder.carbohydrate;  
   }  
}  

И затем используют его как это:

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

пример выше был взят от Эффективный Java 2

, И это не делает только относится к конструктору. Цитирование Kent Beck в Шаблоны Реализации :

setOuterBounds(x, y, width, height);
setInnerBounds(x + 2, y + 2, width - 4, height - 4);

Создание прямоугольника, явного, поскольку, объект объясняет код лучше:

setOuterBounds(bounds);
setInnerBounds(bounds.expand(-2));
13
ответ дан 24 November 2019 в 00:54
поделиться

Если у Вас есть неприятно много аргументов, то просто пакет их вместе в структуры / классы POD, предпочтительно объявленные как внутренние классы класса, Вы создаете. Тем путем можно все еще потребовать полей при создании кода, который называет конструктора довольно читаемым.

3
ответ дан 24 November 2019 в 00:54
поделиться

В Более объектно-ориентированной ситуации проблемы можно использовать свойства в C#. Не помогает многому, если Вы создаете экземпляр объекта, но предполагаете, что у нас есть родительский класс, для которого нужны слишком много параметров в его конструкторе.
, Так как у Вас могут быть абстрактные свойства, можно использовать это в ваших интересах. Родительский класс должен определить абстрактное свойство, которое должен переопределить дочерний класс.
Обычно класс мог бы быть похожим:

class Customer {
    private string name;
    private int age;
    private string email;

    Customer(string name, int age, string email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
}

class John : Customer {
    John() : base("John", 20, "John@email.com") { 

    }
}

Это может стать грязным и нечитабельным со слишком многими параметрами.
принимая во внимание, что этот метод:

class Customer {
    protected abstract string name { get; }
    protected abstract int age { get; }
    protected abstract string email { get; }
}

class John : Customer {
    protected override string name => "John";
    protected override int age => 20;
    protected override string email=> "John@email.com";
}

, Который является намного более чистым кодом, по-моему, и никакими подрядчиками, необходимы в этом случае, который сохраняет комнату для других необходимых параметров.

0
ответ дан 24 November 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: