Praxis des Zugriffs auf eine neue Geschäftszustandsmaschine für die Produkteinführung

1. Einführung in das Geschäft mit der Einführung neuer Produkte

001.png

Bei der Produktauflistung handelt es sich um die Bereitstellung eines neuen Produkts auf der Dewu-Plattform. Ein vollständiger Produktauflistungsprozess beginnt mit der Einreichung neuer Produktanträge aus verschiedenen Quellen und Kanälen. Er muss mehrere Überprüfungsrunden durch verschiedene Rollen durchlaufen, darunter:

  • Überprüfung der Produktauswahl: Stellen Sie fest, ob es die Regalanforderungen erfüllt, basierend auf den im Antrag für das neue Produkt eingereichten Informationen.

  • Überprüfung der Produktdaten: Überprüfung der Produktdaten auf Richtigkeit und Vollständigkeit, einschließlich mehrerer Runden der Geschäftsverwaltung, Risikokontrolle und rechtlichen Überprüfung;

  • Geschäftsforschungsbewertung: Die Geschäftsforschungsbewertung ist eine Beurteilung der Fähigkeit des Produkts, auf der Plattform identifiziert und unterstützt zu werden, was ebenfalls ein Merkmal des Dewu-Geschäfts ist.

In diesen Überprüfungsrunden gehören die Überprüfung der Produktauswahl und die Überprüfung der Geschäftsforschung zum Prozess der Neuproduktbemusterung. Sie bestimmen, ob das Produkt auf der Dewu-Plattform verkauft werden kann Er gehört zum Produktdatenverarbeitungsprozess und stellt fest, ob die aktuellen Produktinformationen die Anforderungen für die Anzeige auf der C-Seite erfüllen.

Daher müssen bei der Systemimplementierung der Statusfluss des Prozesses für neue Produkteingangsproben und der Produktdatenverarbeitungsprozess einbezogen werden. Ersteres betrifft die Tabelle für neue Produkteingangsproben, und letzteres ist hauptsächlich die Produkt-SPU-Haupttabelle Der Schwerpunkt liegt auf dem Fluss und der Zustandsmaschine des Prozesses für eingehende Proben von neuen Produkten. Die Quellkanalattribute des Prozesses für neue Produktproben sind sehr offensichtlich und es gibt große oder kleine Unterschiede in der Geschäftslogik und den Prozessen verschiedener Kanäle.

2. Warum den Zugriff auf eine Zustandsmaschine in Betracht ziehen?

  • Es gibt eine große Anzahl von Statusaufzählungswerten und die Bedingungen für deren Übertragung sind unklar. Um den Geschäftsprozess zu verstehen, müssen Sie den Code sorgfältig studieren, und die Kosten für den Einstieg und die Wartung sind hoch.

  • Die Übertragung von Staaten wird durch den Code völlig willkürlich festgelegt, und es birgt Risiken bei der willkürlichen Übertragung zwischen Staaten.

  • Einige Statusübertragungen unterstützen keine Idempotenz, und wiederholte Vorgänge können unerwartete Folgen haben.

  • Die Kosten und das Risiko der Übertragung neuer und geänderter Zustände sind hoch, der Umfang der Codeänderungen ist unkontrollierbar und das Testen erfordert eine Regression des gesamten Prozesses.

3. Status, der am neuen Produkteinführungsprozess beteiligt ist

Aufzählung des Status neuer Produktbeispiele

Das Statusfeld, das der Beispieltabelle für neue Produkte entspricht, enthält die folgenden Aufzählungswerte (zur Vereinfachung der Erklärung leicht vereinfacht):

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, "新品资料审核通过"),
}

SPU-Statusaufzählung

Das Statusfeld, das der Produkt-SPU-Haupttabelle entspricht, enthält die folgenden Aufzählungswerte (zur Vereinfachung der Erklärung leicht vereinfacht):

