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

生命周期组件框架:生命周期描述语言——简单状态机示例代码

阅读更多
    //状态机元数据描述
    @StateMachine
    protected static interface CustomerLifecycleMeta{
        @StateSet
        static interface States {
            @Initial
            @Transition(event = CustomerLifecycleMeta.Events.Activate.class, value = {Active.class})
            static interface Draft{}
            @Transitions({@Transition(event = CustomerLifecycleMeta.Events.Suspend.class, value = Suspended.class), @Transition(event = CustomerLifecycleMeta.Events.Cancel.class, value = Cancelled.class)})
            static interface Active {}
            
            @Transition(event = CustomerLifecycleMeta.Events.Resume.class, value = Active.class)
            static interface Suspended {}
            
            @Final
            static interface Cancelled {}
        }
        @EventSet
        static interface Events {
            static interface Activate {}
            static interface Suspend {}
            static interface Resume {}
            static interface Cancel {}
        }
    }

    

    public abstract static class ReactiveObject {

        @StateIndicator
        private String state = null;

        protected void initialState(String stateName) {
            if ( null == state ) {
                this.state = stateName;
            } else {
                throw new IllegalStateException("Cannot call initialState method after state had been intialized.");
            }
        }

        public String getState() {
            return state;
        }
    }

 

   // 标记生命周期元数据引用的业务对象(反应型对象)

    @LifecycleMeta(CustomerLifecycleMeta.class)
    public static class Customer extends ReactiveObject {

        protected Customer() {
            initialState(Draft.class.getSimpleName());
        }

        @Event
        public void activate() {}

        @Event
        public void suspend() {}

        @Event
        public void resume() {}

        @Event
        public void cancel() {}
    }

 

   // 测试用例

    @Test
    public void test_standalone_object_without_relation_lifecycle() throws VerificationException {
        Customer customer = new Customer();
        customer.activate();
        assertEquals(CustomerLifecycleMeta.States.Active.class.getSimpleName(), customer.getState());
        customer.suspend();
        assertEquals(CustomerLifecycleMeta.States.Suspended.class.getSimpleName(), customer.getState());
        customer.resume();
        assertEquals(CustomerLifecycleMeta.States.Active.class.getSimpleName(), customer.getState());
        customer.cancel();
        assertEquals(CustomerLifecycleMeta.States.Canceled.class.getSimpleName(), customer.getState());
    }

 

正确配置执行环境参数后可以获得下面的引擎执行Log

 //开始执行测试方法

Processing test: test_standalone_object_with_definite_relation(net.madz.lifecycle.engine.EngineCoreFunctionPositiveTests)

//状态机引擎拦截到标记有@Transition的方法执行,开始执行生命周期相关工作
[FINE]: Found Intercept Point: class net.madz.lifecycle.engine.CoreFuntionTestMetadata$Customer.activate( )
[FINE]: Intercepting....instatiating InterceptContext ...

[FINE]: Intercepting....InterceptorController is doing exec ...

[FINE]: Intercepting....instantiating LifecycleInterceptor

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @preExec

[FINE]: intercepting [net.madz.lifecycle.engine.CoreFuntionTestMetadata$Customer@67bba966]
from state: [Draft]
[FINE]: Step 1. start validating State [Draft]
[FINE]: Step 2. start validating transition: [Activate] on state: [Draft]
[FINE]: Step 3. start validating inbound relation constraint is next state is predictable before method invocation.
[FINE]: Step 4. start callback before state change from : Draft => to : Active

[FINE]: intercepting with: net.madz.bcel.intercept.CallableInterceptor @intercept

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @postExec

[FINE]: Step 5. start validating inbound relation constraint is next state after method invocation.
[FINE]: Step 6. Set next state to reactiveObject.
[FINE]: Step 6. ReactiveObject is tranisited to state: [Active]
[FINE]: Step 7. Start Callback after state change from : Draft => to : Active
[FINE]: Step 8. Start fire state change event.

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @cleanup

[FINE]: Intercepting....LifecycleInterceptor is doing cleanup ...

[FINE]: Found Intercept Point: class net.madz.lifecycle.engine.CoreFuntionTestMetadata$InternetServiceOrder.start( )
[FINE]: Intercepting....instatiating InterceptContext ...

[FINE]: Intercepting....InterceptorController is doing exec ...

[FINE]: Intercepting....instantiating LifecycleInterceptor

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @preExec

[FINE]: intercepting [net.madz.lifecycle.engine.CoreFuntionTestMetadata$InternetServiceOrder@3033e3e0]
from state: [New]
[FINE]: Step 1. start validating State [New]
[FINE]: Step 2. start validating transition: [Start] on state: [New]
[FINE]: Step 3. start validating inbound relation constraint is next state is predictable before method invocation.
[FINE]: Step 4. start callback before state change from : New => to : InService

[FINE]: intercepting with: net.madz.bcel.intercept.CallableInterceptor @intercept

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @postExec

