Last active
October 28, 2022 13:18
-
-
Save talhaHavadar/0b0db2755e57e2427713285fc5107804 to your computer and use it in GitHub Desktop.
Java validation structure by using combinator pattern #java #validation #combinator #designpatterns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.exceptions; | |
/** | |
* Created by talhahavadar on 13.03.2018. | |
*/ | |
public class InvalidPlateException extends RuntimeException { | |
private static final String message = "Plate information is not valid."; | |
public InvalidPlateException() { | |
this(message); | |
} | |
public InvalidPlateException(String message) { | |
super(message); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar; | |
import com.talhahavadar.models.Plate; | |
import com.talhahavadar.validation.PlateValidation; | |
import com.talhahavadar.validation.ValidationResult; | |
public class Main { | |
public static void main(String[] args) { | |
// write your code here | |
Plate istanbulPlate = new Plate(34, "AB", 3241); | |
System.out.println("First Validation check starts"); | |
PlateValidation.validateThat() | |
.validCityCode() | |
.fromBalikesir() | |
.validPlateCode() | |
.apply(istanbulPlate).getReason().ifPresent(e -> System.out.println(e.getMessage())); | |
System.out.println("\nSecond Validation check starts"); | |
ValidationResult result = PlateValidation.validateThat() | |
.validCityCode() | |
.fromIstanbul() | |
.validPlateCode() | |
.apply(istanbulPlate); | |
System.out.println(result.isValid()); | |
result.getReason().ifPresent(e -> System.out.println(e.getMessage())); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.models; | |
/** | |
* Created by talhahavadar on 13.03.2018. | |
*/ | |
public class Plate { | |
private int cityCode; | |
private String plateText; | |
private int plateCode; | |
public Plate(int cityCode, String plateText, int plateCode) { | |
this.cityCode = cityCode; | |
this.plateText = plateText; | |
this.plateCode = plateCode; | |
} | |
public int getCityCode() { | |
return cityCode; | |
} | |
public void setCityCode(int cityCode) { | |
this.cityCode = cityCode; | |
} | |
public String getPlateText() { | |
return plateText; | |
} | |
public void setPlateText(String plateText) { | |
this.plateText = plateText; | |
} | |
public int getPlateCode() { | |
return plateCode; | |
} | |
public void setPlateCode(int plateCode) { | |
this.plateCode = plateCode; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.validation; | |
import com.talhahavadar.exceptions.InvalidPlateException; | |
import com.talhahavadar.models.Plate; | |
import java.util.function.Predicate; | |
/** | |
* Created by talhahavadar on 13.03.2018. | |
*/ | |
public interface PlateValidation extends Validation<Plate> { | |
default PlateValidation validCityCode() { | |
return and(validate(plate -> { | |
if (plate.getCityCode() > 0 && plate.getCityCode() <= 81) { | |
return ResultHolder.<Plate>hold().that(plate).withResult(true).build(); | |
} | |
return ResultHolder.<Plate>hold().withException(new InvalidPlateException()).withResult(false).build(); | |
})); | |
} | |
default PlateValidation validPlateCode() { | |
return and(validate(plate -> { | |
if (plate.getCityCode() > 0 && plate.getCityCode() <= 9999) { | |
return ResultHolder.<Plate>hold().that(plate).withResult(true).build(); | |
} | |
return ResultHolder.<Plate>hold().withException(new InvalidPlateException()).withResult(false).build(); | |
})); | |
} | |
default PlateValidation fromBalikesir() { | |
return and(validate(plate -> plate.getCityCode() == 10 ? | |
ResultHolder.<Plate>hold().that(plate).withResult(true).build() : | |
ResultHolder.<Plate>hold().withException(new InvalidPlateException()).withResult(false).build())); | |
} | |
default PlateValidation fromIstanbul() { | |
return and(validate(plate -> plate.getCityCode() == 34 ? | |
ResultHolder.<Plate>hold().that(plate).withResult(true).build() : | |
ResultHolder.<Plate>hold().withException(new InvalidPlateException()).withResult(false).build())); | |
} | |
static PlateValidation validateThat() { | |
return validate(plate -> ResultHolder.<Plate>hold().withResult(true).build()); | |
} | |
static PlateValidation validate(Validate<Plate, Plate> validate) { | |
return plate -> { | |
ResultHolder<Plate> resultHolder = validate.doThat(plate); | |
return resultHolder.getException().isPresent() ? ValidationResult.invalid(resultHolder.getException().get()): | |
ValidationResult.valid(); | |
}; | |
} | |
default PlateValidation and(PlateValidation other) { | |
return plate -> { | |
ValidationResult validationResult = this.apply(plate); | |
return validationResult.isValid() ? other.apply(plate) : validationResult; | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.validation; | |
import java.util.Optional; | |
/** | |
* Created by talhahavadar on 13.03.2018. | |
*/ | |
public class ResultHolder<T> { | |
private T value; | |
private boolean result; | |
private Exception exception; | |
private ResultHolder() { | |
} | |
public ResultHolder(T value, boolean result) { | |
this.value = value; | |
this.result = result; | |
} | |
public ResultHolder(T value, boolean result, Exception exception) { | |
this(value, result); | |
this.exception = exception; | |
} | |
public static <R> ResultHolderBuilder<R> hold() { | |
return new ResultHolderBuilder<>(); | |
} | |
public T getValue() { | |
return value; | |
} | |
public boolean isValid() { | |
return result; | |
} | |
public Optional<Exception> getException() { | |
return Optional.ofNullable(exception); | |
} | |
public static class ResultHolderBuilder<T> { | |
private T value; | |
private boolean result; | |
private Exception exception; | |
private ResultHolderBuilder() { | |
} | |
public ResultHolderBuilder<T> that(T obj) { | |
this.value = obj; | |
return this; | |
} | |
public ResultHolderBuilder<T> withResult(boolean result) { | |
this.result = result; | |
return this; | |
} | |
public ResultHolderBuilder<T> withException(Exception exception) { | |
this.exception = exception; | |
return this; | |
} | |
public ResultHolder<T> build() { | |
return new ResultHolder<T>(value, result, exception); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.validation; | |
/** | |
* Created by talhahavadar on 13.03.2018. | |
*/ | |
@FunctionalInterface | |
public interface Validate<T, R> { | |
ResultHolder<R> doThat(T t); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.validation; | |
import java.util.function.Function; | |
/** | |
* Created by talhahavadar on 6.03.2018. | |
*/ | |
public interface Validation<T> extends Function<T, ValidationResult> { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.talhahavadar.validation; | |
import java.util.Optional; | |
/** | |
* Created by talhahavadar on 6.03.2018. | |
*/ | |
public interface ValidationResult { | |
static ValidationResult valid() { | |
return new ValidationResult() { | |
@Override | |
public boolean isValid() { | |
return true; | |
} | |
@Override | |
public Optional<Exception> getReason() { | |
return Optional.empty(); | |
} | |
}; | |
} | |
static ValidationResult invalid(Exception message) { | |
return new ValidationResult() { | |
@Override | |
public boolean isValid() { | |
return false; | |
} | |
@Override | |
public Optional<Exception> getReason() { | |
return Optional.of(message); | |
} | |
}; | |
} | |
boolean isValid(); | |
Optional<Exception> getReason(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment