Спартанское программирование

В 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 освободит память, используемую этим объектом, и выделит другую.

9
задан travis 9 September 2008 в 04:33
поделиться

7 ответов

В Прагматически настроенном Программисте Hunt и Thomas говорят об исследовании, которое они называют Законом Demeter, и это фокусируется на связи функций к модулям кроме, там владеют. Позволяя функции никогда не достигнуть 3-го уровня в он связывает Вас, значительно сокращают количество ошибок и увеличивают пригодность для обслуживания кода.

Так:

ObjectA = getTheUser (session.getState () .getAccount () .getAccountNumber ());

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

Лучше:

Account.getUser ();

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

7
ответ дан 4 December 2019 в 09:15
поделиться

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

'Зона наилучшего восприятия' находится где-нибудь в середине.

5
ответ дан 4 December 2019 в 09:15
поделиться

Одно выражение на строку.

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

4
ответ дан 4 December 2019 в 09:15
поделиться

Я обычно нахожусь в, "короче лучший" лагерь. Ваш пример хорош:

ObjectA a = getTheUser(session.getState().getAccount().getAccountNumber());

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

obja State = session.getState();
objb Account = State.getAccount();
objc AccountNumber = Account.getAccountNumber();
ObjectA a = getTheUser(AccountNumber);

Это - компромисс:

objb Account = session.getState().getAccount();
ObjectA a = getTheUser(Account.getAccountNumber());

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

2
ответ дан 4 December 2019 в 09:15
поделиться

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

3
ответ дан 4 December 2019 в 09:15
поделиться

Хорошее объяснение. Я думаю, что это - версия общего Деления, и Завоюйте менталитет.

0
ответ дан 4 December 2019 в 09:15
поделиться

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

Вот несколько подсказок, которые я люблю использовать, чтобы нарезать и поставить на карту код:

  • Имена переменной: как Вы описали бы эту переменную кому-то еще в Вашей команде? Вы не сказали бы "numberOfLinesSoFar целое число". Вы сказали бы "numLines" или что-то подобное - понятный и короткий. Не притворяйтесь как специалист по обслуживанию, не знает код вообще, но удостоверяется, что Вы сами могли выяснить, какова переменная, даже если Вы забыли свое собственное действие относительно записи его. Да, это довольно очевидно, но это стоит больше усилия, чем я вижу многие кодеры, помещенные в него, таким образом, я перечисляю его сначала.
  • Поток управления: Избегайте большого количества заключительных пунктов сразу (серия}'s в C++). Обычно, когда Вы видите это, существует способ избежать его. Общий падеж - что-то как

:

if (things_are_ok) {
  // Do a lot of stuff.
  return true;
} else {
  ExpressDismay(error_str);
  return false;
}

может быть заменен

if (!things_are_ok) return ExpressDismay(error_str);
// Do a lot of stuff.
return true;

если мы можем заставить ExpressDismay (или обертка этого) возвращать false.

Другой случай:

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

Особый случай, который я обсудил бы здесь, против "правильного" способа использовать контейнер STL:

for (vector<string>::iterator a_str = my_vec.begin(); a_str != my_vec.end(); ++a_str)

намного более многословно, и требует перегруженных операторов указателя *a_str или a_str-> размер () в цикле. Для контейнеров, которые имеют быстрый произвольный доступ, следующее намного легче считать:

for (int i = 0; i < my_vec.size(); ++i)

со ссылками на my_vec [я] в теле цикла, которое не смутит никого.

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

0
ответ дан 4 December 2019 в 09:15
поделиться
Другие вопросы по тегам:

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