Patrones de diseño: patrones de adaptador aplicados en Java

prefacio

        Creo que todo el mundo a menudo se encuentra con este tipo de demanda. Para promover rápidamente un determinado negocio, el gerente de producto necesita conectarse en línea con urgencia. La idea general de desarrollo y recepción es así. Primero implemente esta función, que Parece que no hay problema, pero luego Con el desarrollo del negocio y el aumento de usuarios, diferentes productos presentarán varios requisitos nuevos en el futuro, por lo que habrá un problema de que todos modifican la lógica del código en el mismo lugar, y el El código se convertirá en una gran montaña con el tiempo. La persona que se hizo cargo se quejó.

        El patrón de adaptador es uno de los patrones de diseño de GoF23, citando las palabras originales de Du Niang: el patrón de adaptador (a veces también llamado estilo de empaque o empaque) adapta la interfaz de una clase a lo que espera el usuario. Un adaptador permite que clases que normalmente no funcionarían juntas debido a interfaces incompatibles trabajen juntas envolviendo la propia interfaz de la clase en una clase existente. fuente:

Patrón de adaptador_Enciclopedia de Baidu En programación informática, el patrón de adaptador (a veces también llamado estilo de empaquetado o empaquetado) adapta la interfaz de una clase a lo que espera el usuario. Un adaptador permite que clases que normalmente no funcionarían juntas debido a interfaces incompatibles trabajen juntas envolviendo la propia interfaz de la clase en una clase existente. https://baike.baidu.com/item/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F/10218946

Escenarios prácticos de aplicación

Patrón de diseño no utilizado:

        Un producto en un determinado escenario comercial requiere que el procesamiento de la lógica de pago en línea esté conectado a JD Payment.Después de que Zhang San recibió la solicitud, el producto exigió estar en línea en dos días (el corazón de investigación y desarrollo está roto), pero afortunadamente, la lógica es relativamente simple en general.Zhang San La siguiente lógica se completa rápidamente, y la lógica del código es la siguiente.

public class PayHandle {

	public boolean pay(String payType,String orderId) {
		
		//京东支付
		if("1".equals(payType)) {
			//具体的业务处理逻辑
			return jdPay(orderId);
		}
		
		return Boolean.FALSE;
	}
	
	public boolean jdPay(String orderId) {
		return Boolean.TRUE;
	}
}

        El proyecto se lanzó muy rápidamente. Después de un mes, el gerente de producto dijo que el desarrollo comercial es relativamente bueno y que el negocio requiere un nuevo método de pago. Li Si echó un vistazo después de recibir la demanda. ¿No es esto solo agregar un juicio? y un metodo??? La nueva versión 2.0 ya está aquí

public class PayHandle {

	public boolean pay(String payType,String orderId) {
		
		//京东支付
		if("1".equals(payType)) {
			//具体的业务处理逻辑
			return jdPay(orderId);
		}
		//支付保
		else if("2".equals(payType)) {
			return aliPay(orderId);
		}
		
		return Boolean.FALSE;
	}
	
	public boolean jdPay(String orderId) {
		return Boolean.TRUE;
	}
	public boolean aliPay(String orderId) {
		return Boolean.TRUE;
	}
}

        Después de que el proyecto ha sido iterado a través de N versiones, hay un problema. Todos escriben más y más lógica comercial en él, y finalmente hay un accidente de producción después de la modificación. Se cree que hay problemas similares en otros negocios en muchos negocios. escenarios El problema, la razón principal es que la iteración del proyecto es demasiado rápida y no hay un buen diseño.

Utilice un patrón de diseño:

        Entonces algunos de ustedes no podrían quedarse quietos, pensando que el patrón de diseño es útil, no hay que acumular código, de hecho, no es cierto, cualquiera que haya leído los seis principios de los patrones de diseño lo entiende, si Si no entiende los seis principios de los patrones de diseño, primero puede pasar a familiarizarse con el concepto de patrones de diseño:

Patrón de diseño de software_Enciclopedia Baidu El patrón de diseño de software (Patrón de diseño), también conocido como patrón de diseño, es un resumen de la experiencia de diseño de código que se usa repetidamente, conocido por la mayoría de las personas, clasificado y catalogado. Los patrones de diseño se utilizan para el código reutilizable, para hacer que el código sea más fácil de entender para otros, para garantizar la confiabilidad del código y la reutilización del programa. https://baike.baidu.com/item/%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/2117635 ?fromModule=resultado-de-búsqueda_lemma#5

versión optimizada de código

Aquí se utiliza el conocido framework Spring.

Interfaz de pago unificado:

public interface PayHandleService {
	/**
	* @Title: pay 
	* @Description: 支付方法
	* @param payType 支付类型(可使用支付系统统一封装为对应枚举提供大家使用)
	* @param orderId 支付订单号
	* @version V1.0
	 */
	public boolean pay(String payType,String orderId);
}

Clase de implementación de interfaz de pago Jingdong