public enum SpuStatusEnum {
    OFF_SHELF(0, "下架"),
    ON_SHELF(1, "上架"),
    TO_APPROVE(2, "待审核"),
    APPROVED(3, "审核通过"),
    REJECT(4, "审核不通过"),
    TO_RISK_APPROVE(8, "待风控审核"),
    TO_LEGAL_APPROVE(9, "待法务审核"),
}

Der Statusübertragungsteil der SPU, der am Geschäftsprozess zur Einführung neuer Produkte beteiligt ist, unterliegt der Statusübertragung des Produkts. Die Produktstatusübertragung ist ebenfalls mit der Zustandsmaschine verbunden (dies ist jedoch nicht der in diesem Artikel behandelte Inhalt). Der Artikel befasst sich hauptsächlich mit dem Status der neuen Produktbeispiel-Statusübertragung.

4. Alle Veranstaltungen zu neuen Produktmustern

  • Neuen Produktentwurf speichern

  • Reichen Sie einen neuen Produktantrag ein

  • Produktauswahl bestanden

  • Die Produktauswahl ist fehlgeschlagen

  • Erneut einreichen, nachdem die Produktauswahl abgelehnt wurde

  • Initiieren Sie eine Überprüfung der Unternehmensforschung

  • Identifizierung von Unternehmensforschungsbewertungen und -unterstützung

  • Die Identifizierung von Unternehmensforschungsbewertungen wird nicht unterstützt

  • Unternehmensforschungsbericht – Produktinformationen sind falsch

  • SPU-Überprüfung seit mehr als X Tagen abgelehnt

  • Veranlassen Sie den Probenversand

  • Aktualisierung des Musterlieferungsfortschritts

Insgesamt 12.

5. Übertragung des Musterstatus neuer Produkte

Wie oben erwähnt, haben verschiedene Produktquellenkanäle unterschiedliche neue Produkteinführungsprozesse, was bedeutet, dass der Statusfluss verschiedener Kanäle auch unterschiedlich ist. Das Folgende ist eine Darstellung der B-Seiten-Verkäuferkanäle:

002.png

In der Abbildung stellt das orangefarbene Kästchen den Status der eingehenden Proben neuer Produkte dar, das grüne Kästchen stellt den SPU-Status dar, das blaue abgerundete Kästchen stellt das Ereignis dar, das die Zustandsänderung auslöst, und die durch Pfeile verbundenen Stellen stellen den Fluss vom aktuellen Zustand dar zum nächsten Zustand.

Beachten Sie, dass beim Auslösen bestimmter Ereignisse der Zielzustand, in den übertragen werden muss, nicht festgelegt ist. Um den Zielzustand zu bestimmen, in den das Ereignis letztendlich übergehen wird, sind eine Reihe logischer Beurteilungen erforderlich.

6. Auswahl der Zustandsmaschinentechnologie

Wählen Sie Spring StateMachine als eigentliches Zustandsmaschinen-Framework. Weitere Informationen finden Sie in diesem Artikel : https://mp.weixin.qq.com/s/TqXMtS44D4w6d1-KLxcoiQ .

7. Schwierigkeiten beim Zugriff auf Zustandsmaschinen

Derzeit ist der Code für neue Produktmuster immer noch mit dem Problem der Codekopplung zwischen verschiedenen Kanälen konfrontiert, das bei diesem Zugriff gemeinsam gelöst werden muss. Andernfalls sind die Kosten für den Zugriff auf die Zustandsmaschine sehr hoch und die Qualität wird schwer zu gewährleisten sein , und die anschließende Wartung wird schwieriger. Selbst wenn die oben genannten Änderungen an der Zustandsmaschine unter idealen Bedingungen ohne weitere Änderungen vorgenommen werden, treten immer noch zwei Probleme auf:

  • Kopplung der Zielzustandsbeurteilungslogik;

  • Die Kopplung, die die Aktion tatsächlich ausführt.

Es kann einfach verstanden werden, dass es in der Implementierung des Guards der Zustandsmaschine (um festzustellen, ob die Voraussetzungen für die Ausführung erfüllt sind) und der Aktion (die tatsächliche Ausführung der Aktion) eine sehr große Schnittstelle gibt, die unterschiedliche Methoden zur Bestimmung des Ziels enthält Status und die Ausführung unterschiedlicher Aktionen zwischen allen Kanälen. Es ist sehr schwierig zu verstehen, was ein bestimmter Kanal konkret tut.

