public class User {
// 用户 id
private Long uid;
// 用户的部门,为了保持示例简单,这里就用普通的字符串
// 需要远程调用 通讯录系统 获得
private String department;
// 用户的主管,为了保持示例简单,这里就用一个 id 表示
// 需要远程调用 通讯录系统 获得
private Long supervisor;
// 用户所持有的权限
// 需要远程调用 权限系统 获得
private Set<String> permission;
}
public boolean isSupervisor(User u1, User u2) {
return Objects.equals(u1.getSupervisor(), u2.getUid());
}
Supplier<Integer> a = () -> 10 + 1;
int b = a.get() + 1;
/**
* 为了方便与标准的 Java 函数式接口交互,Lazy 也实现了 Supplier
*/
public class Lazy<T> implements Supplier<T> {
private final Supplier<? extends T> supplier;
// 利用 value 属性缓存 supplier 计算后的值
private T value;
private Lazy(Supplier<? extends T> supplier) {
this.supplier = supplier;
}
public static <T> Lazy<T> of(Supplier<? extends T> supplier) {
return new Lazy<>(supplier);
}
public T get() {
if (value == null) {
T newValue = supplier.get();
if (newValue == null) {
throw new IllegalStateException("Lazy value can not be null!");
}
value = newValue;
}
return value;
}
}
Lazy<Integer> a = Lazy.of(() -> 10 + 1);
int b = a.get() + 1;
// get 不会再重新计算, 直接用缓存的值
int c = a.get();
public class User {
// 用户 id
private Long uid;
// 用户的部门,为了保持示例简单,这里就用普通的字符串
// 需要远程调用 通讯录系统 获得
private Lazy<String> department;
// 用户的主管,为了保持示例简单,这里就用一个 id 表示
// 需要远程调用 通讯录系统 获得
private Lazy<Long> supervisor;
// 用户所含有的权限
// 需要远程调用 权限系统 获得
private Lazy<Set<String>> permission;
public Long getUid() {
return uid;
}
public void setUid(Long uid) {
this.uid = uid;
}
public String getDepartment() {
return department.get();
}
/**
* 因为 department 是一个惰性加载的属性,所以 set 方法必须传入计算函数,而不是具体值
*/
public void setDepartment(Lazy<String> department) {
this.department = department;
}
// ... 后面类似的省略
}
Long uid = 1L;
User user = new User();
user.setUid(uid);
// departmentService 是一个rpc调用
user.setDepartment(Lazy.of(() -> departmentService.getDepartment(uid)));
// ....
String department = departmentService.getDepartment(uid);
Long supervisor = SupervisorService.getSupervisor(department);
在盒子中装的是类型,而不是 1 和 "1" 的原因是,盒子中不一定是单个值,比如集合,甚至是更加复杂的多值映射关系。
// 反例,不能成为函子,因为这个方法没有在盒子中如实反映 function 的映射关系
public Box<S> map(Function<T,S> function) {
return new Box<>(null);
}
public <S> Lazy<S> map(Function<? super T, ? extends S> function) {
return Lazy.of(() -> function.apply(get()));
}
Lazy<String> departmentLazy = Lazy.of(() -> departmentService.getDepartment(uid));
Lazy<Long> supervisorLazy = departmentLazy.map(
department -> SupervisorService.getSupervisor(department)
);
Lazy<Lazy<Set<String>>> permissions = departmentLazy.map(department ->
supervisorLazy.map(supervisor -> getPermissions(department, supervisor))
);
Lazy<Long> param1Lazy = Lazy.of(() -> 2L);
Lazy<Long> param2Lazy = Lazy.of(() -> 2L);
Lazy<Long> param3Lazy = Lazy.of(() -> 2L);
Lazy<Lazy<Lazy<Long>>> result = param1Lazy.map(param1 ->
param2Lazy.map(param2 ->
param3Lazy.map(param3 -> param1 + param2 + param3)
)
);
public <S> Lazy<S> flatMap(Function super T, Lazy extends S>> function) {
return Lazy.of(() -> function.apply(get()).get());
}
Lazy<Set<String>> permissions = departmentLazy.flatMap(department ->
supervisorLazy.map(supervisor -> getPermissions(department, supervisor))
);
Lazy<Long> param1Lazy = Lazy.of(() -> 2L);
Lazy<Long> param2Lazy = Lazy.of(() -> 2L);
Lazy<Long> param3Lazy = Lazy.of(() -> 2L);
Lazy<Long> result = param1Lazy.flatMap(param1 ->
param2Lazy.flatMap(param2 ->
param3Lazy.map(param3 -> param1 + param2 + param3)
)
);
do
param1 <- param1Lazy
param2 <- param2Lazy
param3 <- param3Lazy
-- 注释: do 记法中 return 的含义和 Java 完全不一样
-- 它表示将值打包进盒子里,
-- 等价的 Java 写法是 Lazy.of(() -> param1 + param2 + param3)
return param1 + param2 + param3
public class Lazy<T> implements Supplier<T> {
private final Supplier<? extends T> supplier;
private T value;
private Lazy(Supplier<? extends T> supplier) {
this.supplier = supplier;
}
public static <T> Lazy<T> of(Supplier<? extends T> supplier) {
return new Lazy<>(supplier);
}
public T get() {
if (value == null) {
T newValue = supplier.get();
if (newValue == null) {
throw new IllegalStateException("Lazy value can not be null!");
}
value = newValue;
}
return value;
}
public <S> Lazy<S> map(Function<? super T, ? extends S> function) {
return Lazy.of(() -> function.apply(get()));
}
public <S> Lazy<S> flatMap(Function<? super T, Lazy<? extends S>> function) {
return Lazy.of(() -> function.apply(get()).get());
}
}
public class UserFactory {
// 部门服务, rpc 接口
private DepartmentService departmentService;
// 主管服务, rpc 接口
private SupervisorService supervisorService;
// 权限服务, rpc 接口
private PermissionService permissionService;
public User buildUser(long uid) {
Lazy<String> departmentLazy = Lazy.of(() -> departmentService.getDepartment(uid));
// 通过部门获得主管
// department -> supervisor
Lazy<Long> supervisorLazy = departmentLazy.map(
department -> SupervisorService.getSupervisor(department)
);
// 通过部门和主管获得权限
// department, supervisor -> permission
Lazy<Set<String>> permissionsLazy = departmentLazy.flatMap(department ->
supervisorLazy.map(
supervisor -> permissionService.getPermissions(department, supervisor)
)
);
User user = new User();
user.setUid(uid);
user.setDepartment(departmentLazy);
user.setSupervisor(supervisorLazy);
user.setPermissions(permissionsLazy);
}
}
// 注意,这里的 function 是装在 lazy 里面的
public <S> Lazy<S> apply(Lazy<Function<? super T, ? extends S>> function) {
return Lazy.of(() -> function.get().apply(get()));
}
-- 注释: 结果为 box c
box f <*> box a <*> box b
点击阅读原文查看详情!