web-dev-qa-db-ja.com

検証クラスの設計

この質問 のフォローアップです。私は受け入れられた回答が示唆することを実装することにしましたが、検証されるエンティティーが持つ各メンバーに対して個別のパブリックメソッドも必要であることを理解しました。

これは提案されたものです:

_public interface Validable {
    public void setValidator(Validator validator);
    public void validate() throws ValidationException;
    public List<String> getMessages();
}

public interface Validator<T> {
    public boolean validate(T e);
    public List<String> getValidationMessages();
}

public class EventValidator implements Validator<Event> {
    public boolean validate(Event e) {
        // validate each member here, as well as the entity as a whole
        return isValid;
    }

    // etc...
}
_

しかし、今はEventの各メンバーのパブリックメソッドが必要です。その理由は、リストまたはディクショナリへのアイテムの追加、データの初期化、データの変更など、同様の目的でEventセッターおよびメソッドでこれらの各メソッドを使用するためです。

だから私は次のようなものが必要になります:

_public class EventValidator implements Validator<Event> {
    // Validates the whole object
    public boolean validate(Event e) {
        // ...
    }

    public boolean validatePlayers() {
        // ...
    }

    public boolean validateCourts() {
        // ...
    }

    public boolean validateMatches() {
        // ...
    }
}
_

最初に必要なのは、 "main" validate(Event e)メソッドの_Event e_パラメーターをメンバー変数に変更して、残りのメソッドがそれらにアクセスできるようにすることです。しかし、これはエンティティーを検証ツールから分離するというこのデザインの全体のポイントに違反しています。

私のニーズをカバーするのに最も適したデザインは何ですか?ゼロから始めて、現在のデザインを完全に忘れてしまってもかまいません。

6
dabadaba

ValidableとValidatorは単一のエンティティの検証に関連するインターフェイスであり、エンティティの複合の検証をこのデザインに強制しようとしていることを理解するのに役立つと思います。バリデーターはイベントを検証するだけでよく、イベントを作成するためのルールを検証するためにそれを使用しないでください。 イベントイベント作成のルールを区別します。

この洞察を得ると、今後多くのオプションがあります。

テニスの試合をモデル化しているようです。その場合、イベントはおそらく何らかのマッチメーカーによって作成されるべきです。 (ビルダーパターンを使用するのに適していますか?)実際に検証したいのはイベントではなく、イベントの作成のプロセスのステップです。あなたが持っているデザインは個々のエンティティを検証するのに本当に素晴らしい仕事をしますが、今度はそれらのエンティティをイベントに構成するためのルールを検証する必要があります。

1
Price Jones

これは、複数の「ステップ」検証を個別に呼び出すことができる代替設計です。

==> IValidable.Java <==

import Java.util.List;

public interface IValidable {
    public void setValidator(IValidator<Event> validator_);
    public void validate(String stepTag) throws ValidationException, UnknownStepTagException;
    public String getLastValidationMessage();
}

==> IValidator.Java <==

import Java.util.List;

public interface IValidator<T> {
    public boolean validate(T e, String stepTag) throws UnknownStepTagException;
    public String getLastValidationMessage();
    public String getLastStepTag();
}

==> Event.Java <==

import Java.util.List;

public class Event implements IValidable {

    public static final String VALIDABLE_STEP_PLAYERS="PLAYERS";
    public static final String VALIDABLE_STEP_COURTS="COURTS";
    public static final String VALIDABLE_STEP_MATCHES="MATCHES";

    private IValidator<Event> validator;
    private String lastValidationMessage;

    @Override
    public void setValidator(IValidator<Event> validator_) {
        this.validator = validator_;
    }

    @Override
    public void validate(String stepTag) throws ValidationException, UnknownStepTagException {
        if (!this.validator.validate(this,stepTag)){
            throw new ValidationException("WTF!");
        }
    }

    @Override
    public String getLastValidationMessage() {
        return this.lastValidationMessage;
    }

}

==> SimpleEventValidator.Java <==

public class SimpleEventValidator implements IValidator<Event> {

    private String lastValidationMessage ="";
    private String lastStepTag="";
    @Override
    public boolean validate(Event e, String stepTag) throws UnknownStepTagException {
        // based on the stepTag executed appropiate privateMethod
        // this example always returns false    
        this.lastStepTag=stepTag;
        return false;
    }

    @Override
    public String getLastValidationMessage() {
        return this.lastValidationMessage;
    }

    @Override
    public String getLastStepTag() {
        return this.lastStepTag;
    }

    private boolean validateThis(){
        return false;
    }

    private boolean validateThat(){
        return false;
    }       

}

==> UnknownStepTagException.Java <==

public class UnknownStepTagException extends Exception {

}

==> ValidationException.Java <==

public class ValidationException extends Exception {
    public ValidationException(String message) {
        super(message);
    }

    private static final long serialVersionUID = 1L;
}

==> Test.Java <==

import Java.util.ArrayList;
import Java.util.List;

public class Test {
    public static void main (String args[]){
        Event e = new Event();
        IValidator<Event> v = new SimpleEventValidator();
        e.setValidator(v);
        List<String> messages = new ArrayList<String>();
        // set other thins to e like
        // e.setPlayers(player1,player2,player3)
        // e.setNumberOfMatches(3);
        // etc
        try {
            e.validate(Event.VALIDABLE_STEP_COURTS);
            messages.add(e.getLastValidationMessage());
            e.validate(Event.VALIDABLE_STEP_MATCHES);
            messages.add(e.getLastValidationMessage());
            e.validate(Event.VALIDABLE_STEP_PLAYERS);
            messages.add(e.getLastValidationMessage());
        } catch (ValidationException e1) {
            messages.add(e.getLastValidationMessage());
            System.out.println("Your event doesn't comply with the fedaration regulations for the following reasons: ");
            for (String s:messages){
                System.out.println(s);
            }
        } catch (UnknownStepTagException e2) {
            System.out.println("Unknown validation step "+v.getLastStepTag());
        }
    }
}

===============

0