Das Problem konzentriert sich auf den Code der Produktauswahlüberprüfungs- und Geschäftsforschungsüberprüfungsschnittstelle für eingehende Proben neuer Produkte (dieser Teil ist auch der Teil mit der komplexesten Geschäftslogik für eingehende Proben neuer Produkte). Pass-Fail-Logik, Produktauswahl und Geschäftsforschungslogik sind alle lang und nicht lesbar. Es gibt auch Probleme bei großen Transaktionen (mehrere RPC-Aufrufe in der Transaktion). während die Staatsmaschine verbunden ist und Fusionen, insbesondere einschließlich:

  • Codes für verschiedene Kanäle werden im Strategiemodus aufgeteilt;

  • Verschiedene Zustände und unterschiedliche Verarbeitungslogiken für Operationsereignisse werden in den Schutz- und Aktionsklassen verschiedener Zustände und Ereignisse der Zustandsmaschine zusammengefasst.

  • Die gleiche Codeverarbeitungslogik in verschiedenen Kanälen wird in einzelne Codemodule gekapselt und in jedem Kanal aufgerufen.

Die allgemeine Transformationsmethode ist in der folgenden Abbildung dargestellt:

003.png

8. Erwartetes Einkommen

Wie aus dem oben Gesagten hervorgeht, müssen, obwohl es sich um einen Zustandsmaschinenzugriff handelt, tatsächlich zwei Aspekte der Transformation abgeschlossen werden. Der eine besteht darin, die Entkopplung des in Kanäle und Operationen unterteilten Geschäftscodes im gesamten neuen Prozess abzuschließen die Transformation, konnten:

  • Lösen Sie wichtige Transaktionsprobleme im vorherigen Link zur Anwendung neuer Produkte, z. B.: Einreichung der Registrierung und Überprüfung neuer Produkte;

  • Durch die geschäftliche Isolation zwischen Produktquellkanälen ist der Umfang von Codeänderungen besser kontrollierbar und für Tests förderlicher.

  • Verbessern Sie die Skalierbarkeit des Codes, senken Sie die Schwelle für das Codeverständnis und verbessern Sie die Effizienz der iterativen Entwicklung für den täglichen Bedarf.

Der zweite ist der Zugriff auf die Zustandsmaschine, mit der das Zustandsflussproblem im Probenahmeprozess für neue Produkte gelöst werden kann, einschließlich:

  • Einheitliche und zentrale Verwaltung von Statusänderungsregeln zur Erleichterung des Lernens und der späteren Wartung;

  • Vermeiden Sie illegale und wiederholte Statusübertragungen;

  • Es wird einfacher, die Reihenfolge zwischen neuen Zuständen und Zustandsprozessen anzupassen, und Codeänderungen sind besser kontrollierbar.

9. Detailliertes Design

Der Grund für die Aufteilung nach Kanal

Das Initiieren neuer Produktmuster aus verschiedenen Produktquellenkanälen ist ein Prozess, bei dem verschiedene Rollen neue Produkte über verschiedene Terminals einreichen. Die Kombination von Rollen und Terminals ist nicht beliebig kombinierbar ein gemeinsames Geschäftsmerkmal, nur wenn spezifische Rollen festgelegt werden, kann ein vollständiger Geschäftsprozess bestimmt werden.

Die Möglichkeit, neue Produkte in jedem Kanal zu beantragen, ist ebenfalls unterschiedlich. Beispielsweise verfügen Händler über den umfassendsten Überblick über Produktinformationen, sodass sie bei der Beantragung neuer Produkte vollständige Produktinformationen eingeben können, und es gibt mehr Geschäftsprozesse als andere Im Vergleich dazu können auf der App-Seite nur wenige Produktinformationen eingegeben werden. Sobald der Antrag abgelehnt wird, kann er nicht mehr geändert und übermittelt werden. Daher sind Unterschiede zwischen verschiedenen Kanälen natürlich und können abhängig von den Kanälen selbst weiterhin bestehen.

