2014-02-15 3 views
3

저는 Dart에서 몇 가지 코드를 작성했습니다. 나는 공장 제작자를 정말 좋아하지만, 나는 그것이 유용하다는 점을 두려워하고있다. 특히 값 객체 클래스를 작성할 때 유효성 검사가 실패하면 null을 반환하는 경우가 있습니다. Dart의 팩토리 생성자에서 null을 반환 할 수 있습니까?

class EmailAddress { 
    static final RegExp _regex = new RegExp(...); 
    final String _value; 

    factory EmailAddress(String input) { 
    return _regex.hasMatch(input) ? new EmailAddress._internal(input) : null; 
    } 

    const EmailAddress._internal(this._value); 

    toString() => _value; 
} 

는 처음에는이 모든 나쁜 것 같지 않습니다. 그러나 실제로 사용하면 이것이 보입니다.

methodThatCreatesAnEmailAddress() { 
    var emailAddress = new EmailAddress("definitely not an email address"); 
    ... 
} 

이 나쁜 이유 인수는 Java 또는 C++과 같은 다른 정적으로 입력 된 언어에서 오는 개발자가, emailAddress는 항상 null 이외의 값으로 초기화 기대한다는 것입니다. 이것이 이것이 완벽하게 수용되는 이유는 생성자가 팩토리이며, 따라서 null 값을 반환 할 수 있다는 것입니다.

이렇게 나쁜 습관이나 유용한 기능을 활용하고 있습니까?

+0

'return _regex.hasMatch (input)? 새로운 EmailAddress._internal (입력) : throw "something went wrong"; 또한 잘못 전달 된 인수로 올바른 결과를 예상하는 경우 emailAddress가 항상 null이 아닌 값으로 초기화됩니다. – mezoni

+0

전자 메일 주소의 유효성 검사는 생성자에서 수행하지 말고 사용자가 요청할 때 수행하십시오. 가능한 한 빨리 확인하고 가능한 빨리 사용자에게 알려야합니다 (예 :이 경우 '보내기'버튼을 사용 중지하는 것이 좋습니다). – GameAlchemist

답변

2

다트 Factory software concept에 내장 된 factory 기능에 null 제한이 없기 때문에 null 값을 공장에서 반환 할 수 있습니다. 내가 질문을 바꿔 수있는 반면에

이 운영자가 null 값을 반환 할 수없는 그런 제한이 없기 때문에이 또한 허용

bool operator ==(other) { 
    return null; 
} 

"가 수용 할 수있는 평등 연산자에서 null을 반환하는 것입니다" .

하지만 또 다른 질문이 있습니까? 왜 그것을 어떻게 피하는가?

factory EmailAddress(String input) { 
    return _regex.hasMatch(input) ? new EmailAddress._internal(input) : 
    throw "something went wrong"; 
} 

P. 다트의 공장 contructors 구별하기가 매우 어렵 기 때문에 다트에 factory에서 null를 반환하는 것은 bad practice 것을

내 개인적인 의견.

바깥 쪽에서는 다른 종류의 개체를 만들 수 있기 때문에 더 강력하다는 차이점이있는 생성자처럼 보입니다.

또한 제한이 있지만 이것은 다른 이야기입니다 ...

+0

본인은 귀하의 의견에 동의합니다. 나는'var emailAddress = new EmailAddress.fromString (input); '과 같은 것을 고려하고있다. 이것은 사실 이것이 팩토리 생성자이고 반환 값이 null 일 수 있다는 것이 좀 더 분명하다고 생각합니다. – Andrew

+1

명명 된 생성자의 경우에도이 패턴을 반 패턴으로 간주합니다. 'new '로 생성자를 호출 할 때, 나는'null'을 기대하지 않는다. – Ganymede

1

나쁜 습관입니다. 누군가가 생성자를 호출 할 때 그들은 null이 아닌 값을 기대합니다. 귀하의 경우 내가 정적 메서드에서 유효성 검사를 할 수 있습니다 들어

:

class EmailAddress { 
    final String _value; 
    static final RegExp _regex = new RegExp(r"..."); 

    static bool isValid(String email) => _regex.hasMatch(email); 

    EmailAddress(this._value) { 
    if (!isValid(_value)) throw "Invalid email: $_value"; 
    } 
} 

지금 당신은 코드 재사용과 좋은 의미를 얻는다. 예 :

querySelector("#sendButton").disabled = !EmailAddress.isValid(userEmail); 
1

이렇게하지 마십시오. 생성자의 사용자로서 생성자의 클래스의 인스턴스를받을 것으로 예상됩니다. Dart에서 기존 인스턴스 또는 하위 유형의 인스턴스를 반환해도되지만 null은 반환하지 않습니다.

나는 당신이 원하는 일을하는 두 가지 옵션 중 하나를 권 해드립니다 :

  1. 가 유효하지 않은 입력에 예외가 발생. 이 방법을 사용하면 적어도 null을 어딘가에 저장 한 경우보다 오류가 일찍 발생합니다.

  2. 생성자 대신 정적 메서드를 사용하십시오. 정적 메서드는 null을 반환 할 수 있으며 혼동하지 않을 수 있습니다.

  3. int.parse과 같은 대체 경로를 제공하십시오. 오류가 발생하면 콜백을 받아 들일 수 있습니다.

나는 1 또는 3 자신을 선호합니다. 무언가가 유효하지 않을 때 명시 적으로 알고 싶습니다.

관련 문제