1. 程式人生 > >轉換器模式【其他模式】

轉換器模式【其他模式】

轉換器模式

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);
    }
}