1. Introducción al negocio de lanzamiento de nuevos productos.
Listado de productos significa colocar un nuevo producto en la plataforma Dewu. Un proceso completo de listado de productos comienza con el envío de solicitudes de nuevos productos desde varias fuentes y canales. Debe pasar por múltiples rondas de revisión por parte de diferentes roles, que incluyen principalmente:
-
Revisión de selección de productos: determinar si cumple con los requisitos de estantería en función de la información presentada en la solicitud de nuevo producto;
-
Revisión de datos del producto: revisión de los datos del producto para verificar su precisión e integridad, incluidas múltiples rondas de gestión comercial, control de riesgos y revisión legal;
-
Revisión de la investigación empresarial: la revisión de la investigación empresarial es un juicio sobre la capacidad del producto para identificarse y soportarse en la plataforma, que también es una característica del negocio de Dewu.
En estas rondas de revisión, la revisión de selección de productos y la revisión de investigación comercial pertenecen al proceso de muestreo de nuevos productos. Solo aparecen en la revisión de datos del producto para determinar si el producto se puede vender. pertenece al proceso de procesamiento de datos del producto, determina si la información actual del producto cumple con los requisitos para su visualización en el lado C.
Por lo tanto, en la implementación del sistema, el flujo de estado del proceso de muestra de entrada de nuevo producto y el proceso de procesamiento de datos del producto deben estar involucrados. El primero involucra la tabla de muestra de entrada de nuevo producto, y el segundo es principalmente la tabla principal de SPU del producto. Centrándose en el flujo y la máquina de estado del proceso de muestra entrante del nuevo producto, el atributo del canal de origen del proceso de muestreo del nuevo producto es muy obvio y existen diferencias grandes o pequeñas en la lógica comercial y los procesos de los diferentes canales.
2. ¿Por qué considerar acceder a una máquina de estados?
-
Hay una gran cantidad de valores de enumeración de estado y las condiciones para su transferencia no están claras. Para comprender el proceso comercial, es necesario estudiar el código detenidamente y el costo de comenzar y mantenerlo es alto.
-
La transferencia de estados está especificada de manera completamente arbitraria en el código, y existen riesgos en la transferencia arbitraria entre estados.
-
Algunas transferencias de estado no respaldan la idempotencia y las operaciones repetidas pueden causar consecuencias inesperadas.
-
El costo y el riesgo de transferir estados nuevos y modificados son altos, el alcance de las modificaciones del código es incontrolable y las pruebas requieren una regresión de todo el proceso.
3. Estado involucrado en el proceso de lanzamiento de nuevos productos.
Enumeración del estado de la muestra del nuevo producto
El campo de estado correspondiente a la tabla de muestra del nuevo producto contiene los siguientes valores de enumeración (moderadamente simplificados para facilitar la explicación):
public enum NewProductShowEnum {
DRAFT(0, "草稿"),
CHECKING(1, "选品中"),
UNPUT_ON_SALE_UNPASS(2, "选品不通过"),
UNPUT_ON_SALE_PASSED(3, "商研审核中"),
UNPUT_ON_SALE_PASSED_UNSEND(4, "商品资料待审核"),
UNPUT_ON_SALE_PASSED_UNSEND_NOT_PUT(5, "鉴别不通过"),
UNPUT_ON_SALE_PASSED_SEND(6, "请寄样"),
SEND_PRODUCT(7, "商品已寄样"),
SEND_PASS(8, "寄样鉴别通过"),
SEND_REJECT(9, "寄样鉴别不通过"),
GONDOR_INVALID(10, "作废"),
FINSH_SPU(11, "新品资料审核通过"),
}
Enumeración del estado de SPU
El campo de estado correspondiente a la tabla principal de SPU del producto contiene los siguientes valores de enumeración (moderadamente simplificados para facilitar la explicación):
public enum SpuStatusEnum {
OFF_SHELF(0, "下架"),
ON_SHELF(1, "上架"),
TO_APPROVE(2, "待审核"),
APPROVED(3, "审核通过"),
REJECT(4, "审核不通过"),
TO_RISK_APPROVE(8, "待风控审核"),
TO_LEGAL_APPROVE(9, "待法务审核"),
}
La parte de transferencia de estado de la SPU involucrada en el proceso comercial de lanzamiento de un nuevo producto está sujeta a la transferencia de estado del producto. La transferencia de estado del producto también está conectada a la máquina de estado (pero no es el contenido que se analiza en este artículo). El artículo discutirá principalmente el estado de la tabla de muestra del nuevo producto.
4. Todos los eventos relacionados con muestras de nuevos productos.
-
Guardar borrador de nuevo producto
-
Enviar solicitud de nuevo producto
-
Selección de producto aprobada
-
La selección del producto falló
-
Volver a enviar después de que se rechace la selección de productos
-
Iniciar una revisión de la investigación empresarial.
-
Identificación de soporte de revisión de investigación empresarial
-
No se admite la identificación de revisiones de investigación empresarial
-
Revisión de investigación empresarial: la información del producto es incorrecta
-
Revisión de SPU rechazada por más de X días
-
Iniciar el envío de muestras
-
Actualización del progreso de la entrega de muestra
12 en total.
5. Transferencia de estado de muestra de nuevo producto
Como se mencionó anteriormente, diferentes canales de origen de productos tienen diferentes procesos de lanzamiento de nuevos productos, lo que significa que el flujo de estado de diferentes canales también es diferente. La siguiente es una ilustración de los canales de vendedores del lado B:
En la figura, el cuadro naranja representa el estado de las muestras entrantes de nuevos productos, el cuadro verde representa el estado de la SPU, el cuadro redondeado azul representa el evento que desencadena el cambio de estado y los lugares conectados por flechas representan el flujo desde el estado actual. al siguiente estado.
Tenga en cuenta que cuando se activan ciertos eventos, el estado objetivo al que se debe transferir no es fijo. Se requieren una serie de juicios lógicos para determinar el estado objetivo al que eventualmente fluirá el evento.
6. Selección de tecnología de máquina de estados.
Elija Spring StateMachine como marco de la máquina de estado real para procesos y detalles específicos, consulte este artículo https://mp.weixin.qq.com/s/TqXMtS44D4w6d1-KLxcoiQ . Este artículo no entrará en detalles.
7. Dificultades que enfrenta el acceso a la máquina de estados
En la actualidad, el código para muestras de nuevos productos todavía enfrenta el problema del acoplamiento de código entre diferentes canales, que debe resolverse juntos en este acceso, de lo contrario, el costo del acceso a la máquina de estado será muy alto y la calidad será difícil de garantizar. , y el mantenimiento posterior será más difícil. Incluso si las modificaciones de la máquina de estado mencionadas anteriormente se realizan en condiciones ideales, sin otras modificaciones, todavía habrá dos problemas:
-
Acoplamiento de la lógica de juicio del estado objetivo;
-
El acoplamiento que realmente realiza la acción.
Se puede entender simplemente que existe una interfaz muy grande en la implementación de la guardia de la máquina de estado (para determinar si se cumplen los requisitos previos para la ejecución) y la acción (la ejecución real de la acción), que contiene diferentes métodos para determinar el objetivo. estado y ejecutando diferentes acciones entre todos los canales, es muy difícil leer para entender qué hace un determinado canal específicamente.
El problema se concentra en el código de la interfaz de revisión de selección de productos y revisión de investigación comercial para muestras entrantes de nuevos productos (esta parte también es la parte con la lógica comercial más y más compleja para las muestras entrantes de nuevos productos. Se mezcla con todas las). La lógica de aprobación y falla, la selección de productos y la lógica de la investigación empresarial están mezcladas. El código es largo y no se puede leer. También hay problemas con transacciones grandes (varias llamadas RPC en la transacción). mientras la máquina de estados está conectada y se fusiona, incluyendo específicamente:
-
Los códigos para diferentes canales se dividen usando el modo estrategia;
-
Los diferentes estados y la lógica de procesamiento de eventos de operación se resumen en las clases de protección y acción de diferentes estados y eventos de la máquina de estados;
-
La misma lógica de procesamiento de código en diferentes canales se encapsula en módulos de código individuales y se llama en cada canal.
El método de transformación general se muestra en la siguiente figura:
8. Ingresos esperados
Como se puede entender de lo anterior, aunque es un acceso a la máquina de estado, en realidad necesita completar dos aspectos de la transformación. Uno es completar el desacoplamiento del código comercial dividido en canales y operaciones en todo el nuevo proceso. la transformación, pudieron:
-
Resolver problemas de transacciones importantes en el enlace anterior de solicitud de nuevos productos, tales como: envío de registro y revisión de nuevos productos;
-
El aislamiento empresarial entre los canales de origen del producto hace que el alcance de los cambios de código sea más controlable y más propicio para las pruebas;
-
Mejore la escalabilidad del código, reduzca el umbral de comprensión del código y mejore la eficiencia del desarrollo iterativo para las necesidades diarias.
El segundo es el acceso a la máquina de estados, que puede resolver el problema del flujo de estados en el proceso de muestreo de nuevos productos, que incluye:
-
Gestión unificada y centralizada de reglas de cambio de estado para facilitar el aprendizaje y posterior mantenimiento;
-
Evitar transferencias de estatus ilegales y repetidas;
-
Se vuelve más fácil ajustar el orden entre nuevos estados y procesos estatales, y las modificaciones del código son más controlables.
9. Diseño detallado
El fundamento de la división por canal
Iniciar muestras de nuevos productos desde diferentes canales de origen de productos es un proceso en el que diferentes roles envían nuevos productos a través de diferentes terminales. La combinación de roles y terminales es fija y no se pueden combinar a voluntad. Una característica comercial común, solo cuando se determinan roles específicos se puede determinar un proceso comercial completo.
La capacidad de solicitar nuevos productos en cada canal también es diferente. Por ejemplo, los comerciantes tienen la comprensión más completa de la información del producto, por lo que pueden completar la información completa del producto al solicitar nuevos productos, y hay más procesos comerciales que otros. En comparación, solo se puede completar una pequeña cantidad de información del producto en el lado de la aplicación. Una vez que se rechaza la solicitud, no se puede modificar ni enviar. Por lo tanto, las diferencias entre los diferentes canales son naturales y pueden seguir existiendo sujetas a los propios canales.
Por tanto, es razonable y necesario dividir según canales en determinadas operaciones.
Las operaciones comerciales están desacopladas por canal.
Interfaz común para operaciones comerciales.
Los registros únicos de muchos nodos importantes en muestras de nuevos productos (las operaciones por lotes también se convertirán en procesamiento único) las operaciones comerciales (como el envío de solicitudes de nuevos productos, la revisión de la selección de productos y la revisión de la investigación comercial) se pueden resumir en " preprocesamiento de solicitudes -> verificación de operaciones". "-> Ejecutar lógica empresarial -> Operaciones de persistencia -> Acciones de posprocesamiento relacionadas ", por lo que se diseña una clase de interfaz común para llevar a cabo el proceso de ejecución de diferentes operaciones comerciales para nuevos productos y muestras de diferentes canales:
public interface NspOperate<C> {
/**
* 支持的商品来源渠道
* @return
*/
Integer supportApplyType();
/**
* 支持的操作类型
* @return
*/
String operateCode();
/**
* 请求预处理
* @param context
*/
void preProcessRequest(C context);
/**
* 校验
* @param context
*/
void verify(C context);
/**
* 执行业务逻辑
* @param context
*/
void process(C context);
/**
* 执行持久化
* @param context
*/
void persistent(C context);
/**
* 后处理
* @param context
*/
void post(C context);
}
Algunas notas:
-
Cada evento de la máquina de estados posterior corresponde al tipo de operación de la interfaz uno a uno. Además, también se pueden definir otros tipos de operaciones para escenarios que no implican transferencia de estado (por ejemplo: editar aplicaciones de nuevos productos, crear SPU basadas en aplicaciones de nuevos productos).
-
La definición del método de proceso es relativamente amplia. En diferentes operaciones comerciales, el contenido de ejecución real puede ser muy diferente. Por ejemplo, al enviar una revisión de un nuevo producto, solo puede realizar algunas acciones de recopilación de datos, mientras que en una revisión de investigación comercial. es necesario analizar los objetivos después de esta operación. Juicio de estado. Por lo tanto, las subclases pueden dividirse aún más y definir nuevos métodos que se implementarán en función de sus propias necesidades comerciales.
-
El método de persistencia persistente se define por separado para admitir la adición de transacciones solo a este método. El código del sistema actual en realidad tiene un diseño similar, pero la transacción es demasiado amplia e incluye todo el proceso de ejecución, como la verificación y el procesamiento comercial. llamadas, que también es una de las razones importantes para las grandes transacciones. Por lo tanto, aquí está claro que la implementación de este método solo lee y escribe operaciones de base de datos y no contiene ninguna lógica empresarial.
-
Cada implementación de esta interfaz utiliza "canal de origen del producto + tipo de operación" para formar una clave única para la gestión de Spring Bean. Al mismo tiempo, para tener en cuenta que algunas operaciones no distinguen el origen del producto, se permite definir. un applyType especial (como -1) para representar la implementación actual admite todos los canales. Al obtener la implementación, optimice para obtener la implementación del canal actual. Si no se encuentra, intente encontrar la implementación de todos los canales:
public NspOperate getNspOperate(Integer applyType, String operateCode) {
String key = buildKey(applyType, operateCode);
NspOperate nspOperate = operateMap.get(key);
if (Objects.isNull(nspOperate)) {
String generalKey = buildKey(-1, operateCode);
nspOperate = operateMap.get(generalKey);
}
AssertUtils.throwIf(Objects.isNull(nspOperate), "NspOperate not found! key = " + key);
return nspOperate;
}
Clase de implementación de operaciones comerciales
Según el escenario empresarial actual, para facilitar la reutilización de algunos códigos, la implementación de operaciones comerciales tiene hasta tres niveles de relaciones de herencia:
-
El primer nivel: Dimensiones para agregar tipos de operaciones (eventos comerciales), como la revisión de la investigación empresarial, donde puede definir códigos comunes y métodos personalizados en la revisión de la investigación empresarial, como: verificación general de parámetros de entrada para la revisión de la investigación empresarial, los campos no están vacíos y similares.
-
Segundo nivel: específico de la dimensión del tipo de operación (eventos comerciales), como revisión de investigación comercial: admite identificación, revisión de investigación comercial: no admite identificación, etc. Aquí puede definir los códigos comunes de todos los canales de origen de productos bajo el tipo de operación. dimensión. Por ejemplo: cuando no se admite la identificación, se requiere el motivo y la revisión de la investigación empresarial requiere una serie de lógica de juicio de múltiples sistemas.
-
La tercera capa: implementación específica a nivel del canal de origen del producto, puede reutilizar el código en la clase principal.
No todas las operaciones comerciales requieren estas tres capas de implementación. En el uso real, ocurrirán tres situaciones, como:
-
Solo hay una capa: las muestras de nuevos productos se invalidan, independientemente del canal de origen del producto. Todos los canales utilizan la misma lógica y solo una clase de implementación es suficiente.
-
Solo hay dos niveles: enviar una solicitud de nuevo producto y distinguir entre diferentes canales de origen de productos.
-
Hay tres niveles: revisión de investigación comercial de nuevos productos La revisión de investigación comercial también se divide en múltiples tipos de operaciones (eventos comerciales), como: revisión de investigación comercial: admite identificación, revisión de investigación comercial: no admite identificación, revisión de investigación comercial: inicia. envío de muestras, etc., cada canal de origen de productos básicos tiene su propia implementación para cada tipo de operación.
Acceso a la máquina de estado
Definición de máquina de estados
A juzgar por el diagrama de flujo de estado anterior, el flujo de estado de nuevos productos y muestras es relativamente claro, pero de hecho habrá algunas diferencias menores en el proceso de estado de cada canal. Para evitar una división incompleta de los canales de origen, se deben realizar consideraciones integrales. También se toma en cuenta que el costo de la configuración de la máquina de estados no es alto, por lo que se decide que cada canal cree su propia configuración de máquina de estados.
Tomando el canal del lado C como ejemplo, la configuración de la máquina de estados es la siguiente:
@Configuration
@Slf4j
@EnableStateMachineFactory(name = "newSpuApplyStateMachineFactory")
public class NewSpuApplyStateMachineConfig extends EnumStateMachineConfigurerAdapter<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> {
public final static String DEFAULT_MACHINEID = "spring/machine/commodity/newspuapply";
@Resource
private NewSpuApplyStateMachinePersist newSpuApplyStateMachinePersist;
@Resource
private NspNewApplyAction nspNewApplyAction;
@Resource
private NspNewApplyGuard nspNewApplyGuard;
@Bean
public StateMachinePersister<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum, NewSpuApplySendEventContext> newSpuApplyMachinePersister() {
return new DefaultStateMachinePersister<>(newSpuApplyStateMachinePersist);
}
@Override
public void configure(StateMachineConfigurationConfigurer<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> config) throws Exception {
config.withConfiguration().machineId(DEFAULT_MACHINEID);
}
@Override
public void configure(StateMachineStateConfigurer<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> config) throws Exception {
config.withStates()
.initial(NewProductShowEnum.STM_INITIAL)
.state(NewProductShowEnum.CHECKING)
.state(NewProductShowEnum.UNPUT_ON_SALE_UNPASS)
.state(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND)
.state(NewProductShowEnum.UNPUT_ON_SALE_PASSED)
.choice(NewProductShowEnum.STM_UNPUT_ON_SALE_PASSED_UNSEND)
.choice(NewProductShowEnum.STM_UNPUT_ON_SALE_PASSED)
.state(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND_NOT_PUT)
.state(NewProductShowEnum.OTHER_UNPASS_FOR_SPU_STUDYER)
.state(NewProductShowEnum.FINSH_SPU)
.state(NewProductShowEnum.GONDOR_INVALID)
.states(EnumSet.allOf(NewProductShowEnum.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> transitions) throws Exception {
transitions.withExternal()
//提交新的新品申请
.source(NewProductShowEnum.STM_INITIAL)
.target(NewProductShowEnum.CHECKING)
.event(NewSpuApplyStateMachineEventsEnum.NEW_APPLY)
.guard(nspNewApplyGuard)
.action(nspNewApplyAction)
//选品不通过
.and().withExternal()
.source(NewProductShowEnum.CHECKING)
.target(NewProductShowEnum.UNPUT_ON_SALE_UNPASS)
.event(NewSpuApplyStateMachineEventsEnum.OM_PICK_REJECT)
.guard(nspOmRejectGuard)
.action(nspOmRejectAction)
//选品通过
.and().withExternal()
.source(NewProductShowEnum.CHECKING)
.target(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND)
.event(NewSpuApplyStateMachineEventsEnum.OM_PICK_PASS)
.guard(nspOmPassGuard)
.action(nspOmPassAction)
//发起商研审核
.and().withExternal()
.source(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND)
.target(NewProductShowEnum.STM_UNPUT_ON_SALE_PASSED_UNSEND)
.event(NewSpuApplyStateMachineEventsEnum.START_BR_AUDIT)
.and().withChoice()
.source(NewProductShowEnum.STM_UNPUT_ON_SALE_PASSED_UNSEND)
.first(NewProductShowEnum.UNPUT_ON_SALE_PASSED, nspStartBrAuditWaitAuditStatusDecide, nspStartBrAuditWaitAuditChoiceAction)
.then(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND_NOT_PUT, nspStartBrAuditRejctStatusDecide, nspStartBrAuditRejctChoiceAction)
.last(NewProductShowEnum.FINSH_SPU, nspStartBrAuditFinishChoiceAction)
//商研审核-支持鉴别
.and().withExternal()
.source(NewProductShowEnum.UNPUT_ON_SALE_PASSED)
.target(NewProductShowEnum.FINSH_SPU)
.event(NewSpuApplyStateMachineEventsEnum.BR_HUMAN_AUDIT_SUPPORT_ALL)
.guard(nspBrAuditSupportAllGuard)
.action(nspBrAuditSupportAllAction)
//商研审核-商品信息有误
.and().withExternal()
.source(NewProductShowEnum.UNPUT_ON_SALE_PASSED)
.target(NewProductShowEnum.OTHER_UNPASS_FOR_SPU_STUDYER)
.event(NewSpuApplyStateMachineEventsEnum.BR_HUMAN_AUDIT_WRONG_INFO)
.guard(nspBrAuditWrongInfoGuard)
.action(nspBrAuditWrongInfoAction)
//商研审核-不支持鉴别
.and().withExternal()
.source(NewProductShowEnum.UNPUT_ON_SALE_PASSED)
.target(NewProductShowEnum.UNPUT_ON_SALE_PASSED_UNSEND_NOT_PUT)
.event(NewSpuApplyStateMachineEventsEnum.BR_HUMAN_AUDIT_SUPPORT_NONE)
.guard(nspBrAuditRejectGuard)
.action(nspBrAuditRejectAction)
;
}
}
El estado de la máquina de estado se asigna completamente con el campo de estado en la tabla de base de datos de muestra del nuevo producto, y los eventos de la máquina de estado coinciden completamente con los eventos en la figura anterior. En las muestras de nuevos productos, hay algunos escenarios que requieren una serie de juicios lógicos para llegar al estado objetivo después de recibir un evento. Aquí, el estado de elección de la máquina de estados se utilizará para completar el juicio y la transferencia del estado objetivo. .
Aclaremos qué elementos relacionados con la máquina de estados se separan de forma independiente y cuáles se comparten:
Se puede ver que solo la clase de configuración de la máquina de estados es diferente para cada canal, por lo que el costo no es alto. A continuación se explicará cómo todos los canales comparten las clases de implementación de acción y guardia.
Implementación de Guardia y Acción.
Como puede verse en la configuración específica de la máquina de estados anterior, hay dos tipos de flujos de estado involucrados en el proceso de muestreo de nuevos productos:
-
El estado objetivo después de desencadenar el evento se fija. Por ejemplo, si el evento de error en la selección de productos se activa durante la revisión de selección de productos, el estado objetivo de la nueva solicitud de producto se determinará como error en la selección de productos;
-
El estado objetivo después de desencadenar el evento debe juzgarse mediante la lógica del código. Por esta razón, el estado de elección se introduce en la configuración de la máquina de estados. Por ejemplo, en el caso de iniciar una revisión de investigación comercial, el estado objetivo de un nuevo producto. La aplicación puede ser que la identificación no sea compatible directamente, o la aplicación del nuevo producto puede aprobarse directamente, o también puede requerir una revisión manual.
En el diseño de la máquina de estados Spring, las responsabilidades de estos dos tipos de flujos de estados, gurad y acción, serán diferentes:
Por tanto, la lógica de implementación de estos dos tipos de guardia y acción será diferente.
Sin embargo, para la protección y la acción bajo el mismo evento/estado de elección, se pueden compartir diferentes canales de origen del producto, porque se ha implementado el código comercial dividido según el canal de origen del producto y solo es necesario enrutarlo al NspOperate específico en el implementación La clase de implementación empresarial es suficiente. A continuación se dan ejemplos:
Guardia con estado objetivo fijo:
@Component
public class NspNewApplyGuard extends AbstractGuard<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum, NewSpuApplySendEventContext> {
@Resource
private NewSpuApplyOperateHelper newSpuApplyOperateHelper;
@Override
protected boolean process(StateContext<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> context) {
final CatetorySendEventContextRequest<NewSpuApplyContext> request = getSendEventContext(context).getRequest();
NewSpuApplyContext ctx = request.getParams();
Integer applyType = ctx.getApplyType(); //从业务数据中取出商品来源
NspOperate<NewSpuApplyContext> nspOperate = newSpuApplyOperateHelper.getNspOperate(applyType, NewSpuApplyStateMachineEventsEnum.NEW_APPLY.getCode()); //固定的事件code
//做请求的预处理
nspOperate.preProcessRequest(ctx);
//对业务数据做校验,校验不通过即抛出异常
nspOperate.verify(ctx);
//正常执行完上述2个方法,代表是可以执行的
return Boolean.TRUE;
}
}
En guardia, solo necesita obtener la clase de implementación NspOperate basada en el código fuente del producto y el código de evento fijo, y llamar a los métodos preProcessRequest y verificar de NspOperate para completar la verificación.
Acción con estado objetivo fijo:
@Component
public class NspNewApplyAction extends AbstractSuccessAction<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum, CategorySendEventContext> {
@Resource
private NewSpuApplyOperateHelper newSpuApplyOperateHelper;
@Override
protected void process(StateContext<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> context) {
final CatetorySendEventContextRequest<NewSpuApplyContext> request = getSendEventContext(context).getRequest();
NewSpuApplyContext ctx = request.getParams();
Integer applyType = ctx.getApplyType(); //从业务数据中取出商品来源
NspOperate<NewSpuApplyContext> nspOperate = newSpuApplyOperateHelper.getNspOperate(applyType, NewSpuApplyStateMachineEventsEnum.NEW_APPLY.getCode()); //固定的事件code
//执行业务逻辑
nspOperate.process(ctx);
//持久化
nspOperate.persistent(ctx);
//后处理
nspOperate.post(ctx);
}
}
En la acción, la clase de implementación NspOperate también se obtiene en función del código fuente del producto y del evento fijo, y se llama a los últimos métodos de NspOperate para completar la operación comercial.
Guardia en estado de Elección:
Guard necesita determinar el estado del objetivo en función de los canales y eventos actuales. Aquí, se abstrae una interfaz separada para que guard implemente llamadas. Si se necesita una lógica similar en NspOperate, también se puede hacer referencia a esta interfaz separada, por lo que no habrá código. duplicación:
public interface NspStatusDecider<C, R> {
/**
* 支持的商品来源渠道
* @return
*/
Integer supportApplyType();
/**
* 支持的操作类型
* @return
*/
String operateCode();
/**
* 判定目标状态
* @param context
*/
R decideStatus(C context);
}
@Component
public class NspBrAuditNoIdentifyGuard extends AbstractGuard<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum, NewSpuApplySendEventContext> {
@Resource
private NewSpuApplyOperateHelper newSpuApplyOperateHelper;
@Override
protected boolean process(StateContext<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> context) {
final CatetorySendEventContextRequest<NewSpuApplyContext> request = getSendEventContext(context).getRequest();
NewSpuApplyContext ctx = request.getParams();
Integer applyType = ctx.getApplyType(); //从业务数据中取出商品来源
NspStatusDecider<NewSpuApplyContext, Result> nspStatusDecider = newSpuApplyOperateHelper.getNspStatusDecider(applyType, NewSpuApplyStateMachineEventsEnum.BR_HUMAN_AUDIT_SUPPORT_NONE.getCode()); //固定的事件code
//判定目标状态
Result result = nspStatusDecider.decideStatus(ctx);
ctx.setResult(result); //将判定结果放入上下文,其他的guard可以引用结果,避免重复判断
return Result.isSuccess(result); //根据判定结果决定是否匹配当前guard对应的目标状态
}
}
Acción en estado de Elección:
@Component
public class NspBrAuditNoIdentifyAction extends AbstractSuccessAction<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum, CategorySendEventContext> {
@Resource
private NewSpuApplyOperateHelper newSpuApplyOperateHelper;
@Override
protected void process(StateContext<NewProductShowEnum, NewSpuApplyStateMachineEventsEnum> context) {
final CatetorySendEventContextRequest<NewSpuApplyContext> request = getSendEventContext(context).getRequest();
NewSpuApplyContext ctx = request.getParams();
Integer applyType = ctx.getApplyType(); //从业务数据中取出商品来源
NspOperate<NewSpuApplyContext> nspOperate = newSpuApplyOperateHelper.getNspOperate(applyType, NewSpuApplyStateMachineEventsEnum.BR_HUMAN_AUDIT_SUPPORT_NONE.getCode()); //固定的事件code
//做请求的预处理
nspOperate.preProcessRequest(ctx);
//对业务数据做校验
nspOperate.verify(ctx);
//执行业务逻辑
nspOperate.process(ctx);
//持久化
nspOperate.persistent(ctx);
//后处理
nspOperate.post(ctx);
}
}
La única diferencia con la acción con un estado de destino fijo es que se ejecutan los métodos preProcessRequest y de verificación de NspOperate.
En lugar de usar diferentes implementaciones de protección y acción entre diferentes canales, use clases de estrategia separadas para dividir diferentes implementaciones de canales por las dos consideraciones siguientes:
-
Es posible reemplazar la implementación de la máquina de estados, por lo que no se espera que el código relacionado con la implementación de la máquina de estados esté acoplado con el código de lógica de negocios;
-
En escenarios que no involucran máquinas de estado, también es necesario dividir la lógica por canal, como la edición de aplicaciones de nuevos productos, etc.
Vinculación con el flujo de estado de SPU durante el proceso de lanzamiento del producto
Cuando la muestra del nuevo producto ingresa al estado "Información del producto pendiente de revisión", el proceso de la máquina de estado de la SPU se hará cargo del flujo de estado de la SPU posterior. Cuando el estado de la SPU alcance "Auditoría aprobada", el estado de la muestra del nuevo producto fluirá a la investigación comercial. y etapa de revisión. Durante este período, cada cambio de información y estado de la SPU debe notificarse de las muestras entrantes de nuevos productos (a través de MQ o evento en la aplicación), y luego se realiza el procesamiento comercial correspondiente en los registros de muestras entrantes de nuevos productos.
Análisis ampliado posterior
Para cambios futuros que puedan estar involucrados en el proceso de aplicación de nuevos productos, evaluar la escalabilidad de esta transformación.
Agregar nuevos canales de origen de productos
Simplemente configure una nueva máquina de estado para implementar diversas operaciones comerciales y eventos para el nuevo canal sin afectar los canales existentes.
Nodo de estado agregado para muestras de nuevos productos.
Simplemente modifique la configuración de la máquina de estados y agregue nuevos eventos y las clases de implementación correspondientes.
Ajustar el orden entre estados para muestras entrantes de nuevos productos
Modifique la configuración de la máquina de estado y evalúe la modificación de las clases de implementación de operaciones comerciales involucradas. El alcance de la modificación es claro y controlable.
10. Resumen
Utilizamos el modelo de estrategia para desacoplar la lógica empresarial de diferentes canales de origen de productos, conservar los puntos comunes e implementar su propia lógica diferenciada para proporcionar escalabilidad para cambios futuros en los requisitos comerciales mediante la introducción de máquinas de estado, aclaramos y estandarizamos el estado de las mismas; El proceso de nuevo producto garantiza que el estado se transfiera de forma correcta y legal, al tiempo que sienta una base sólida para futuros cambios en el proceso de negocio.
Por un lado, esta transformación resuelve los problemas persistentes en la implementación actual y reduce la dificultad de comenzar con el código existente. Por otro lado, también tiene en cuenta la eficiencia del desarrollo en el futuro, ya sea que se agreguen nuevas fuentes. canales o modificar procesos comerciales, el alcance de las modificaciones del código se puede garantizar. Es controlable y medible sin agregar carga de trabajo adicional, y puede respaldar el negocio de manera más efectiva, segura y estable.
* Texto/Naranja dulce
Este artículo es original de Dewu Technology. Para obtener más artículos interesantes, consulte: Sitio web oficial de Dewu Technology.
La reimpresión sin el permiso de Dewu Technology está estrictamente prohibida; de lo contrario, se perseguirá la responsabilidad legal de acuerdo con la ley.
Los estudiantes de secundaria crean su propio lenguaje de programación de código abierto como una ceremonia de mayoría de edad: comentarios agudos de los internautas: confiando en la defensa, Apple lanzó el chip M4 RustDesk Los servicios nacionales fueron suspendidos debido al fraude desenfrenado Yunfeng renunció a Alibaba. En el futuro, planea producir un juego independiente en la plataforma Windows Taobao (taobao.com). Reiniciar el trabajo de optimización de la versión web, destino de los programadores, Visual Studio Code 1.89 lanza Java 17, la versión Java LTS más utilizada, Windows 10 tiene un cuota de mercado del 70%, Windows 11 continúa disminuyendo Open Source Daily | Google apoya a Hongmeng para que se haga cargo; Rabbit R1 de código abierto respalda los teléfonos Android; Haier Electric ha cerrado la plataforma abierta;