Javaの新鮮なビジネスプラットフォーム - オーダーモジュールのステートマシンアーキテクチャ
説明:新鮮な状態の電力会社の受注がJavaプラットフォームでは、事業譲渡します
私たちは、国家の様々な順序があることを知っている:一時的な注文は、受注評価は、そのためのリターンで完了するまでレシート保留、支払わなければなりません。各状態と状態は、ねじれに先立って実行される前の動作状態についてねじれています。
例は示しています
たとえばプロセス:ユーザーがまだ注文をクリックしていないため、ユーザは、いわゆる「暫定リスト」を生成するために、バックグラウンドでのショッピングカートにアイテムを追加して、注文が実際に正式に生成されていません。シングルユーザー、「暫定リストは、」に変換することができた場合にのみ、「支払われるために。」このプロセスよう:次のシングルの操作の状態発注の「暫定リスト」で唯一、「保留中の支払い」注文のステータスを取得します。すなわち- +適切な前状態動作、注文のステータスを反転させるために。それはハードコードされている場合は、このプロセスでは、我々は、注文の現在の状態を確認の操作を実行し、これらの二つの組み合わせの状態は価値の移転によって得られるべきかの一連の... else文を必要としています。オーダーの流れが非常に複雑になっている場合、ロジックアウト書き込みが非常に複雑になる、と読みやすさは非常に低いです。メンテナンスが遅れてピットです。
2つの状態のデザインパターンや注文状況循環
この問題に対処する、我々は使用することができるステートマシンデザインパターンを処理するために。実際に対応し、ステートマシンです。
ステートマシンのデザインパターンについての具体的な詳細は、自己のBaiduすることができます。ここで、簡単な言葉で要約することができる:オブジェクトの内部状態は、実行外部条件によって変化します。注文の現在の状態との組み合わせで、注文のステータスと現在の操作が行われた変更:そして転送指図ステータスにマッピング。
3つのプリコーディングと抽象デザイン
プロセスのためにシミュレートされた流動状態を示しています。一時的な順序を開始し、順序が既知の状態である時はいつでも、状態を変更するために取得するために、我々は、対応する操作を実行する必要があります。
ビューのステートマシンの観点から、我々は最初の情報と抽象の様々な対処します
3.1コードの抽象
対応するオーダーステータス列挙クラスの準備
パブリック 列挙OrderStatusEnum { CREATE_EVENT( 1、 "受注の作成" )、 FORMAL_EVENT( 2、 "正式注文が" )、 NEED_PAY( 3、 "支払うべき" )、 PAY_DONE( 4、 "有給" )、 ORDER_FINISHED( 5、「注文"完了) ORDER_CANCEL(「注文がキャンセルされている。、6" ); OrderStatusEnum(int型のステータス文字列DESC){ この .status = ステータス、 この .desc = DESC; } 公共 int型のステータス、 パブリック文字列DESC; }
列挙型クラスの必要性はレディステータス情報であることを。
全体の作業のメカニズムを説明するための図で初:
次いで、コアコードの一部は、必要に応じ:管理オーダーステータス転送ステーションマネージャクラス、オペレータ順序ねじれ状態のためのクラスの集合を、ねじれた状態セット注文後論理演算後続のプロセッサタイプを行います。
クラスマネージャは、(対応するクラスのプロセッサで書かれた)ビジネス・ロジックに必要な一連の動作を行う、(opertorクラスに依存する対応)この結果は、ステータスライン上で操作を実行するために得なければならない、受注状況に応じた必要な電流。利点は、転送注文状況と対応するビジネスプロセスがあることであるデカップリング。そして、もはや場合は...他の複雑な操作の束を持っていません。たびに新しい業務フローの注文状況の必要性は、あなたが完了するために、オペレータおよびプロセッサのコンポーネントの対応するセットに書き込むことができ、既存のサービスの分離が高いです。
実施例次に、コードステッカー
/ ** *注文状況循環マネージャ-ステートマシンのコアコンポーネント * @author 電子ビジネスのためのJavaの新鮮なプラットフォーム * * * /
@Component public class OrderStateManager { Map<Integer, AbstractOrderOperator> orderOperatorMaps = new HashMap<Integer, AbstractOrderOperator>(); Map<Integer, AbstractOrderProcessor> orderProcessorMaps = new HashMap<Integer, AbstractOrderProcessor>(); public OrderStateManager() { } /** * 状态流转方法 * @param orderId 订单id * @param event 流转的订单操作事件 * @param status 当前订单状态 * @return 扭转后的订单状态 */ public int handleEvent(final String orderId, OrderStatusEnum event, final int status) { if (this.isFinalStatus(status)) { throw new IllegalArgumentException("handle event can't process final state order."); } // 获取对应处理器,根据入参状态和时间获取订单流转的结果状态 AbstractOrderOperator abstractOrderOperator = this.getStateOperator(event); int resState = abstractOrderOperator.handleEvent(status, event); // 得到结果状态,在对应的processor中处理订单数据及其相关信息 AbstractOrderProcessor orderProcessor = this.getOrderProcessor(event); if (!orderProcessor.process(orderId, resState)) { throw new IllegalStateException(String.format("订单状态流转失败,订单id:%s", orderId)); } return resState; } /** * 根据入参状态枚举实例获取对应的状态处理器 * @param event event * @return */ private AbstractOrderOperator getStateOperator(OrderStatusEnum event) { AbstractOrderOperator operator = null; for (Map.Entry<Integer, AbstractOrderOperator> entry: orderOperatorMaps.entrySet()) { if (event.status == entry.getKey()) { operator = entry.getValue(); } } if (null == operator) { throw new IllegalArgumentException(String.format("can't find proper operator. The parameter state :%s", event.toString())); } return operator; } /** * 根据入参状态枚举实例获取对应的状态后处理器 * @param event event * @return */ private AbstractOrderProcessor getOrderProcessor(OrderStatusEnum event) { AbstractOrderProcessor processor = null; for (Map.Entry<Integer, AbstractOrderProcessor> entry : orderProcessorMaps.entrySet()) { if (event.status == entry.getKey()) { processor = entry.getValue(); } } if (null == processor) { throw new IllegalArgumentException(String.format("can't find proper processor. The parameter state :%s", event.toString())); } return processor; } /** * 判断是不是已完成订单 * @param status 订单状态码 * @return */ private boolean isFinalStatus(int status) { return OrderStatusEnum.ORDER_FINISHED.status == status; } }
核心的代码就是类中的 handleEvent 方法。
对应的获取到的组件处理类示例:
/** * @author Java生鲜电商平台-订单模块状态机架构设计 **/ @Data public abstract class AbstractOrderOperator { int status; public abstract int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum); } =================================== /** * 创建订单操作状态流转 * Java生鲜电商平台-订单模块状态机架构设计 **/ @Component @OrderOperator public class CreateOrderOperator extends AbstractOrderOperator { public CreateOrderOperator() { super.setStatus(1); } @Override public int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum) { if (orderStatus != OrderStatusEnum.CREATE_EVENT.status && orderStatus != OrderStatusEnum.ORDER_CANCEL.status) { throw new IllegalArgumentException(String.format("create operation can't handle the status: %s", orderStatus)); } System.out.println("进入创建订单状态扭转处理器..."); switch (orderStatusEnum) { case CREATE_EVENT: return OrderStatusEnum.FORMAL_EVENT.status; case ORDER_CANCEL: return OrderStatusEnum.ORDER_CANCEL.status; default: return getStatus(); } } }
后处理器
/** * 订单处理器 **/ @Data public abstract class AbstractOrderProcessor { int status; public abstract boolean process(String orderId, Object... params); }
@Component @OrderProcessor public class CreateOrderProcessor extends AbstractOrderProcessor{ public CreateOrderProcessor() { super.setStatus(1); } @Override public boolean process(String orderId, Object... params) { // TODO 创建/取消订单对应的数据库修改,mq发送等操作,可以在此处process方法中完成 System.out.println("进入创建订单后处理器..."); return true; } }
这些组件类都是依赖于spring的组件扫描注入。如果要定制化地处理自己的组件类。可以用一些其他的技巧来处理。比如此处使用到了自定义注解,通过自定义注解+自定义状态机初始化类来完成对应组件类的筛选与初始化。将这个初始化类加载完毕,状态机就可以正常使用了。
/** * 状态机前置激活类,在spring中扫描配置此类 <br/> * 使用自定义注解标记对应的状态处理器和后置处理器并在初始化操作中完成对应处理器的初始化。 **/ @Component public class Initialization implements BeanPostProcessor { @Resource OrderStateManager manager; @Nullable public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof AbstractOrderOperator && bean.getClass().isAnnotationPresent(OrderOperator.class) ) { AbstractOrderOperator orderState = (AbstractOrderOperator) bean; manager.orderOperatorMaps.put(orderState.getStatus(), orderState); } if (bean instanceof AbstractOrderProcessor && bean.getClass().isAnnotationPresent(OrderProcessor.class) ) { AbstractOrderProcessor orderProcessor = (AbstractOrderProcessor) bean; manager.orderProcessorMaps.put(orderProcessor.getStatus(), orderProcessor); } return bean; } }
这里有一个问题就是在正式开发环境中,依赖于项目的spring环境,需要在状态机正式运行前将对应的状态扭转组件类(operator和processor)注入到环境中。
联系QQ:137071249
QQ群:793305035