Daher ist es sinnvoll und notwendig, bei bestimmten Vorgängen nach Kanälen aufzuteilen.

Der Geschäftsbetrieb ist nach Kanälen entkoppelt

Gemeinsame Schnittstelle für den Geschäftsbetrieb

Einzelne Datensätze vieler wichtiger Knoten in neuen Produktproben (Batch-Vorgänge werden ebenfalls in Einzelverarbeitung umgewandelt) Geschäftsvorgänge (z. B. Einreichen neuer Produktanträge, Überprüfung der Produktauswahl, Überprüfung der Geschäftsforschung) können in „ Anforderungsvorverarbeitung -> Vorgangsüberprüfung“ abstrahiert werden „ -> Geschäftslogik ausführen -> Persistenzoperationen -> Zugehörige Nachbearbeitungsaktionen “, sodass eine gemeinsame Schnittstellenklasse entwickelt wurde, um den Ausführungsprozess verschiedener Geschäftsoperationen für neue Produkte und Muster aus verschiedenen Kanälen zu übertragen:

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

Einige Notizen:

  • Jedes Ereignis der nachfolgenden Zustandsmaschine entspricht eins zu eins dem Operationstyp der Schnittstelle.  Darüber hinaus können auch andere Operationstypen für Szenarien definiert werden, die keinen Statustransfer beinhalten (zum Beispiel: Bearbeiten neuer Produktanwendungen, Erstellen von SPUs basierend auf neuen Produktanwendungen).

  • Die Definition der Prozessmethode ist relativ weit gefasst. In verschiedenen Geschäftsabläufen kann der tatsächliche Ausführungsinhalt sehr unterschiedlich sein. Wenn Sie beispielsweise eine neue Produktbewertung einreichen, führen Sie möglicherweise nur einige Datenzusammenstellungsaktionen durch. Sie müssen die Ziele nach dieser Operation analysieren. Daher können Unterklassen weiter aufteilen und neue Methoden definieren, die basierend auf ihren eigenen Geschäftsanforderungen implementiert werden sollen.

  • Die persistente Persistenzmethode wird separat definiert, um das Hinzufügen von Transaktionen nur zu dieser Methode zu unterstützen. Der aktuelle Systemcode hat tatsächlich ein ähnliches Design, aber die Transaktion ist zu umfassend und umfasst möglicherweise verschiedene RPCs Aufrufe, was auch einer der wichtigen Gründe für große Transaktionen ist. Daher ist hier klar, dass die Implementierung dieser Methode nur DB-Operationen liest und schreibt und keine Geschäftslogik enthält.

  • Jede Implementierung dieser Schnittstelle verwendet „Produktquellkanal + Operationstyp“, um einen eindeutigen Schlüssel für die Spring Bean-Verwaltung zu bilden. Um zu berücksichtigen, dass einige Operationen die Produktquelle nicht unterscheiden, ist es zulässig, sie zu definieren Ein spezieller applyType (z. B. -1) zur Darstellung der aktuellen Implementierung unterstützt alle Kanäle. Optimieren Sie beim Abrufen der Implementierung, um die Implementierung des aktuellen Kanals zu erhalten. Wenn nicht gefunden, versuchen Sie, die Implementierung aller Kanäle zu finden:

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

Klasse zur Implementierung von Geschäftsabläufen

Gemäß dem aktuellen Geschäftsszenario verfügt die Implementierung von Geschäftsvorgängen über bis zu drei Ebenen von Vererbungsbeziehungen, um die Wiederverwendung einiger Codes zu erleichtern:

