StateMachine 0.1.1

StateMachine 0.1.1

测试测试
语种语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年5月

Luis Solano维护。



  • Luis Solano Bonet

Objective-C 的状态机库

这个库受到了 Ruby 钻石 state_machine 的启发。

特性

  • 为您的类定义状态机的 DSL
  • 为您的类的实例动态添加方法以触发事件
  • 查询对象是否处于某种状态的方法(isActive, isPending 等)
  • 查询某个事件是否将触发有效转换的方法(canActive, canSuspend 等)
  • 转换回调。在一个转换发生之前和之后执行任意代码。

安装

WIP(请,读:您找出它,然后告诉我)

  • StateMachine 将很快成为一个 CocoaPod
  • 您应该能够将 StateMachine 添加到您源代码树中。如果您正在使用 git,考虑使用 git submodule

用法

定义类的状态机

让我们对一个订阅类进行建模

此时,您负责定义一个状态属性,如下所示。在未来,这将由 StateMachine 处理

@interface Subscription : NSObject
@property (nonatomic, retain) NSString *state; // Property managed by StateMachine

@property (nonatomic, retain) NSDate *terminatedAt;
- (void) stopBilling;
@end

这里是精彩的部分。在类的实现中,我们使用 StateMachine DSL 定义有效的状态和事件。对于每个事件,您定义有效的转换。

DSL 是一个正在进行中的项目,将会改变

您还必须在构造函数中调用 initializeStateMachine,目前是这样。目标是移除这个限制并减少干扰。

@implementation Subscription

STATE_MACHINE(^(LSStateMachine *sm) {
    sm.initialState = @"pending";

    [sm addState:@"pending"];
    [sm addState:@"active"];
    [sm addState:@"suspended"];
    [sm addState:@"terminated"];

    [sm when:@"activate" transitionFrom:@"pending" to:@"active"];
    [sm when:@"suspend" transitionFrom:@"active" to:@"suspended"];
    [sm when:@"unsuspend" transitionFrom:@"suspended" to:@"active"];
    [sm when:@"terminate" transitionFrom:@"active" to:@"terminated"];
    [sm when:@"terminate" transitionFrom:@"suspended" to:@"terminated"];

    [sm before:@"terminate" do:^(Subscription *subscription){
        subscription.terminatedAt = [NSDate dateWithTimeIntervalSince1970:123123123];
    }];

    [sm after:@"suspend" do:^(Subscription *subscription) {
        [subscription stopBilling];
    }];
});

- (id)init {
    self = [super init];
    if (self) {
        [self initializeStateMachine];
    }
    return self;
}

- (void) stopBilling {
    // Yeah, sure...
}

@end

StateMachine 将为您的方法添加触发事件。为了使编译器快乐,您需要告诉它在运行时会有这些方法。您可以通过定义具有一个方法(每个事件一个)和 initializeStateMachine 方法的 Objective-C 类别的头文件来实现这一点。就像这样

@interface Subscription (State)
- (void)initializeStateMachine;
- (BOOL)activate;
- (BOOL)suspend;
- (BOOL)unsuspend;
- (BOOL)terminate;

- (BOOL)isPending;
- (BOOL)isActive;
- (BOOL)isSuspended;
- (BOOL)isTerminated;

- (BOOL)canActivate;
- (BOOL)canSuspend;
- (BOOL)canUnsuspend;
- (BOOL)canTerminate;
@end

如您所见,StateMachine 将定义查询方法来检查对象是否处于某个状态(isPending, isActive 等)以及是否可以触发有效转换(canActivate, canSuspend 等)。

触发事件

现在,您可以使用通常的方式创建类的实例

Subscription *subscription = [[Subscription alloc] init];

它的初始状态是 pending

subscription.state; // @"pending"

您可以触发事件

[subscription activate]; // retuns YES because it's a valid transition
subscription.state; // @"active"

[subscription suspend]; // retuns YES because it's a valid transition
// Method stopBilling was called
subscription.state; // @"suspended"

[subscription terminate]; // retuns YES because it's a valid transition
subscription.state; // @"terminated"
subcription.terminatedAt; // [NSDate dateWithTimeIntervalSince1970:123123123];

如果我们触发一个无效的事件

// The subscription is now suspended
[subscription activate]; // retuns NO because it's not a valid transition
subscription.state; // @"suspended"

参与贡献

  1. 进行Fork
  2. 创建功能分支
  3. 提交您的更改
  4. 将更改推送到分支
  5. 创建新的Pull Request