Java 组合
简要概括我尝试了Java的组合模式。
结论是,函数式(组合模式)的代码可读性更高,但会消耗更多内存。速度几乎没有任何变化。
请参考
-
Combinator Pattern in Java 8
- Combinator Pattern in Java 8
-
- Javaラムダ式:コンビネーターパターンの改善
- functional programming
做法 (zuò fǎ)
程序型
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
编程语言中的函数式
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
结果 – jié guǒ
JVM 堆内存函数型的大小是124 KB,而过程型的大小是66 KB。
[QUICK PERF] Measured heap allocation (test method thread): 124.14 Kilo bytes (127 120 bytes)
[QUICK PERF] Measured heap allocation (test method thread): 66.49 Kilo bytes (68 088 bytes)
性能测试我试了几次,但结果感觉并没有太大的变化,函数式的方式稍微慢一些。
(可能是由于验证内容的原因)
Benchmark Mode Cnt Score Error Units
CombinatorPatternBenchmarkTest.functional thrpt 5 859447.226 ± 5632.616 ops/s
CombinatorPatternBenchmarkTest.imperative thrpt 5 865311.952 ± 4481.358 ops/s
附錄
整个代码
数据
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
以下是英文句子的中文释义:
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
编程语言中的函数式
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
结果 – jié guǒ
JVM 堆内存函数型的大小是124 KB,而过程型的大小是66 KB。
[QUICK PERF] Measured heap allocation (test method thread): 124.14 Kilo bytes (127 120 bytes)
[QUICK PERF] Measured heap allocation (test method thread): 66.49 Kilo bytes (68 088 bytes)
性能测试我试了几次,但结果感觉并没有太大的变化,函数式的方式稍微慢一些。
(可能是由于验证内容的原因)
Benchmark Mode Cnt Score Error Units
CombinatorPatternBenchmarkTest.functional thrpt 5 859447.226 ± 5632.616 ops/s
CombinatorPatternBenchmarkTest.imperative thrpt 5 865311.952 ± 4481.358 ops/s
附錄
整个代码
数据
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
以下是英文句子的中文释义:
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
JVM 堆内存函数型的大小是124 KB,而过程型的大小是66 KB。
[QUICK PERF] Measured heap allocation (test method thread): 124.14 Kilo bytes (127 120 bytes)
[QUICK PERF] Measured heap allocation (test method thread): 66.49 Kilo bytes (68 088 bytes)
性能测试我试了几次,但结果感觉并没有太大的变化,函数式的方式稍微慢一些。
(可能是由于验证内容的原因)
Benchmark Mode Cnt Score Error Units
CombinatorPatternBenchmarkTest.functional thrpt 5 859447.226 ± 5632.616 ops/s
CombinatorPatternBenchmarkTest.imperative thrpt 5 865311.952 ± 4481.358 ops/s
附錄
整个代码
数据
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
以下是英文句子的中文释义:
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
[QUICK PERF] Measured heap allocation (test method thread): 124.14 Kilo bytes (127 120 bytes)
[QUICK PERF] Measured heap allocation (test method thread): 66.49 Kilo bytes (68 088 bytes)
(可能是由于验证内容的原因)
Benchmark Mode Cnt Score Error Units
CombinatorPatternBenchmarkTest.functional thrpt 5 859447.226 ± 5632.616 ops/s
CombinatorPatternBenchmarkTest.imperative thrpt 5 865311.952 ± 4481.358 ops/s
附錄
整个代码
数据
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
以下是英文句子的中文释义:
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
数据
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
以下是英文句子的中文释义:
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
@AllArgsConstructor
@Data
public class Parson {
private String name;
private int age;
private String addr;
private String addr2;
}
枚举
public enum ValidationResult {
SUCCESS,
HOGE_CANNOT_BE_USED_IN_NAME,
ADDR_IS_TOO_LONG,
IS_A_CHILD,
}
办理程序验证器
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
函数式 (组合器模式) 验证器
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
public class ImperativeValidator {
public static ValidationResult isValidName(String name) {
return name.contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
public static ValidationResult isValidAddr(String addr) {
return addr.length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
public static ValidationResult isValidAge(int age) {
return age <= 18 ? IS_A_CHILD : SUCCESS;
}
}
interface CombinatorPatternValidator extends Function<Parson, ValidationResult> {
static CombinatorPatternValidator isValidName() {
return p -> p.getName().contains("hoge") ? HOGE_CANNOT_BE_USED_IN_NAME : SUCCESS;
}
static CombinatorPatternValidator isValidAddr() {
return p -> p.getAddr().length() > 100 ? ADDR_IS_TOO_LONG : SUCCESS;
}
static CombinatorPatternValidator isValidAge() {
return p -> p.getAge() <= 18 ? IS_A_CHILD : SUCCESS;
}
default CombinatorPatternValidator and(CombinatorPatternValidator other) {
return p -> {
var result = this.apply(p);
return result.equals(SUCCESS) ? other.apply(p) : result;
};
}
}
验证服务
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
测试代码
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
public class ValidationService {
public ValidationResult imperativeValidate(Parson parson) {
var result = ImperativeValidator.isValidName(parson.getName());
if (result != ValidationResult.SUCCESS) {
return result;
}
result = ImperativeValidator.isValidAddr(parson.getAddr());
if (result != ValidationResult.SUCCESS) {
return result;
}
return ImperativeValidator.isValidAge(parson.getAge());
}
public ValidationResult functionalValidate(Parson p) {
return CombinatorPatternValidator.isValidName()
.and(isValidAddr())
.and(isValidAge())
.apply(p);
}
}
堆栈测量
请参考Java中的堆大小测量JUnit5部分。
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
基准测试
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
@QuickPerfTest
public class CombinatorPatternTest {
ValidationService service = new ValidationService();
@MeasureHeapAllocation
@Test
void imperative() {
service.imperativeValidate(create());
}
@MeasureHeapAllocation
@Test
void functional() {
service.functionalValidate(create());
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}
参考にするJava性能測定ベンチマークのJUnit5編を使用ください。
@State(value = Scope.Benchmark)
public class CombinatorPatternBenchmarkTest {
ValidationService service = new ValidationService();
@Benchmark
public void imperative() {
service.imperativeValidate(create());
}
@Benchmark
public void functional() {
service.functionalValidate(create());
}
@Test
void benchMark() throws RunnerException {
Options opt = new OptionsBuilder()
.include(CombinatorPatternBenchmarkTest.class.getSimpleName())
.forks(1) // 1回実行
.warmupIterations(1) // 1回繰り返し
.build();
new Runner(opt).run();
}
Parson create() {
return new Parson(RandomStringUtils.randomAlphabetic(10), new Random().nextInt(100), RandomStringUtils.randomAlphabetic(20), RandomStringUtils.randomAlphabetic(20));
}
}