Объявите при старте или как поедете? - PullRequest
3 голосов
/ 11 февраля 2010

Я бы сказал, что это в значительной степени стиль / удобочитаемость, хотя я вижу почти всю цель-с / какао, отформатированную в соответствии с "METHOD_002". Мне просто любопытно, если бы «METHOD_001» считался плохим стилем, есть преимущества наличия всех объявлений в верхней части метода, но опять же есть недостатки с точки зрения читабельности, если вы не объявляете объекты, где их используете? *

METHOD_001

-(IBAction)dateButtonPressed {

    NSDate      *dateSelected;
    NSString    *dateString;
    NSArray     *dateItems;
    NSString    *alertMessage;
    UIAlertView *alert;

    dateSelected = [datePicker date];
    dateString = [[NSString alloc] initWithFormat:@"%@", dateSelected];
    dateItems = [dateString componentsSeparatedByString:@" "];
    alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@",  [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
    alert = [[UIAlertView alloc] initWithTitle:@"You Selected" 
                                       message:alertMessage 
                                      delegate:nil 
                             cancelButtonTitle:@"OK" 
                             otherButtonTitles:nil];
    [alert show];
    [alert release];
    [alertMessage release];
    [dateString release];

}

METHOD_002

-(IBAction)dateButtonPressed {

    NSDate *dateSelected = [datePicker date];
    NSString *dateString = [[NSString alloc] initWithFormat:@"%@", dateSelected];
    NSArray *dateItems = [dateString componentsSeparatedByString:@" "];
    NSString *alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@",  [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You Selected" 
                                                    message:alertMessage 
                                                   delegate:nil 
                                          cancelButtonTitle:@"OK" 
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];
    [alertMessage release];
    [dateString release];

}

1009 * Гэри *

Ответы [ 6 ]

5 голосов
/ 11 февраля 2010

METHOD_002 определенно. Хотя некоторые могут предложить обоснования для METHOD_001, он существует в основном по техническим, историческим причинам. Более старым C-компиляторам требовались все переменные стека (локальные переменные), определенные перед любым исполняемым кодом. Это является частью стандарта ANSI. Его больше нет, и его следует отнести к истории.

METHOD_002 имеет несколько преимуществ:

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

  • Ловит другое случайное повторное использование. Например, вы определяете переменную «result» в верхней части функции и присваиваете ей значение nil. Ваш код предполагает, что это NULL в начале некоторого цикла. Затем вы добавляете больше кода вверху функции и по привычке повторно используете переменную «result». Возможно, вы только что создали непреднамеренные побочные эффекты для более позднего кода. Если вы используете METHOD_002, то вы либо сделаете предыдущий результат локальным для блока, либо получите ошибку компилятора, когда вы переопределите другую переменную с тем же именем в той же области видимости.

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

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

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

У METHOD_002 есть один недостаток:

  • Труднее найти тип переменной. Это менее важно для IDE, поскольку вы можете легко перейти к ее объявлению. И я утверждаю, что имя переменной обычно должно делать ее тип очевидным. Но все же иногда бывает трудно найти тип. Как следствие, иногда это может затруднить определение области видимости переменной.
1 голос
/ 11 февраля 2010

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

Пример последнего случая:

Использование method_002:

-(void) someMethod{
    //...some code
    SomeClass *myVar=[assign someValue];
    //...some more code
    if (someTest) {
        myVar=someValue;
    }else{
        myVar=someOtherValue;
    }
}

Если вы вернетесь к коду и посмотрите на myVar=someOtherValue;, вам придется пробираться назад по коду, чтобы найти определение. И наоборот, если вы используете method_001, вы получите:

-(void) someMethod{
    SomeClass *myVar;
    //...some code
    myVar=[assign someValue];
    //...some more code
    if (someTest) {
        myVar=someValue;
    }else{
        myVar=someOtherValue;
    }
}

И вы просто прыгаете наверх, чтобы увидеть определение.

Если вы используете этот стиль последовательно, вы будете автоматически знать, что любые переменные, определенные в начале функции / метода, будут иметь несколько назначений, а любые, определенные в теле, - нет.

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

1 голос
/ 11 февраля 2010

Определенно, МЕТОД_002. Меня научили METHOD_001 еще в тот день, когда я писал длинные, длинные и длинные блоки ASP-кода, и казалось, что тогда имеет смысл перечислить все переменные сверху, как предупреждение (в этом путешествии мы столкнемся со следующим ... ). На практике, однако, можно было смотреть на что-то, называемое strFwdBck, и удивляться, что было в кофе в тот день. У нас тогда не было предупреждений о «неиспользуемых переменных», по крайней мере, о которых я не знал.

Теперь я лишь заявляю о том, что мне действительно нужно, и немедленно использую это. И даже тогда я часто возвращаюсь и подтягиваю вещи.

-(IBAction)dateButtonPressed {
     NSString *dateString = [[NSString alloc] initWithFormat:@"%@", [datePicker date]];
     NSArray *dateItems = [dateString componentsSeparatedByString:@" "];

     NSString *alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@",        [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
    [dateString release];

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You Selected" 
                                                    message:alertMessage 
                                                   delegate:nil 
                                          cancelButtonTitle:@"OK" 
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];
    [alertMessage release];
}
1 голос
/ 11 февраля 2010

Я бы предпочел "МЕТОД_002". Он кажется более кратким и простым для чтения, хотя это может быть только потому, что я к нему привык.

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

0 голосов
/ 11 февраля 2010

Я думаю, что ваш метод 2 действительно находится на 1/2 пути между методом 1 и тем, что я бы назвал методом 3

метод 3 - это место, где вы объявляете переменные, где бы вы ни находились в коде, прямо перед их первым использованием. Если это в конце функции, пусть будет так.

Разница между способом 1 и 2 в ваших примерах, по-видимому, в основном заключается в инициализации. Я думаю, что инициализация переменных, когда вы объявляете их, является хорошей идеей и способствует удобочитаемости. Однако я также склонен думать, что объявление переменных в верхней части облегчает отладку. Если вы не читаете функцию сверху вниз, может быть сложно выяснить, где была объявлена ​​переменная и какого типа она может быть.

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

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

0 голосов
/ 11 февраля 2010

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

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

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