간단한 대답은 조작이 불가능할 때마다 (어플리케이션 또는 비즈니스 로직을 위반하기 때문에)입니다. 메소드가 호출되어 메소드 작성을 수행 할 수없는 경우 예외를 처리하십시오. 좋은 예는 제공된 매개 변수를 사용하여 인스턴스를 만들 수없는 경우 생성자가 항상 ArgumentExceptions를 발생시키는 것입니다. 다른 예는 InvalidOperationException이며, 이는 다른 멤버 또는 클래스 멤버의 상태로 인해 조작을 수행 할 수 없을 때 발생합니다.
귀하의 경우, Login (username, password)과 같은 메소드가 호출 된 경우, 사용자 이름이 유효하지 않은 경우, 실제로 UserNameNotValidException을 발생시키는 것이 정확합니다. 제공된 매개 변수를 사용하여 사용자를 로그인 할 수 없습니다 (즉, 인증을 위반하기 때문에 불가능 함). 예외를 발생시킵니다. 비록 당신의 두 예외가 ArgumentException에서 상속받을 수도 있습니다.
로그인 실패가 매우 일반적 일 수 있기 때문에 예외를 발생시키지 않으려면 한 가지 전략은 다른 실패를 나타내는 유형을 리턴하는 메소드를 작성하는 것입니다. 예를 들면 다음과 같습니다.
{ // class
...
public LoginResult Login(string user, string password)
{
if (IsInvalidUser(user))
{
return new UserInvalidLoginResult(user);
}
else if (IsInvalidPassword(user, password))
{
return new PasswordInvalidLoginResult(user, password);
}
else
{
return new SuccessfulLoginResult();
}
}
...
}
public abstract class LoginResult
{
public readonly string Message;
protected LoginResult(string message)
{
this.Message = message;
}
}
public class SuccessfulLoginResult : LoginResult
{
public SucccessfulLogin(string user)
: base(string.Format("Login for user '{0}' was successful.", user))
{ }
}
public class UserInvalidLoginResult : LoginResult
{
public UserInvalidLoginResult(string user)
: base(string.Format("The username '{0}' is invalid.", user))
{ }
}
public class PasswordInvalidLoginResult : LoginResult
{
public PasswordInvalidLoginResult(string password, string user)
: base(string.Format("The password '{0}' for username '{0}' is invalid.", password, user))
{ }
}
대부분의 개발자는 예외로 인해 발생하는 오버 헤드로 인해 예외를 피해야합니다. 리소스를 사용하는 것이 좋지만 일반적으로 응용 프로그램 디자인을 희생하지는 않습니다. 아마 두 예외를 던지지 말라고 들었을 것입니다. 예외 사용 여부는 일반적으로 예외 발생 빈도로 요약됩니다. 상당히 흔하거나 기대할 수있는 결과 인 경우 대부분의 개발자가 예외를 피하고 대신 리소스 소비로 인해 실패를 나타내는 다른 방법을 만드는 경우입니다.
다음은 Try () 패턴을 사용하여 방금 설명한 시나리오에서 예외 사용을 피하는 예입니다.
public class ValidatedLogin
{
public readonly string User;
public readonly string Password;
public ValidatedLogin(string user, string password)
{
if (IsInvalidUser(user))
{
throw new UserInvalidException(user);
}
else if (IsInvalidPassword(user, password))
{
throw new PasswordInvalidException(password);
}
this.User = user;
this.Password = password;
}
public static bool TryCreate(string user, string password, out ValidatedLogin validatedLogin)
{
if (IsInvalidUser(user) ||
IsInvalidPassword(user, password))
{
return false;
}
validatedLogin = new ValidatedLogin(user, password);
return true;
}
}