java架構師筆記:Java中的轉換器設計模式

java閘瓦發表於2019-04-18

在這篇文章中,我們將討論 Java / J2EE專案中最常用的 Converter Design Pattern。由於Java8 功能不僅提供了相應型別之間的通用雙向轉換方式,而且還提供了轉換相同型別物件集合的常用方法,從而將樣板程式碼減少到絕對最小值。我們使用Java8 功能編寫了此模式的原始碼

目的

轉換器設計模式的目的是為相應型別之間的雙向轉換提供一種通用的方式,允許型別無需彼此瞭解的簡潔的實現。此外,轉換器設計模式引入了雙向收集對映,將樣板程式碼減少到最小。

原始碼

轉換器設計模式是一種行為設計模式,允許在相應型別(如DTO和邏輯同構型別的域表示)之間進行雙向轉換。此外,該模式還引入了一種在型別之間轉換物件集合的通用方法。

類圖

java架構師筆記:Java中的轉換器設計模式

讓我們根據上面的類圖編寫原始碼。

在本例中,我們將把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(資料傳輸物件)時,您可能需要將其轉換為域等效

相關文章