004.png

  • Die erste Ebene: Dimensionen zum Aggregieren von Vorgangstypen (Geschäftsereignissen), z. B. Geschäftsforschungsüberprüfungen, in denen Sie allgemeine Codes und benutzerdefinierte Methoden für Geschäftsforschungsüberprüfungen definieren können, z. B.: Allgemeine Eingabeparameterüberprüfung für Geschäftsforschungsüberprüfungen. Die Felder sind nicht leer und dergleichen.

  • Zweite Ebene: Spezifisch für die Dimension des Vorgangstyps (Geschäftsereignisse), z. B. Überprüfung der Geschäftsforschung – unterstützt die Identifizierung, Überprüfung der Geschäftsforschung – unterstützt die Identifizierung nicht usw. Hier können Sie die gemeinsamen Codes aller Produktquellkanäle unter dem Vorgangstyp definieren Abmessungen. Beispiel: Der Grund ist erforderlich, wenn die Identifizierung nicht unterstützt wird und die Überprüfung der Geschäftsforschung eine Reihe von Beurteilungslogiken aus mehreren Systemen aufruft.

  • Die dritte Ebene: Spezifische Implementierung auf der Ebene des Produktquellkanals. Sie können den Code in der übergeordneten Klasse wiederverwenden.

Nicht jeder Geschäftsbetrieb erfordert diese drei Implementierungsebenen. Bei der tatsächlichen Verwendung treten drei Situationen auf, wie zum Beispiel:

  • Es gibt nur eine Ebene: Beispiele neuer Produkte werden unabhängig vom Quellkanal des Produkts ungültig gemacht. Alle Kanäle verwenden dieselbe Logik und nur eine Implementierungsklasse reicht aus.

  • Es gibt nur zwei Ebenen: Einen neuen Produktantrag einreichen und zwischen verschiedenen Produktquellenkanälen unterscheiden.

  • Es gibt drei Ebenen: Die Überprüfung der kommerziellen Forschung für neue Produkte ist ebenfalls in mehrere Vorgangstypen (Geschäftsereignisse) unterteilt, z. B.: Überprüfung der kommerziellen Forschung – unterstützt die Identifizierung, Überprüfung der kommerziellen Forschung – unterstützt die Identifizierung nicht, Überprüfung der kommerziellen Forschung – initiiert Probenversand usw. Jeder Warenquellenkanal verfügt über eine eigene Implementierung unter jedem Operationstyp.

Zugriff auf Zustandsmaschinen

Definition des Zustandsautomaten

Dem obigen Statusflussdiagramm nach zu urteilen, ist der Statusfluss neuer Produkte und Muster relativ klar, tatsächlich wird es jedoch einige geringfügige Unterschiede im Statusprozess jedes Kanals geben. Um eine unvollständige Aufteilung der Quellkanäle zu vermeiden, sind umfassende Überlegungen erforderlich Da die Kosten für die Konfiguration der Zustandsmaschine nicht hoch sind, wird entschieden, dass jeder Kanal seine eigene Konfiguration der Zustandsmaschine erstellt.

Am Beispiel des C-seitigen Kanals ist die Konfiguration der Zustandsmaschine wie folgt:

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

Der Status der Zustandsmaschine wird vollständig dem Statusfeld in der Beispiel-DB-Tabelle für neue Produkte zugeordnet, und die Ereignisse der Zustandsmaschine werden vollständig mit den Ereignissen in der obigen Abbildung abgeglichen.  In den neuen Produktbeispielen gibt es einige Szenarien, die eine Reihe logischer Beurteilungen erfordern, um nach dem Empfang eines Ereignisses zum Zielzustand zu gelangen. Dabei wird der Auswahlzustand der Zustandsmaschine verwendet, um die Beurteilung und Übertragung des Zielzustands abzuschließen .

Lassen Sie uns klären, welche Elemente im Zusammenhang mit der Zustandsmaschine unabhängig voneinander getrennt und welche gemeinsam genutzt werden:

005.png

Es ist ersichtlich, dass nur die Konfigurationsklasse der Zustandsmaschine für jeden Kanal unterschiedlich ist, sodass die Kosten nicht hoch sind. Im Folgenden wird erläutert, wie die Guard- und Action-Implementierungsklassen von allen Kanälen gemeinsam genutzt werden.

Implementierung von Guard und Action