[FINE]: Step 5. start validating inbound relation constraint is next state after method invocation.
[FINE]: Step 6. Set next state to reactiveObject.
[FINE]: Step 6. ReactiveObject is tranisited to state: [InService]
[FINE]: Step 7. Start Callback after state change from : New => to : InService
[FINE]: Step 8. Start fire state change event.

[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @cleanup

[FINE]: Intercepting....LifecycleInterceptor is doing cleanup ...
Finish test: test_standalone_object_with_definite_relation(net.madz.lifecycle.engine.EngineCoreFunctionPositiveTests)
##################################################################################

 

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

分享到:
评论
4 楼 barryzhong 2013-12-12  
kingbo203 写道
Android 平台也实现了一个简易的状态机框架:
框架的定义:
http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java
具体的一个应用
http://androidxref.com/source/xref/packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpStateMachine.java


这种编程模型采用的是最经典的状态模式来构建状态机。在这种编程模型中,为了表达一个状态转移需要应用程序员编写下面类似的代码。

private class HaltingState extends State {
728            @Override
729            public boolean processMessage(Message msg) {
730                mSm.haltedProcessMessage(msg);
731                return true;
732            }
733        }

private class QuittingState extends State {
739            @Override
740            public boolean processMessage(Message msg) {
741                return NOT_HANDLED;
742            }
743        }


这种虽然完全可以表达状态机的语义并且对于生命周期的变化也非常容易扩展。但是存在以下几个缺点:

    [1] 要想观看状态机的全貌,这种表达不是很直观。
    [2] 状态机描述与业务代码的耦合,导致状态机不能重用,这也是把这个状态作为内置类的一个原因。比如若QuittingState根据不同的Message可以去到不同的State,那么业务代码的逻辑判断必须融合到这个QuitingState当中。这个生命周期部分的描述就不可以给其他对象重用。表达方式抽象程度不够。
    [3] 没有改变开发实践,未能在开发实践中突出对象生命周期设计的重要性。倘若将生命周期通过元数据的方式描述同时与业务代码分开,那么在开发实践中,生命周期的设计工作可以跟团队中设计能力较强的同事的来进行,而经验不丰富的同事可以来编写一般意义上的计算逻辑或者业务逻辑。若有生命周期上的调整,直接修改的是元数据的部分,而不是业务代码的部分,当然如果计算逻辑需要调整一定要修改业务代码。这样的好处是可以让生命周期元数据部分受到更好的管控。而不是在某一个业务对象的Java文件里的某一行修改。
    [4] 生命周期回调以及状态变化事件的监听,依然需要采取类似于Observer的方式进行。这也是微妙的控制结构表达的问题。这种编程模型是过去比较流行的,现如今Annotation大行其道,通常为了实现回调功能,过去需要写一个类实现一个接口,而现如今只需要声明一个方法,并添加一个Annotation即可,虽然思想相同,但是表达方式更加的简洁。


Lifecycle的原型在5年前逐渐的演化,从仅仅通过Hash算法进行Transition(转移)的合法性校验,到使用状态模式在processMessage方法中编写更多的业务逻辑。到使用Java Reflection + 动态代理 来进一步简化编程模型,使用元数据描述生命周期,使得生命周期与业务代码分离。再到现如今的通过 Java Instrument在运行时 或者 编译时修改class字节码,以便去掉Java 动态代理必须要求一个接口的多余限制。旨在使得编程模型变得更加简洁。这个路线也是大多数开源软件框架的路线。比如EJB框架,从EJB2.0 必须实现 Home接口和EJB接口,到只需要@Stateless类似的注释即可完成与容器之间的交互。

不过生命周期框架的核心思想是:对于OO设计和编程,要重视生命周期的设计,以减少多年后软件或者软件服务升级所带来的苦恼,包括减少代码量,减少测试代码。从对象与对象的交互出发,通过生命周期这把标尺来设计一个概念的范围,比如一个类的范围,哪些行为哪些属性应该包含在一个概念当中,对象与对象之间的关系也是通过生命周期这把标尺来衡量。

至于表达方式,满足产品本身的性质即可。如果是一个很小的软件,也没有很长的维护周期,那么一个状态模式就已经足够好了。对于复杂的软件,包含很多业务对象,甚至有较深的层级关系,对象与对象之间的关系比较复杂,这个时候采用元数据来描述各自的生命周期以及约束,把生命周期相关的工作交给生命周期引擎完成,就是更好的选择。
3 楼 kingbo203 2013-12-11  
Android 平台也实现了一个简易的状态机框架:
框架的定义:
http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java
具体的一个应用
http://androidxref.com/source/xref/packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
2 楼 barryzhong 2013-11-24  
superdingdang 写道
@Function中的value表达什么意思?


value指的是函数值,是转移函数的函数值。也就是下一个可能的状态的集合。

引用维基百科的关于有限状态自动机的数学模型http://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA#.E6.95.B0.E5.AD.A6.E6.A8.A1.E5.9E.8B
1 楼 superdingdang 2013-11-24  
@Function中的value表达什么意思?

相关推荐

Global site tag (gtag.js) - Google Analytics