@Service
public class JdPayHandleServiceImpl implements PayHandleService {
	
	/**获取支付方式*/
	@Override
	public String getPayType() {
		return "1";
	}
	
	/**
	 * 京东支付处理方法
	 */
	@Override
	public boolean pay(String payType, String orderId) {
		//具体处理业务逻辑
		return false;
	}

}

Realización de la interfaz de pago de garantía de pago

@Service
public class AliPayHandleServiceImpl implements PayHandleService {
	
	/**获取支付方式*/
	@Override
	public String getPayType() {
		return "2";
	}
	
	/**支付类型*/
	@Override
	public boolean pay(String payType, String orderId) {
		//处理具体逻辑
		return false;
	}

}

Implementar clases de procesamiento mediante inyección Autowired

@Service
public class PayHandle{
	
	@Autowired
	private Map<String, PayHandleService> payHandleServiceMap;
	
	public boolean pay(String payType,String orderId) {
		for (Entry<String, PayHandleService> entry:payHandleServiceMap.entrySet()) {
			PayHandleService payHandleService = entry.getValue();
			if(payType.equals(payHandleService.getPayType())) {
				return payHandleService.pay(payType, orderId);
			}
		}
		return Boolean.FALSE;
	}

}

Utilice el procesamiento de inyección de devolución de llamada de ApplicationContextAware

@Service
public class PayHandle implements ApplicationContextAware{
	
	private Map<String, PayHandleService> payHandleServiceMap;
	
	public boolean pay(String payType,String orderId) {
		for (Entry<String, PayHandleService> entry:payHandleServiceMap.entrySet()) {
			PayHandleService payHandleService = entry.getValue();
			if(payType.equals(payHandleService.getPayType())) {
				return payHandleService.pay(payType, orderId);
			}
		}
		return Boolean.FALSE;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		payHandleServiceMap = applicationContext.getBeansOfType(PayHandleService.class);
	}
	
}

Esta implementación no parece ser muy elegante. Todos encuentran que no importa si usa la inyección Autowired o la inyección de devolución de llamada ApplicationContextAware, finalmente obtendrá un mapa. La clave de este mapa es en realidad el nombre de la clase de implementación específica. Todos sabemos que si la clase de implementación predeterminada de Spring no es Si especifica la identificación, solo la primera letra del nombre del bean actual está en minúscula, por lo que realmente puede hacer esto.

Nueva enumeración optimizada

public enum PayTypeMapping {
	JD_PAY("1","jdPayHandleServiceImpl","京东支付"),
	ALI_PAY("2","aliPayHandleServiceImpl","支付保支付"),
	;
	
	/**支付类型*/
	private String payType;
	/**支付类型实现类名称*/
    private String payHandleName;
    /**描述*/
    private String desc;
	
	public String getPayType() {
		return payType;
	}

	public String getPayHandleName() {
		return payHandleName;
	}

	public String getDesc() {
		return desc;
	}

	private PayTypeMapping(String payType, String payHandleName, String desc) {
		this.payType = payType;
		this.payHandleName = payHandleName;
		this.desc = desc;
	}



	private static final Map<String, PayTypeMapping> CODE_MAP = EnumSet.allOf(PayTypeMapping.class).stream().collect(Collectors.toMap(PayTypeMapping::getPayType, a -> a, (k1, k2) -> k1));
	
	/**根据支付类型获取支付实现类相关信息*/
    public static PayTypeMapping of(String code) {
        return StringUtils.isNotBlank(code)? CODE_MAP.get(code) : null;
    }
}

Lógica de llamada final optimizada

@Service
public class PayHandle{
	
	@Autowired
	private Map<String, PayHandleService> payHandleServiceMap;
	
	public boolean pay(String payType,String orderId) {
		PayTypeMapping payTypeMapping = PayTypeMapping.of(payType);
		if(Objects.nonNull(payTypeMapping)) {
			PayHandleService payHandleService = payHandleServiceMap.get(payTypeMapping.getPayHandleName());
			return payHandleService.pay(payType, orderId);
		}
		return Boolean.FALSE;
	}

}

epílogo

        La optimización final tiene seguimiento. No importa qué tipo se agregue, se modificará por separado y no afectará a otra lógica comercial. Este artículo solo enumera un comportamiento de pago. De hecho, hay muchos escenarios comerciales prácticos que también pueden usar adaptadores. para resolver el código inflado. Además de la mantenibilidad, todavía quiero recordarles a todos que el patrón de diseño no es aplicable a ninguna escena. Recuerde no agregar el patrón de diseño al proyecto real sin rodeos, lo que en realidad conducirá al efecto contrario; No importa cuán alto sea, el objetivo final es garantizar la mantenibilidad y la escalabilidad del proyecto; también espero que después de leer este artículo, tenga una nueva comprensión de sus reservas de conocimiento.

Supongo que te gusta

Origin blog.csdn.net/m0_37506254/article/details/127038976
Recomendado
Clasificación