Java中的转换器设计模式

19-04-10 jdon
         

在这篇文章中,我们将讨论 Java / J2EE项目中最常用的  Converter Design Pattern。由于Java8 功能不仅提供了相应类型之间的通用双向转换方式,而且还提供了转换相同类型对象集合的常用方法,从而将样板代码减少到绝对最小值。我们使用Java8 功能编写了此模式的源代码。

目的

转换器设计模式的目的是为相应类型之间的双向转换提供一种通用的方式,允许类型无需彼此了解的简洁的实现。此外,转换器设计模式引入了双向收集映射,将样板代码减少到最小。

源代码

转换器设计模式是一种行为设计模式,允许在相应类型(如DTO和逻辑同构类型的域表示)之间进行双向转换。此外,该模式还引入了一种在类型之间转换对象集合的通用方法。

类图

让我们根据上面的类图编写源代码。

在本例中,我们将把customerd转换为customer实体,反之亦然,我们还将在类型之间转换对象集合。

步骤1:让我们创建一个通用转换器。

public abstract class Converter < T, C > {

    private final Function < T,
    C > fromDto;
    private final Function < C,
    T > fromEntity;

    /**
     * @param fromDto
     *            Function that converts given dto entity into the domain
     *            entity.
     * @param fromEntity
     *            Function that converts given domain entity into the dto
     *            entity.
     */
    public Converter(final Function < T, C > fromDto, final Function < C, T > fromEntity) {
        this.fromDto = fromDto;
        this.fromEntity = fromEntity;
    }

    /**
     * @param customerDto
     *            DTO entity
     * @return The domain representation - the result of the converting function
     *         application on dto entity.
     */
    public final C convertFromDto(final T customerDto) {
        return fromDto.apply(customerDto);
    }

    /**
     * @param customer
     *            domain entity
     * @return The DTO representation - the result of the converting function
     *         application on domain entity.
     */
    public final T convertFromEntity(final C customer) {
        return fromEntity.apply(customer);
    }

    /**
     * @param dtoCustomers
     *            collection of DTO entities
     * @return List of domain representation of provided entities retrieved by
     *         mapping each of them with the conversion function
     */
    public final List < C > createFromDtos(final Collection < T > dtoCustomers) {
        return dtoCustomers.stream().map(this::convertFromDto).collect(Collectors.toList());
    }

    /**
     * @param customers
     *            collection of domain entities
     * @return List of domain representation of provided entities retrieved by
     *         mapping each of them with the conversion function
     */
    public final List < T > createFromEntities(final Collection < C > customers) {
        return customers.stream().map(this::convertFromEntity).collect(Collectors.toList());
    }

}

步骤2:让我们创建一个简单客户转换器的实现。

public class CustomerConverter extends Converter<CustomerDto, Customer> {

 public CustomerConverter() {
  super(customerDto -> new Customer(customerDto.getCustomerId(), customerDto.getCustomerName(),
    customerDto.getCustomerLastName(), customerDto.isStatus()),
    customer -> new CustomerDto(customer.getCustomerId(), customer.getCustomerName(),
      customer.getCustomerLastName(), customer.isStatus()));

 }

}

步骤3: 创建customerdto类。

public class CustomerDto {
    private String customerId;
    private String customerName;
    private String customerLastName;
    private boolean status;
    public CustomerDto(String customerId, String customerName, String customerLastName, boolean status) {
        super();
        this.customerId = customerId;
        this.customerName = customerName;
        this.customerLastName = customerLastName;
        this.status = status;
    }
    public String getCustomerId() {
        return customerId;
    }
    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerLastName() {
        return customerLastName;
    }
    public void setCustomerLastName(String customerLastName) {
        this.customerLastName = customerLastName;
    }
    public boolean isStatus() {
        return status;
    }
    public void setStatus(boolean status) {
        this.status = status;
    }

}

步骤4: 创建Customer实体类。

public class Customer {
    private String customerId;
    private String customerName;
    private String customerLastName;
    private boolean status;
    public Customer(String customerId, String customerName, String customerLastName, boolean status) {
        super();
        this.customerId = customerId;
        this.customerName = customerName;
        this.customerLastName = customerLastName;
        this.status = status;
    }
    public String getCustomerId() {
        return customerId;
    }
    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerLastName() {
        return customerLastName;
    }
    public void setCustomerLastName(String customerLastName) {
        this.customerLastName = customerLastName;
    }
    public boolean isStatus() {
        return status;
    }
    public void setStatus(boolean status) {
        this.status = status;
    }

}

步骤5:  现在,让我们通过创建Client类来测试这个模式。

public class Client {
    /**
     * Program entry point
     *
     * @param args command line args
     */
    public static void main(String[] args) {
        Converter < CustomerDto, Customer > CustomerConverter = new CustomerConverter();

        CustomerDto dtoCustomer = new CustomerDto("100", "Ramesh", "Fadatare", true);
        Customer Customer = CustomerConverter.convertFromDto(dtoCustomer);
        System.out.println("Entity converted from DTO:" + Customer);

        List < Customer > customers = new ArrayList < > ();
        customers.add(new Customer("100", "Ramesh1", "Fadatare", true));
        customers.add(new Customer("200", "Ramesh2", "Fadatare", true));
        customers.add(new Customer("300", "Ramesh3", "Fadatare", true));

        customers.forEach(System.out::println);

        customers.forEach((customer) - > System.out.println(customer.getCustomerId()));

        System.out.println("DTO entities converted from domain:");
        List < CustomerDto > dtoEntities = CustomerConverter.createFromEntities(customers);
        dtoEntities.forEach(System.out::println);
        dtoEntities.forEach((customer) - > System.out.println(customer.getCustomerId()));

    }
}

输出:

Entity converted from DTO:com.ramesh.j2ee.converter.Customer@87aac27
com.ramesh.j2ee.converter.Customer@1b28cdfa
com.ramesh.j2ee.converter.Customer@eed1f14
com.ramesh.j2ee.converter.Customer@7229724f
100
200
300
DTO entities converted from domain:
com.ramesh.j2ee.converter.CustomerDto@4dd8dc3
com.ramesh.j2ee.converter.CustomerDto@6d03e736
com.ramesh.j2ee.converter.CustomerDto@568db2f2
100
200
300

适用性

在以下情况下 使用转换器模式

  • 当您拥有逻辑上与其他类型相对应的类型时,您需要在它们之间转换实体
  • 如果要根据上下文提供不同类型的转换方式
  • 每当您引入DTO(数据传输对象)时,您可能需要将其转换为域等效。