`
barryzhong
  • 浏览: 21388 次
  • 性别: Icon_minigender_1
社区版块
存档分类

生命周期组件框架:生命周期描述语言——条件转移以及生命周期回调 示例

阅读更多
    @StateMachine
    public static interface InvoiceStateMachineMeta {

        @StateSet
        static interface States {

            @Initial
            @Function(transition = InvoiceStateMachineMeta.Transitions.Post.class, value = { InvoiceStateMachineMeta.States.Posted.class })
            static interface Draft {}
            @Functions({ @Function(transition = InvoiceStateMachineMeta.Transitions.Pay.class, value = { States.PartialPaid.class,
                    InvoiceStateMachineMeta.States.PaidOff.class }) })
            static interface Posted {}
            @Function(transition = InvoiceStateMachineMeta.Transitions.Pay.class, value = { States.PartialPaid.class,
                    InvoiceStateMachineMeta.States.PaidOff.class })
            static interface PartialPaid {}
            @End
            static interface PaidOff {}
        }
        @TransitionSet
        static interface Transitions {

            static interface Post {}
            @Conditional(condition = Payable.class, judger = PayableJudger.class, postEval = true)
            static interface Pay {}
        }
        @ConditionSet
        static interface Conditions {

            static interface Payable {

                BigDecimal getTotalAmount();

                BigDecimal getPayedAmount();
            }
        }
        public static class Utilities {

            public static class PayableJudger implements ConditionalTransition<Payable> {

                @Override
                public Class<?> doConditionJudge(Payable t) {
                    if ( 0 < t.getPayedAmount().compareTo(BigDecimal.ZERO) && 0 < t.getTotalAmount().compareTo(t.getPayedAmount()) ) {
                        return PartialPaid.class;
                    } else if ( 0 >= t.getTotalAmount().compareTo(t.getPayedAmount()) ) {
                        return PaidOff.class;
                    } else {
                        throw new IllegalStateException();
                    }
                }
            }
        }
    }
    @StateMachine
    public static interface InvoiceItemStateMachineMeta {

        @StateSet
        static interface States {

            @Initial
            @Function(transition = InvoiceItemStateMachineMeta.Transitions.Pay.class, value = { InvoiceItemStateMachineMeta.States.Paid.class })
            static interface Unpaid {}
            @End
            @InboundWhile(on = { InvoiceStateMachineMeta.States.Posted.class, InvoiceStateMachineMeta.States.PartialPaid.class },
                    relation = InvoiceItemStateMachineMeta.Relations.ParentInvoice.class)
            static interface Paid {}
        }
        @TransitionSet
        static interface Transitions {

            static interface Pay {}
        }
        @RelationSet
        static interface Relations {

            @RelateTo(InvoiceStateMachineMeta.class)
            static interface ParentInvoice {}
        }
    }

 

@LifecycleMeta(InvoiceStateMachineMeta.class)
    public static class Invoice extends ReactiveObject implements InvoiceStateMachineMeta.Conditions.Payable {

        private final BigDecimal totalAmount;;
        private BigDecimal payedAmount = new BigDecimal(0D);
        private final List<InvoiceItem> items = new ArrayList<>();

        public Invoice(final BigDecimal totalAmount) {
            initialState(InvoiceStateMachineMeta.States.Draft.class.getSimpleName());
            this.totalAmount = totalAmount;
        }

        @Condition(InvoiceStateMachineMeta.Conditions.Payable.class)
        public InvoiceStateMachineMeta.Conditions.Payable getPayable() {
            return this;
        }

        @Override
        public BigDecimal getTotalAmount() {
            return totalAmount;
        }

        @Override
        public synchronized BigDecimal getPayedAmount() {
            return payedAmount;
        }

        @Transition
        public void post() {}

        @Transition(InvoiceStateMachineMeta.Transitions.Pay.class)
        @PostStateChange(to = InvoiceItemStateMachineMeta.States.Paid.class, observableName = "items", mappedBy = "parent")
        public synchronized void onItemPaied(LifecycleContext<InvoiceItem, String> context) {
            payedAmount = payedAmount.add(context.getTarget().getPayedAmount());
        }

        public void addItem(InvoiceItem invoiceItem) {
            if ( !items.contains(invoiceItem) ) {
                items.add(invoiceItem);
            }
        }

        public List<InvoiceItem> getItems() {
            return Collections.unmodifiableList(items);
        }
    }
    @LifecycleMeta(InvoiceItemStateMachineMeta.class)
    public static class InvoiceItem extends ReactiveObject {

        private int seq;
        private BigDecimal amount;
        private BigDecimal payedAmount;
        private final Invoice parent;

        public InvoiceItem(Invoice parent, BigDecimal amount) {
            initialState(InvoiceItemStateMachineMeta.States.Unpaid.class.getSimpleName());
            this.amount = amount;
            this.parent = parent;
            this.seq = this.parent.getItems().size() + 1;
            this.parent.addItem(this);
        }

        @Transition
        public void pay(final BigDecimal amount) {
            if ( 0 < this.amount.compareTo(amount) ) {
                throw new IllegalArgumentException("paying amount is not enough to pay this item.");
            }
            this.payedAmount = amount;
        }

        public BigDecimal getPayedAmount() {
            return payedAmount;
        }

        @Relation(InvoiceItemStateMachineMeta.Relations.ParentInvoice.class)
        public Invoice getParent() {
            return this.parent;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ( ( parent == null ) ? 0 : parent.hashCode() );
            result = prime * result + seq;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if ( this == obj ) return true;
            if ( obj == null ) return false;
            if ( getClass() != obj.getClass() ) return false;
            InvoiceItem other = (InvoiceItem) obj;
            if ( parent == null ) {
                if ( other.parent != null ) return false;
            } else if ( !parent.equals(other.parent) ) return false;
            if ( seq != other.seq ) return false;
            return true;
        }
    }

 

    @Test
    public void test_relational_callback_post_state_change() {
        final Invoice invoice = new Invoice(new BigDecimal(10000.0D));
        final InvoiceItem itemOne = new InvoiceItem(invoice, new BigDecimal(4000.0D));
        final InvoiceItem itemTwo = new InvoiceItem(invoice, new BigDecimal(4000.0D));
        final InvoiceItem itemThree = new InvoiceItem(invoice, new BigDecimal(2000.0D));
        invoice.post();
        assertState(InvoiceStateMachineMeta.States.Posted.class, invoice);
        assertState(InvoiceItemStateMachineMeta.States.Unpaid.class, itemOne);
        itemOne.pay(new BigDecimal(4000.0D));
        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemOne);
        assertState(InvoiceStateMachineMeta.States.PartialPaid.class, invoice);
        itemTwo.pay(new BigDecimal(4000.0D));
        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemTwo);
        assertState(InvoiceStateMachineMeta.States.PartialPaid.class, invoice);
        itemThree.pay(new BigDecimal(2000.0D));
        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemThree);
        assertState(InvoiceStateMachineMeta.States.PaidOff.class, invoice);
    }

 前文:生命周期组件框架——关系型状态及服务

分享到:
评论

相关推荐

    [已更新Demo附件]生命周期组件框架——关系型状态机服务

    近期,我深入研究了一个名为“生命周期组件框架——关系型状态机服务”的框架,其旨在简化这一过程,并通过关系型状态机来管理组件的生命周期。接下来,我将详细介绍这个框架的核心概念、源码实现以及其作为工具的...

    【OpenHarmony】ArkTS 语法基础 ③ ( 自定义组件生命周期回调函数 - 页面生命周期回调函数 )

    【OpenHarmony】ArkTS 语法基础 ③ ( @Component 自定义组件生命周期回调函数 | @Entry 页面生命周期回调函数 ) https://hanshuliang.blog.csdn.net/article/details/139424435 博客源码快照 一、ArkTS @Component ...

    Android 设计模式:(一)观察者模式 —— 封装行为的大局观

    但通常在Android开发中,我们更倾向于使用Android提供的`Observer`和`LiveData`等组件,这些组件更加适应Android的生命周期管理。 例如,在`StrategyDemo`这个示例中,我们可以假设它演示了如何在Android应用中使用...

    Android activity生命周期示例

    这是Activity生命周期的第一个回调,开发者通常在这里初始化UI布局、设置基本属性和数据。 2. **启动(Started)**:`onStart()`方法在Activity可见但不一定是焦点时调用。此时,Activity已对用户可见,但可能被...

    Android四大基本组件介绍与生命周期 pdf 介绍

    - **生命周期**:主要包括onCreate()、onStartCommand()或onBind()、onDestroy()等回调方法。 ##### 3. ContentProvider - **定义**:ContentProvider用于实现不同应用间的共享数据。 - **用途**:存储和检索数据,...

    Activity生命周期详解

    在这个例子中,我们创建了一个名为`LifeCycleActivity`的`Activity`类,并在每个生命周期回调方法中记录了日志消息。这样可以帮助开发者跟踪`Activity`的生命周期状态变化,并据此调整代码逻辑。 总结来说,理解`...

    将Activity的生命周期打印出来

    在描述中提到的操作,如锁屏、亮屏、解锁或长按电源键,会触发以下特定的生命周期回调: - **锁屏**:通常会调用`onPause()`和`onStop()`。 - **亮屏**:如果Activity之前已停止,亮屏可能调用`onRestart()`、`...

    动手学Android之七——Activity生命周期

    "动手学Android之七——Activity生命周期"这个主题深入探讨了Activity如何在应用程序中创建、运行、暂停、停止以及销毁的过程,这对于理解和优化应用性能至关重要。在这个例子程序中,开发者将有机会实践这些生命...

    Ability生命周期.zip

    - 生命周期回调方法必须高效执行,以确保快速响应系统事件。 - 不要在`onCreate()`和`onStart()`中执行长时间的任务,这可能导致用户界面延迟加载。 - 在`onDestroy()`中清理所有资源,包括订阅、定时器等,以...

    Android-DailyNet简单易用的Android网络请求框架自动绑定生命周期调度请求

    《DailyNet:Android轻量级网络请求框架及生命周期管理》 在移动开发领域,尤其是在Android平台上,网络请求是应用程序不可或缺的一部分。为了简化网络通信过程,许多开发者选择使用网络请求库来处理HTTP请求。其中...

    android Activity生命周期

    在实际开发中,开发者应合理利用生命周期回调,例如在`onCreate()`中初始化资源,在`onStart()`或`onResume()`中启动定时任务,在`onPause()`中停止耗时操作,以确保用户体验流畅,并避免内存泄漏。同时,理解...

    Activity生命周期总结

    在 Android 开发中,理解 Activity 的生命周期是非常重要的,因为它直接影响到应用程序的行为、性能以及用户体验。本文将详细介绍 Activity 生命周期中的各个方法及其触发条件,并通过示例代码进行说明。 #### ...

    深入FLEX组件生命周期

    **定义**:配置阶段用于完成组件的详细配置,包括设置组件的属性、事件回调函数、样式以及效果定义等。这一阶段应尽可能在初始化阶段之前完成所有必要的配置任务。 **代码示例**: ```as // 在配置阶段设置样式 ...

    Spring bean生命周期demo

    在Spring框架中,Bean的生命周期是指从创建到销毁的整个过程。这个过程包含了初始化、正常使用以及最终的销毁几个阶段。了解并掌握Spring Bean的生命周期对于优化应用性能和资源管理至关重要。接下来,我们将深入...

    第四章示例代码__对象的生命周期链

    4. **对象的生命周期回调**:Spring.Net允许在对象生命周期的关键点注册回调方法,如初始化后(`init-method`)、销毁前(`destroy-method`)。这些方法可以在特定时刻执行自定义逻辑。 ```xml ``` 5. *...

    日志跟踪Activity生命周期

    在博客“日志跟踪Activity生命周期”中,作者可能详细介绍了如何利用Android的日志系统(Logcat)来追踪这些生命周期回调。开发者可以通过在每个生命周期方法内添加`Log.d()`或`Log.i()`等方法来记录信息,例如: `...

    View的生命周期

    通过分享这个示例,开发者可以学习如何创建和管理自定义View的生命周期,从而提升Android应用的用户体验和功能多样性。 总结来说,理解并掌握View的生命周期是Android开发中的重要技能。通过自定义View,我们可以...

    Android生命周期详细案例

    而ActivityLife可能是一个示例代码文件,包含了Activity生命周期的各个回调方法,供开发者参考学习。 除了上述基本状态,Android还提供了`onSaveInstanceState()`方法来保存Activity的状态信息,以防系统因内存压力...

    Fragment的生命周期以及使用技巧源码

    在`FragmentStudy`项目中,你可以找到各种示例,包括生命周期方法的打印,不同操作的处理,以及如何在Fragment之间传递数据。通过研究这些代码,你将能够更好地掌握Fragment的使用和最佳实践。 总结,Fragment是...

    Android监听——回调模式与观察者模式

    例如,在Android的回调模式中,Activity的生命周期方法就是一个接口,开发者通过实现这些接口方法来定义回调行为。而在观察者模式中,Java的Observer和Observable接口提供了标准的观察者模式实现,但Android的...

Global site tag (gtag.js) - Google Analytics