프로그램 실행 중에 로직이 동적으로 변경 될 경우 합성을 통해 로직을 위임해도 됩니다. 설명하는 것과 같은 복잡한 유효성 검사는 컴포지션을 통해 다른 클래스에 위임 할 수있는 후보만큼 좋습니다.
유효성 검사는 다른 순간에 발생할 수 있습니다.
예제와 같이 구체적 유효성 검사기를 인스턴스화하는 것은 Event 클래스를 해당 특정 유효성 검사기에 연결하기 때문에 좋지 않습니다.
DI 프레임 워크를 사용하지 않는다고 가정 해 봅시다.
유효성 검사기를 생성자에 추가하거나 setter 메서드로 주입 할 수 있습니다. 팩토리의 작성자 메소드는 Event와 validator를 인스턴스화 한 다음 이벤트 생성자 또는 setValidator 메소드로 전달하는 것이 좋습니다.
분명히 유효성 검사기 인터페이스 및 / 또는 추상 클래스를 작성하여 클래스가 구체적인 유효성 검사기가 아닌 인터페이스에 의존해야합니다.
검증하려는 모든 상태가 아직 제자리에 있지 않을 수 있으므로 생성자에서 validate 메소드를 실행하면 문제가 될 수 있습니다.
Validable 인터페이스를 만들고 클래스에서 구현하도록하자면 해당 인터페이스에 validate () 메서드가있을 수 있습니다.
이렇게하면 응용 프로그램의 상위 구성 요소가 마음대로 validate 메서드를 호출합니다 (이것은 유효성 검사기 멤버에게 위임 됨).
==> IValidable.java <==
import java.util.List;
public interface IValidable {
public void setValidator(IValidator<Event> validator_);
public void validate() throws ValidationException;
public List<String> getMessages();
}
==> IValidator.java <==
import java.util.List;
public interface IValidator<T> {
public boolean validate(T e);
public List<String> getValidationMessages();
}
==> Event.java <==
import java.util.List;
public class Event implements IValidable {
private IValidator<Event> validator;
@Override
public void setValidator(IValidator<Event> validator_) {
this.validator = validator_;
}
@Override
public void validate() throws ValidationException {
if (!this.validator.validate(this)){
throw new ValidationException("WTF!");
}
}
@Override
public List<String> getMessages() {
return this.validator.getValidationMessages();
}
}
==> SimpleEventValidator.java <==
import java.util.ArrayList;
import java.util.List;
public class SimpleEventValidator implements IValidator<Event> {
private List<String> messages = new ArrayList<String>();
@Override
public boolean validate(Event e) {
// do validations here, by accessing the public getters of e
// propulate list of messages is necessary
// this example always returns false
return false;
}
@Override
public List<String> getValidationMessages() {
return this.messages;
}
}
==> ValidationException.java <==
public class ValidationException extends Exception {
public ValidationException(String message) {
super(message);
}
private static final long serialVersionUID = 1L;
}
==> Test.java <==
public class Test {
public static void main (String args[]){
Event e = new Event();
IValidator<Event> v = new SimpleEventValidator();
e.setValidator(v);
// set other thins to e like
// e.setPlayers(player1,player2,player3)
// e.setNumberOfMatches(3);
// etc
try {
e.validate();
} catch (ValidationException e1) {
System.out.println("Your event doesn't comply with the federation regulations for the following reasons: ");
for (String s: e.getMessages()){
System.out.println(s);
}
}
}
}