Является ли создание объектов в геттерах плохой практикой?

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

25
задан AnonJr 21 January 2010 в 17:21
поделиться

14 ответов

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

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

  2. Метод свойств может потребоваться дополнительная память или возвращает ссылку на то, что на самом деле не является частью состояния объекта, поэтому модификация возвращаемого объекта не влияет на исходный объект; Запрос поля всегда возвращает ссылку на объект, который гарантируется частью состояния исходного объекта. Работа с недвижимостью, которая возвращает копию, может быть очень запутанным для разработчиков, и эта характеристика часто не задокументирована.

  3. считают, что свойство не может быть передано как параметр OUT или REF для метода; поле может.

  4. Избегайте долгого имущества имущества. Метод свойств может занять много времени для выполнения; Полевой доступ всегда завершится немедленно.

  5. Избегайте бросания исключений из получений.

  6. Сохранение предыдущих значений, если установщик свойств бросает исключение

  7. , избегайте наблюдаемых побочных эффектов.

  8. Разрешить устанавливать свойства в любом порядке, даже если это приводит к временному неверному состоянию объектов.

Источники

« CLR через C # », Джеффри Рихтер. Глава 9. Определение свойств интеллектуально

« Рекомендации Рамочной конструкции « 2-е издание, Брэд Абрамс, Крзиштоф CWalina, Глава 5.2 Дизайн свойств

16
ответ дан 28 November 2019 в 20:33
поделиться

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

Примечание. Во избежание ожидания php завершения сценария exec 'd, передача выходных данных в файл:

exec('/path/to/file.php | output.log');

Кроме того, можно раскошелить сценарий с помощью функций PCNTL . При этом используется один php-скрипт, который при форсировке может определить, является ли он родителем или дочерним и действовать соответствующим образом. Существуют функции для передачи/приема сигналов с целью обмена данными между родителем/потомком, либо для записи дочернего файла в файл и чтения родительского файла из этого файла.

На странице руководства pcntl _ fork :

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}
-121--3770433-

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

Шаг # 1 : Остановите процесс MySQL Server.

Шаг # 2 : Запустите процесс MySQL (mysqld) server/daemon с параметром --skip-grant-tables, чтобы не запрашивать пароль.

Шаг # 3 : подключение к серверу mysql в качестве пользователя root.

Шаг # 4 : установка нового пароля корневой учетной записи mysql, т.е. сброс пароля mysql.

Шаг # 5 : выход и перезапуск сервера MySQL.

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

Шаг # 1 : Остановить службу mysql

# /etc/init.d/mysql stop

Вывод:

Stopping MySQL database server: mysqld.

Шаг # 2 : Запуск сервера MySQL без пароля:

# mysqld_safe --skip-grant-tables &

Вывод:

[1] 5988
Starting mysqld daemon with databases from /var/lib/mysql
mysqld_safe[6025]: started

Шаг # 3 : Подключение к серверу mysql с помощью клиента mysql:

# mysql -u root

Вывод:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.15-Debian_1-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>

Шаг # 4 : Установка нового пароля пользователя MySQL root

mysql> use mysql;
mysql> update user set password=PASSWORD("NEW-ROOT-PASSWORD") where User='root';
mysql> flush privileges;
mysql> quit

Шаг # 5 : Остановить MySQL Server:

# /etc/init.d/mysql stop

Вывод:

Stopping MySQL database server: mysqld
STOPPING server from pid file /var/run/mysqld/mysqld.pid
mysqld_safe[6186]: ended
[1]+  Done                    mysqld_safe --skip-grant-tables

Шаг # 6 : Запустите MySQL-сервер и протестируйте его

# /etc/init.d/mysql start
# mysql      
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 
# mysql -u root -p

Источник: http://www.cyberciti.biz/tips/recover-mysql-root-password.html

-121--947544-

Это плохая практика. Но если вы думаете об объектах как куча getters & setters вы должны проверить классические дискуссии на эту тему.

Как упомянули некоторые люди, ленивая нагрузка может быть причиной для этого. Зависит от фактической бизнес-логики, которую вы здесь моделируете. Следует создать отдельный метод, если он лучше для разборчивости, но если код для создания объекта прост, можно избежать неделимости.

