Предпочтительный способ объявления методов в классе - PullRequest
5 голосов
/ 30 августа 2011

У меня есть сомнения по поводу создания метода в классе для установки информации.

  1. создание отдельных методов для установки каждого атрибута

    class Address{
        private String name;
        private String city;
    
        public setName(String name) { ... }
        public setCity(String name) { ... }
    }
    
  2. создание единого метода для установки всех атрибутов

    class Address{
        private String name;
        private String city;
    
        public setAddress(String name,String city) { ... }
    }
    

сверху двумя способами, что предпочтительнее с точки зрения памяти?

Ответы [ 7 ]

4 голосов
/ 30 августа 2011

Обычной практикой является использование стиля JavaBean

class Address {
  private String name;
  private String city;

  public setName(String name){
    this.name = name;
  }

  public String getName() {
     return name;
  }

  public setCity(String city){
     this.city = city;
  }

  public getCity() {
    return city;
  }

}

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

class Address {
  private final String name;
  private final String city;

  public Address(String name, String city) {
      this.name = name;
      this.city = city;
  }

  public String getName() {
     return name;
  }

  public getCity() {
    return city;
  }
}

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

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

3 голосов
/ 30 августа 2011

Я не вижу, как эти два подхода будут различаться в отношении памяти.

Выберите подход, который наиболее целесообразно использовать в интерфейсе класса.

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

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


Для методов вообще Я быскажем, что разделение метода на две части мало влияет на потребление памяти.Каждый объект не получает свой собственный набор методов.Память, содержащая методы, распределяется между всеми экземплярами класса.


Практическое правило: Стремитесь сделать интерфейс вашего класса чистым и логичным.

2 голосов
/ 30 августа 2011

Почему бы не использовать метод # 2

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

Использование отдельного метода сеттера для каждогополе, которое вы хотите раскрыть

Обычная практика - иметь один метод установки для каждого поля в вашем классе, которое вы хотите раскрыть (т. е. ваш первый пример).Является ли это хорошей практикой, является дискуссионным, поскольку она заставляет класс быть изменяемым. Лучше сделать объект неизменным, если это возможно, по ряду причин .

Инициализация ваших полей с помощью конструктора

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

public class Address {
    public String name;
    public String city;

    private Address(String name, String city) {
        this.name = name;
        this.city = city;
    }
}

Инициализация полей с использованием шаблона Builder

Ниже приведена совершенно альтернативная реализация (вдохновленная этой статьей ), представляющая собой вариант шаблона Builder .Он имитирует изменчивость объекта без ущерба для читаемости.

public class Address {
    public String name;
    public String city;

    private Address() {}

    private void setName(String name) {
        this.name = name;
    }

    private void setCity(String city) {
        this.city = city;
    }

    static class Builder {
        private Address address = new Address();

        public Builder name(String name) {
            address.setName(name);
            return this;
        }

        public Builder city(String city) {
            address.setCity(city);
            return this;
        }

        public Address build() {
            return address;
        }
    }
}

С помощью вышеуказанного класса вы можете создать неизменный экземпляр класса Address следующим образом:

Address address = new Address.Builder()
        .name("Mansoor's address")
        .city("Toronto")
        .build();

Какой подход используетбольше памяти?

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

1 голос
/ 30 августа 2011

Nb.1 без сомнения.

И вы не пишете этот код вручную, только объявляете свои поля.

Тогда вы позволите Затмению сделать все остальное за вас.

В Eclipse используйте Source -> Генерировать геттеры и сеттеры.

Очень похожая конструкция, как # 2, делается в конструкторе объектов.

Обновленный вопрос по памяти. Не беспокойтесь в производственном коде о разнице в памяти между этими двумя способами.

1 голос
/ 30 августа 2011

Стандарт JavaBean должен иметь геттеры и сеттеры для каждого свойства: http://en.wikibooks.org/wiki/Java_Programming/Java_Beans. Если вы не хотите следовать этому стандартному соглашению, это то, что имеет смысл для вашего магазина.Как и в других ответах на эту тему, вероятно, существует минимальная дельта памяти, если таковая имеется.

1 голос
/ 30 августа 2011

Это не ясный вопрос. Вы имеете в виду, вы бы предпочли два метода, например setFoo(String) и setBar(int), или один метод, например setFooBar(String, int)? Это действительно зависит от того, являются ли они логически различными свойствами, и в этом случае вам нужны отдельные методы, или имеет смысл часто (или только) устанавливать их вместе. Вы можете предоставить оба.

Ни то, ни другое не влияет на память, нет.

0 голосов
/ 30 августа 2011

Обычно вы пишете метод установки и метод получения для каждого атрибута.

Я действительно не вижу случая, когда одного метода достаточно для установки всех атрибутов. В этом случае все атрибуты должны иметь одинаковое значение? Или вам всегда придется передавать параметры для всех атрибутов. Оба случая не совсем то, что вы хотите. Таким образом, вы должны явно предпочесть свой первый подход.

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