Alrite, я сразу перейду к коду:
public interface Visitor {
public void visitInventory();
public void visitMaxCount();
public void visitCountry();
public void visitSomethingElse();
public void complete();
//the idea of this visitor is that when a validator would visit it, it would validate data
//when a persister visits it, it would persist data, etc, etc.
// not sure if I making sense here...
}
public interface Visitable {
public void accept(Visitor visitor);
}
вот базовая реализация:
public class StoreValidator implements Visitor {
private List <ValidationError> storeValidationErrors = new ArrayList<ValidationError>();
public void addError(ValidationError error) {
storeValidationErrors.add(error);
}
public List<ValidationError> getErrors() {
return storeValidationErrors;
}
public void visitInventory() {
// do nothing
}
public void visitMaxCount() {
//do nothing
}
//... etc.. all empty implementations
}
Вы поймете, почему я сделал пустую реализацию здесь ... Я бы сейчас написал валидатор .. который расширяет StoreValidator
public XYZValidator extends StoreValidator {
@Override
public void visitInventory(Visitable visitable) {
// do something with visitable .. cast it to expected type
// invoke a DAO, obtain results from DB
// if errors found, do addError(new ValidationError()); with msg.
}
@Override
public void visitMaxCount(Visitable visitable) {
//do something with visitable..
}
// I wouldn't implement the rest coz they wouldn't make sense
// in XYZValidator.. so they are defined as empty in StoreValidator.
}
Теперь вот как будет выглядеть посетитель:
public Store implements Visitable {
public void accept(Visitor visitor) {
visitor.visitInventory();
visitor.visitMaxCount();
}
}
У меня мог бы быть код, который делает что-то подобное в списке объектов Store:
List<Store> stores; //assume this has a list of stores.
StoreValidator validator = new XYZValidator(); //or I would get it from a validatorfactory
for(Store store: stores) {
store.accept(validator); // so even if you send a wrong validator, you are good.
}
Точно так же у вас будет ABCValidator, который будет обеспечивать реализацию для других методов (visitCountry / visitSomethinElse), и он будет выходить из StoreValidator. У меня был бы другой тип Object (не Store), определяющий метод accept.
Я вижу здесь проблему ...
Скажем, мне нужен FileValidator, который отличается от StoreValidator, я ожидаю, что у него не будет ни одной из этих проверок, связанных с бизнесом, таких как visitInventory () и т. Д. Но, имея один интерфейс Visitor, я бы в конечном итоге объявил все виды методов в Интерфейс посетителя. Это верно? Это как ты это делаешь?
Я не знаю, правильно ли я понял схему или я что-то понимаю.
Пожалуйста, поделитесь своими мыслями.