Wie aus der spezifischen Konfiguration der Zustandsmaschine oben ersichtlich ist, gibt es zwei Arten von Zustandsflüssen, die am Probenahmeprozess für neue Produkte beteiligt sind:

  • Der Zielstatus nach dem Auslösen des Ereignisses ist festgelegt. Wenn beispielsweise das Produktauswahlfehler-Ereignis während der Produktauswahlüberprüfung ausgelöst wird, wird der Zielstatus der neuen Produktanwendung als Produktauswahlfehler bestimmt.

  • Der Zielzustand nach dem Auslösen des Ereignisses muss durch die Codelogik beurteilt werden. Aus diesem Grund wird der Auswahlzustand in die Konfiguration des Zustandsautomaten eingeführt, beispielsweise im Falle der Einleitung einer kommerziellen Forschungsüberprüfung Es kann sein, dass die Identifizierung nicht direkt unterstützt wird oder dass der neue Produktantrag direkt angenommen wird. Möglicherweise ist auch eine manuelle Überprüfung erforderlich.

Beim Entwurf der Spring-Zustandsmaschine sind die Verantwortlichkeiten dieser beiden Arten von Zustandsflüssen, Gurad und Aktion, unterschiedlich:

006.png

Daher ist die Implementierungslogik dieser beiden Arten von Schutz und Aktion unterschiedlich.

Für den Schutz und die Aktion unter demselben Ereignis-/Auswahlstatus können jedoch unterschiedliche Produktquellkanäle gemeinsam genutzt werden, da die Aufteilung des Geschäftscodes entsprechend dem Produktquellkanal implementiert wurde und nur an den spezifischen NspOperate im weitergeleitet werden muss Implementierung Die Business-Implementierungsklasse reicht aus. Beispiele sind unten aufgeführt:

Guard mit festem Zielzustand:

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

Als Schutz müssen Sie lediglich die NspOperate-Implementierungsklasse basierend auf der Produktquelle und dem festen Ereigniscode abrufen und die preProcessRequest- und Verify-Methoden von NspOperate aufrufen, um die Überprüfung abzuschließen.

Aktion mit festem Zielzustand:

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

In der Aktion wird auch die NspOperate-Implementierungsklasse basierend auf der Produktquelle und dem festen Ereigniscode abgerufen, und die letzten paar Methoden von NspOperate werden aufgerufen, um den Geschäftsvorgang abzuschließen.

Wache im Wahlzustand:

Guard muss den Zielstatus basierend auf den aktuellen Kanälen und Ereignissen bestimmen. Hier wird eine separate Schnittstelle für Guard abstrahiert, um Aufrufe zu implementieren. Wenn eine ähnliche Logik in NspOperate benötigt wird, kann auch auf diese separate Schnittstelle verwiesen werden, sodass kein Code vorhanden ist Vervielfältigung:

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对应的目标状态
    }
}

Aktion im Auswahlstatus:

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

Der einzige Unterschied zur Aktion mit festem Zielzustand besteht darin, dass die Methoden preProcessRequest und verify von NspOperate ausgeführt werden.

Anstatt unterschiedliche Schutz- und Aktionsimplementierungen zwischen verschiedenen Kanälen zu verwenden, verwenden Sie aus folgenden zwei Gründen separate Strategieklassen, um unterschiedliche Kanalimplementierungen zu unterteilen:

  • Es ist möglich, die Zustandsmaschinenimplementierung zu ersetzen, sodass nicht erwartet wird, dass der Code, der sich auf die Zustandsmaschinenimplementierung bezieht, mit dem Geschäftslogikcode gekoppelt ist.

  • In Szenarien, die keine Zustandsautomaten beinhalten, besteht auch die Notwendigkeit, die Logik nach Kanälen aufzuteilen, z. B. bei der Bearbeitung neuer Produktanwendungen usw.

Verknüpfung mit dem SPU-Statusfluss während des Produkteinführungsprozesses

