5 очень распространенных "запахов" кода и как их исправить


В этой статье мы рассмотрим 5 ОЧЕНЬ распространенных неприятных "запахов" кода (т.е. ошибок) и способы их устранения. 

Каждое из условных выражений должно иметь свою собственную строку

Вообще говоря, ваш код будет намного легче читать, если у каждого оператора есть своя строка. Исключением из правила является объединение else (или else / if) с окончанием предыдущего if. Однако, если вы пишете новое выражение if, важно поместить его в новую строку. Это предотвратит любые будущие ошибки, так как может быть не очевидно, что два оператора if не связаны логически.

//🚫

getBackgroundArt(track: Track): BackgroundImage {
 let backgroundImage: BackgroundImage;
 if(!track.getGenre()) {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url : this.DEFAULT_BACKGROUND_IMAGE_URL};
 } if (track.getGenre() == "hiphop") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.HIPHOP_BACKGROUND_IMAGE_URL};
 } if(track.getGenre() == "jazz") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.JAZZ_BACKGROUND_IMAGE_URL};
 } if(track.getGenre() == "rap") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.RAP_BACKGROUND_IMAGE_URL};
 } if(track.getGenre() == "country") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.COUNTRY_BACKGROUND_IMAGE_URL};
 }
 return backgroundImage;
}


//
getBackgroundArt(track: Track): BackgroundImage {
 let backgroundImage: BackgroundImage;
 if(!track.getGenre()) {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url : this.DEFAULT_BACKGROUND_IMAGE_URL};
 } else if (track.getGenre() == "hiphop") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.HIPHOP_BACKGROUND_IMAGE_URL};
 } else if(track.getGenre() == "jazz") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.JAZZ_BACKGROUND_IMAGE_URL};
 } else if(track.getGenre() == "rap") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.RAP_BACKGROUND_IMAGE_URL};
 } else if(track.getGenre() == "country") {
   backgroundImage = {dimension: BackgroundImageDimensions.small, url: this.COUNTRY_BACKGROUND_IMAGE_URL};
 }
 return backgroundImage;
}

Правильно комментируйте ваши дополнительные параметры

Необязательные параметры можно найти в большинстве языков программирования. Typescript использует '?', Java использует тип 'Optional', в PHP вы можете просто назначить значение по умолчанию для параметра метода. В Typescript/Javascript, подобно тому, как последнее предложение по умолчанию сохраняется в операторе switch, важно следовать соглашению, чтобы упростить разработку. Когда дело доходит до необязательных параметров, предпочтительно использовать «?» над неопределенным определением.

//🚫
export class Track {
 private name;
 private genre;
 private length;
 private backgroundImage : string | undefined;
 private album: string | undefined;
 private url: string | undefined;


//

export class Track {
 private name;
 private genre;
 private length;
 private backgroundImage? : string;
 private album?: string;
 private url?: string;
}

Остерегайтесь «Dead Stores»

Мертвое хранилище (Dead Stores) - это когда вы присваиваете значение переменной, но затем переназначается без фактического использования исходного значения. Вычисление или установка значения без его фактического использования в лучшем случае является пустой тратой ресурсов, а в худшем - ошибкой в вашем коде. Для следующих примеров давайте предположим, что у нас есть массив музыкальных треков, и мы хотим вычислить общее время исполнения всех песен. 

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

//🚫

public getLength(): number {
 let totalLength = 0;
 totalLength = this.tracks.reduce((count, track) => count + track.getLength(),0);
 //convert to minutes
 return totalLength;
}


//

public getLength(): number {
 const totalLength = this.tracks.reduce((count, track) => count + track.getLength(),0);
// do some formatting later
 return totalLength;
}

Не инвертируйте свои логические значения

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

//🚫

public deleteTrack(index: number) {
 // out of bound check
 if(!(index <= this.tracks.length)) {
   return;
 }

 this.tracks.splice(index,1);
}


//

public deleteTrack(index: number) {
 // out of bound check
 if(index >= this.tracks.length) {
   return;
 }

 this.tracks.splice(index,1);
}

Используйте шаблоны. Не объединяйте!

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

//🚫

createConnection({
   type: 'sqlite',
   database: path.resolve(__dirname, '..')+'/data/musicnow.sqlite',
   entities: [
       __dirname+'/models/*.ts'
   ],
});


//

createConnection({
   type: 'sqlite',
   database: `${path.resolve(__dirname, '..')}/data/musicnow.sqlite`,
   entities: [
       `${__dirname}/models/*.ts`
   ],
});

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


0 комментариев
Сортировка:
Добавить комментарий