Я уже несколько дней размышляю над проблемой дизайна (вонючий код). Может быть, вы можете помочь.
У меня есть метод "Login" в моем RegistrationService, и в настоящее время он выглядит упрощенным следующим образом:
public Boolean Login(String username, String password,
out String successRedirectUrl,
out IValidationDictionary validationResults)
{
successRedirectUrl = "";
if (!Validator.IsValid(username) || !Validator.IsValid(password)) return false;
// Other logic
// Distributed login requests etc.
// Build Redirect Url if login was successful etc.
}
код >
Хорошо, позвольте мне объяснить выше код. Возвращаемое значение метода (Boolean) должно указывать вызывающему, был ли запрос входа в систему успешным. Теперь, если это было успешно, мне нужно перенаправить пользователя на другой Url (таким образом, параметр "out" successRedirectUrl). Если он НЕ был успешным, мне нужно сообщить пользователю, что не так - таким образом, ValidationDictionary (Modelstate).
Этот код действительно уродливый и трудно поддерживать. Я думал о том, чтобы избавиться от типа возвращаемого типа Boolean (сразу возвращая SuccessRedirectUrl и проверяя сторону вызывающего, если он пуст), но я почувствовал, что все стало еще более неясным.
Любая идея, как сделать это лучше?
Спасибо!
Как насчет этого?
public class LoginOutput{
private bool _isLoginSuccess=false;
public bool IsLoginSuccess{/*Usual get set block*/}
private string _successRedirectUrl = String.Empty();
public string SuccessRedirectUrl{/*Usual get set block*/}
public IValidationDictionary ValidationResultDict{/*Usual get set block*/}
}
//your method now could be
public LoginOutput Login(string username, string password){
// your logic goes here
}
Создайте собственный класс для хранения всех трех значений и верните его. Избавьтесь от параметров "out".
Вопросы:
Является ли URL-адрес переадресации другим для разных пользователей? - Я бы сказал, что этого не должно быть, но если это другое, решение не должно быть в вашем бизнес-слое. Это логика пользовательского интерфейса и должна быть там.
Какой ваш интерфейс IValidationDictionary? Возможно, вы просто используете его прямо в логике пользовательского интерфейса:
public IValidationDictionary Login(string user, string password);
var user = "bob";
var validator = Login(user, "password");
if (validator.IsValid)
Response.Redirect(GetUserPage(user));
else
HandleLoginError();
Обратите внимание, что GetUserPage() не должен быть поиском базы данных или чем-то еще сложным. Опять же, это должна быть простая логика пользовательского интерфейса, что-то вроде:
public string GetUserPage(string user)
{
return "/MyPage/" + user;
}