@vGrabko99
html, css, js, php, golang, mysql

Можно ли считать это «говнокодом»?

Привет. Хочу ещё на ранних стадиях изучения Go отучиться говнокодить. Мне кажется что я по тихому переношу запах своего кода с пхп на go вмести с проэктом :D
Вот функция валидации.
Если ps.ByName("data") пустой то отдаст 404 (на уровне роутера. В функции не видно)
Обновил код по совету ниже от Сергей Протько
Вроде бы поборол дублирование
Исправил "магические циферки"
и воспользовался двум правилами
- Один уровень абстракции на 1 функцию
- Чтение кода сверху в низ. Правило понижения

package auth

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"regexp"
	"strings"
)

var DB *sql.DB

func Validate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	result := strings.Split(ps.ByName("data"), "|][|")
	if result[0] == "login" {
		if validateLogin(result[1]) == true {
			fmt.Fprint(w, "valid|][|логин можно использовать при регистрации")
		} else {
			fmt.Fprint(w, "invalid|][|логин нельзя использовать при регистрации")
		}
	} else if result[0] == "email" {
		if validateEmail(result[1]) == true {

			fmt.Fprint(w, "valid|][|email можно использовать при регистрации")
		} else {
			fmt.Fprint(w, "invalid|][|email нельзя использовать при регистрации")
		}
	} else {
		fmt.Fprint(w, "err|][|Данный тип не поддерживается. Возможны login и email")
	}
}

func validateLogin(login string) bool {
	var rxLogin = regexp.MustCompile(`^(?:[0-9a-zA-Zа-яА-Яa-zA-ZáéíóúàâêôãõüçÁÉÍÓÚÀÂÊÔÃÕÜÇ\ \_\-\*\+\=]){1,16}$`)
	var result bool = rxLogin.MatchString(login)
	if result == true {
		return isLoginAvailable(login)
	} else {
		return false
	}
}
func validateEmail(email string) bool {
	var rxEmail = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$")
	var result bool = rxEmail.MatchString(email)
	if result == true {
		return isEmailAvailable(email)
	} else {
		return false
	}
}

func isLoginAvailable(login string) bool {
	rows, err := DB.Query("SELECT id FROM users WHERE login=?", login)
	if err != nil {
		return false
	}
	defer rows.Close()
	var i int = 0
	for rows.Next() {
		i++
	}
	if i == 0 {
		return true
	} else {
		return false
	}
}

func isEmailAvailable(email string) bool {
	rows, err := DB.Query("SELECT id FROM users WHERE email=?", email)
	if err != nil {
		return false
	}
	defer rows.Close()
	var i int = 0
	for rows.Next() {
		i++
	}
	if i == 0 {
		return true
	} else {
		return false
	}
}


Что теперь думаете?)
  • Вопрос задан
  • 803 просмотра
Решения вопроса 3
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
1) дублирование
2) разделить функцию на функции поменьше, что бы убрать вложенность ифов
3) пусть функция возвращает строки, и какая-то другая уже выводит это в stdout, что бы у вас это происходило все в одно месте.
Ответ написан
kumaxim
@kumaxim
Web-программист
Чтобы не сильно говнокодить, нужно сначала прочитать Роберта С Матртина "Чистый код".
А пишите Вы на Go, Java, C#, PHP, Python, Ruby и т.д. - это уже десятое дело...
Ответ написан
winordie
@winordie
Лучшая документация -- исходники
На сколько я понимаю назначение функции isLoginAvailable определить наличии логина в базе. В таком случае лучше писать
rows, err := DB.Query("SELECT EXISTS (SELECT id FROM users WHERE login=?)", login)

Вернет 1 если логин уже есть, 0 -- если нету.

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

if result == true { 
    return isLoginAvailable(login) 
} else { 
    return false 
}

Можно просто
return result && isLoginAvailable(login)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы