轉換器模式【其他模式】
阿新 • • 發佈:2018-12-28
轉換器模式
public class Converter { /** * 轉換器模式:允許兩種型別的物件進行雙向的裝換,適合於 domain、dto 之間的轉換 */ @Test public void all() { final UserConverter userConverter = UserConverter.get(); User user = new User("kristy", "[email protected]"); final UserDTO userDTO = userConverter.from(user); fieldEquals(user, userDTO); user = userConverter.to(userDTO); fieldEquals(user, userDTO); } private void fieldEquals(User user, UserDTO userDTO) { assertEquals(user.getName(), userDTO.getName()); assertEquals(user.getEmail(), userDTO.getIdentifier()); } } /** * 轉換器核心實現 * @param <F> 型別 F * @param <T> 型別 T */ abstract class AConverter<F, T> { private final Function<F, T> from; private final Function<T, F> to; /** * @param from * @param to */ public AConverter(Function<F, T> from, Function<T, F> to) { super(); this.from = from; this.to = to; } /** * 單個物件間的轉換 */ public T from(F f) { Objects.requireNonNull(f); return from.apply(f); } public F to(T t) { Objects.requireNonNull(t); return to.apply(t); } /** * 集合物件間的轉換 */ public Collection<T> fromCollection(Collection<F> fs) { Objects.requireNonNull(fs); return fs.stream().map(from).collect(Collectors.toList()); } public Collection<F> toCollection(Collection<T> fs) { Objects.requireNonNull(fs); return fs.stream().map(to).collect(Collectors.toList()); } } @Data class User { private final String name; private final String email; } @Data class UserDTO { private final String name; private final String identifier; } class UserConverter extends AConverter<User, UserDTO> { private static class Holder { private static UserConverter INSTANCE = new UserConverter(); } private UserConverter() { this(user -> { return new UserDTO(user.getName(), user.getEmail()); }, userDTO -> { return new User(userDTO.getName(), userDTO.getIdentifier()); }); } public static final UserConverter get() { return Holder.INSTANCE; } private UserConverter(Function<User, UserDTO> from, Function<UserDTO, User> to) { super(from, to); } }