状态机学习及对一段 java 代码的改写

《敏捷软件开发:原则、模式与实践》这本书中的第 29 章讲解了 State 模式,例子是地铁里的十字转门。书中对于状态机的实现,有一个范例是使用迁移表来实现(程序 29.12, P382),这里不列出详细代码。
我在这个例子里面了解到,原来 java 还支持 private interface,并且可以不创建接口的实例,而直接生成一个实现了接口的对象。使用的语法是类似于 C# 里匿名函数一样的内嵌定义语法。

不过,例子中的 interface 定义的作用,仅仅是为了能够方便的创建迁移表,以及在循环遍历迁移表的时候,可以用一致的语法去调用方法。这可不就是 C# 的 delegate 所起的作用吗?
因此我用 C# 语法重写了这个例子,由于使用了 delegate,代码减少了大概一半。

记得在网上也看到有不少说法称 C# 中 delegate 的设计违反了 OO 的设计原则,但是从这个例子中我们可以看到,delegate 确实非常方便,在某些情况下可以大幅度简化设计,相比而言原书上的 java 程序例子,在一个 class 内部定义 private interface,然后再定义其实现,导致了很多只有一句话的代理方法,感觉非常臃肿和复杂。最主要是这里的 interface 定义是 private 的,变得毫无疑义。因此用 delegate 语法替换是一种便捷而无害的做法。

思考:并非纯粹 OO 的语言就是最好的语言,很多场景下,OO 跟过程式混合使用会带来更高的生产力。比如 python 和 delphi 就都支持这样的特性。

附 C# 的实现代码:

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  StateMachine1
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            TurnstileController controller 
=   new  TurnstileController();
            Turnstile turn 
=   new  Turnstile(controller);

            turn.DoEvent(Event.Coin);
            turn.DoEvent(Event.Coin);
            turn.DoEvent(Event.Pass);
            turn.DoEvent(Event.Pass);

            Console.ReadLine();
        }
    }

    
public   enum  State
    {
        Locked,
        Unlocked
    }

    
public   enum  Event
    {
        Coin,
        Pass
    }

    
public   class  TurnstileController
    {
        
public   void  Lock()
        {
            Console.WriteLine(
" Lock " );
        }

        
public   void  Unlock()
        {
            Console.WriteLine(
" Unlock " );
        }

        
public   void  Alarm()
        {
            Console.WriteLine(
" Alarm " );
        }

        
public   void  ThankYou()
        {
            Console.WriteLine(
" ThankYou " );
        }
    }

    
public   class  Turnstile
    {
        State state 
=  State.Locked;

        
//  这个属性暴露出来是为了让测试类获取或设定十字转门的初始状态
         public  State State
        {
            
get  {  return  state; }
            
set  { state  =  value; }
        }

        
private  TurnstileController controller;

        
//  用 delegate 代替 java 的 private interface 实现
         private   delegate   void  Action();

        
//  表示状态迁移表的一个条目
         private   class  Transition
        {
            
public  State CurrentState;
            
public  Event Event;
            
public  State NewState;
            
public  Action Action;

            
public  Transition(State currentState, Event evt, State newState, Action action)
            {
                
this .CurrentState  =  currentState;
                
this .Event  =  evt;
                
this .NewState  =  newState;
                
this .Action  =  action;
            }
        }

        
private  List < Transition >  transitions  =   new  List < Transition > ();

        
public  Turnstile(TurnstileController controller)
        {
            
this .controller  =  controller;

            
//  构造状态迁移表
            AddTransition(State.Locked, Event.Coin, State.Unlocked,  new  Action(controller.Unlock));
            AddTransition(State.Locked, Event.Pass, State.Locked, 
new  Action(controller.Alarm));
            AddTransition(State.Unlocked, Event.Coin, State.Unlocked, 
new  Action(controller.ThankYou));
            AddTransition(State.Unlocked, Event.Pass, State.Locked, 
new  Action(controller.Lock));
        }

        
private   void  AddTransition(State currentState, Event evt, State newState, Action action)
        {
            transitions.Add(
new  Transition(currentState, evt, newState, action));
        }

        
///   <summary>
        
///  处理事件
        
///   </summary>
        
///   <param name="evt"></param>
         public   void  DoEvent(Event evt)
        {
            
foreach  (Transition tran  in  transitions)
            {
                
if  (state  ==  tran.CurrentState  &&  evt  ==  tran.Event)
                {
                    state 
=  tran.NewState;
                    tran.Action.Invoke();

                    
//  原书遗漏这个操作
                     break ;
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值