0
ответ дан 28 November 2019 в 20:33
поделиться

Как у вас есть это плохо, но не Dis, похожее на приемлемую практику, называемую ленивую загрузку, которую можно прочитать здесь.

http://www.aspcode.net/lazy-loading-of-struckures-in-c-howto-part-8.aspx

0
ответ дан 28 November 2019 в 20:33
поделиться

Это зависит от вашего приложения. Если вам все еще нужно 3 из 4 классов, то было бы более идеально использовать Реестр, чем обрабатывать 3 независимо только потому, что вам не нужен четвертый. Загрузка классов лениво была бы одним из подходов к уменьшению занимаемой памяти, но затем вам нужно проинструктировать реестр, когда создавать объекты, и это мало чем отличается от обработки одиночек. Кроме того, можно создать конструктор n-параметров или использовать массив, чтобы указать реестру, какие классы следует создать во время построения.

class Registry {
    public $class1;
    public $class2;

    function __construct($uses) {
        foreach($uses as $class) {
            $this->{$class} = new {$class}();
        }
    }

}

Затем создайте экземпляр реестра, указав классы для создания экземпляра.

$reg = new Registry(array('class1'));

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

-121--3176691-

Вы можете написать свой собственный менеджер для модели (специальный для набора форм) и использовать его.

http://docs.djangoproject.com/en/dev/topics/db/managers/

-121--2959418-

Согласно мне, если что-то является «свойством», получатель должен вернуть вам свойство (в основном данные, которые уже существуют), соответствующее объекту.

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

Вместо этого я бы использовал метод типа GetMyObject (). Особенно если будет происходить «действие», я думаю, что в большинстве случаев лучше иметь метод, чем свойство имя .

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

2
ответ дан 28 November 2019 в 20:33
поделиться

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

0
ответ дан 28 November 2019 в 20:33
поделиться

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

, используйте класс обертки или подобное вместо этого.

2
ответ дан 28 November 2019 в 20:33
поделиться

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

0
ответ дан 28 November 2019 в 20:33
поделиться

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

0
ответ дан 28 November 2019 в 20:33
поделиться

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

У меня был класс с

private Collection<int> moo;

public Collection<int> Moo
{
  get 
  {
    if (this.moo == null) this.moo = new Collection<int>();
    return this.moo;
  }
}

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

this.moo.Add(baa);

, не проверяя его, было создано.

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

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

1
ответ дан 28 November 2019 в 20:33
поделиться

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

при чтении дважды из поля или свойства, вы ожидаете двух вещей:

  • нет никакого влияния на поведение (внешнего) объекта
  • вы получаете идентичные результаты

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

Object o1 = myInst.object;
Object o2 = myInst.object;
o1.poznamka = "some note";

в случае поля такие условия будут истинными:

o1 == o2;
o2.poznamka == "some note";

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

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

4
ответ дан 28 November 2019 в 20:33
поделиться
[11152841-

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

Однако это обычно не требуется на свойствах (т. Е. Геттерс и загадки), а как таковое считается плохой практикой.

8
ответ дан 28 November 2019 в 20:33
поделиться

Да, это плохая практика.

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

22
ответ дан 28 November 2019 в 20:33
поделиться

Свойство - это просто удобный способ выразить рассчитанное поле.

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

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

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

Также есть и готча недвижимости, где вы можете так легко и невинно звонить в недвижимость несколько раз и в конечном итоге запустить тот же код (который, надеюсь, не медленнее!).

1
ответ дан 28 November 2019 в 20:33
поделиться

Для написания кода, который легко протестирован, вы должны поддерживать разделение инициализации объекта.

I.E В то время как в тестовых случаях вы не удерживаете проверку некоторых конкретных предметов.

Как в доме объекта, вы не хотите тестировать что-либо, связанное с кухонным объектом. А ты вана тестирует только сад. Поэтому, хотя вы инициируете класс House и инициируете объект в некоторых конструкторах или в Getter, вы не будете кодировать хорошее, которое будет поддерживать тестирование.

1
ответ дан 28 November 2019 в 20:33
поделиться
Другие вопросы по тегам:

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