Wenn das neue Produktmuster den Status „Überprüfung der Produktinformationen steht aus“ erhält, übernimmt der SPU-Statusautomatenprozess den nachfolgenden SPU-Statusfluss. Wenn der SPU-Status „Audit bestanden“ erreicht, fließt der Status des neuen Produktmusters in die kommerzielle Forschung ein und Überprüfungsphase. Während dieses Zeitraums muss jede Informations- und Statusänderung der SPU über eingehende Muster neuer Produkte benachrichtigt werden (über MQ oder ein anwendungsinternes Ereignis), und dann wird die entsprechende Geschäftsverarbeitung für die Datensätze eingehender Muster neuer Produkte durchgeführt.

Anschließend erweiterte Analyse

Bewerten Sie die Skalierbarkeit dieser Transformation für zukünftige Änderungen, die möglicherweise mit dem Anwendungsprozess für neue Produkte verbunden sind.

Fügen Sie neue Produktquellkanäle hinzu

Konfigurieren Sie einfach eine neue Zustandsmaschine, um verschiedene Geschäftsvorgänge und Ereignisse für den neuen Kanal zu implementieren, ohne bestehende Kanäle zu beeinträchtigen.

Statusknoten für neue Produktproben hinzugefügt

Ändern Sie einfach die Konfiguration des Zustandsautomaten und fügen Sie neue Ereignisse und entsprechende Implementierungsklassen hinzu.

Passen Sie die Reihenfolge zwischen den Staaten für neue Produktmuster an

Ändern Sie die Zustandsmaschinenkonfiguration und bewerten Sie die Änderung der beteiligten Geschäftsbetriebsimplementierungsklassen. Der Umfang der Änderung ist klar und kontrollierbar.

10. Zusammenfassung

Wir verwenden das Strategiemodell, um die Geschäftslogik verschiedener Produktquellkanäle zu entkoppeln, Gemeinsamkeiten beizubehalten und ihre eigene differenzierte Logik zu implementieren, um durch die Einführung von Zustandsmaschinen Skalierbarkeit für zukünftige Änderungen der Geschäftsanforderungen bereitzustellen Der neue Produktprozess stellt sicher, dass der Status korrekt und rechtsgültig übertragen wird, und legt gleichzeitig eine solide Grundlage für zukünftige Geschäftsprozessänderungen.

Einerseits löst diese Transformation die hartnäckigen Probleme in der aktuellen Implementierung und verringert die Schwierigkeit, mit dem vorhandenen Code zu beginnen. Andererseits berücksichtigt sie auch die Entwicklungseffizienz in der Zukunft Durch die Änderung von Kanälen oder Geschäftsprozessen kann der Umfang der Codeänderungen garantiert werden. Dies ist ohne zusätzlichen Arbeitsaufwand kontrollierbar und kann das Unternehmen effektiver, sicherer und stabiler unterstützen.

* Text/Süßes Orange

 

Dieser Artikel stammt ursprünglich von Dewu Technology. Weitere spannende Artikel finden Sie auf der offiziellen Website von Dewu Technology

Ein Nachdruck ohne die Genehmigung von Dewu Technology ist strengstens untersagt, andernfalls wird eine rechtliche Haftung gemäß dem Gesetz verfolgt!

High-School-Schüler erstellen ihre eigene Open-Source-Programmiersprache als Coming-of-Age-Zeremonie – scharfe Kommentare von Internetnutzern: Unter Berufung auf die Verteidigung hat Apple den M4-Chip RustDesk veröffentlicht. Inländische Dienste wurden wegen grassierenden Betrugs eingestellt . In Zukunft plant er, ein unabhängiges Spiel auf der Windows-Plattform Taobao (taobao.com) zu produzieren. Webversionsoptimierungsarbeiten neu starten, Ziel für Programmierer, Visual Studio Code 1.89 veröffentlicht Java 17, die am häufigsten verwendete Java LTS-Version, Windows 10 hat eine Marktanteil von 70 %, Windows 11 geht weiter zurück ; Google unterstützt Hongmeng bei der Übernahme von Open-Source-Rabbit-R1;
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/u/5783135/blog/11105548
Empfohlen
Rangfolge