选用了一个假设需要用户验证的例子进行State模式学习,这个例子并不恰当。无所谓了,只要能学习到其中的内容即可。

适用性:

1,一个对象的行为取决于他的状态,并且它必须在运行时刻依据状态改变他的行为。

2,一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用于一个或多个枚举表示。通常,多个操作句包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以依据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而对立变化。

下面的代码只针对于1点,第2点还未研究。

/**

 * state基类

 * @author jevan

 * @version (1.0 at 2013-7-4)

 */

public abstract class State {

    

    

    protected void changeState(Auth a, State state) {

        a.changeState(state);

    };

    

    abstract public boolean doAuth(Auth auth,String path);

}

下面是三个子类:

/**

 * auth之前的本机检查

 * @author jevan

 * @version (1.0 at 2013-7-4)

 */

public class LocalCheckState extends State {

    protected static State instance = null;

    public static State getState() {

        if (instance == null)

            instance = new LocalCheckState();

        return instance;

    }

    /**

     * 检查software的身份id是否有效。

     * @param url

     * @return

     */

    private boolean checkID( ) {

        return true;

    }

    @Override

    public boolean doAuth(Auth auth, String path) {

        //check auth data

        if (!checkID()) {

            return false;

        }

        changeState(auth, NetCheckState.getState());

        return true;

    }

}

/**

 * 认证之前的ping检查

 * @author jevan

 * @version (1.0 at 2013-7-4)

 */

public class NetCheckState extends State {

    protected static State instance = null;

    public static State getState() {

        if (instance == null)

            instance = new NetCheckState();

        return instance;

    }

    /**

     * 本地网络检查

     * 

     * @return

     */

    private boolean isConnect() {

        // 1,检查网卡连接状态

        // 2,检查ip是否有效

        return true;

    }

    /**

     * ping下外网是否可用。

     * 

     * @return

     */

    private boolean isUsed() {

        return true;

    }

    @Override

    public boolean doAuth(Auth auth, String path) {

        if (!isConnect()) {

            return false;

        }

        if (!isUsed()) {

            return false;

        }

        

        changeState(auth, AuthState.getState());

        return true;

    }

}

/**

 * 最终认证类

 * @author jevan

 * @version (1.0 at 2013-7-4)

 */

class AuthState extends State {

    protected static State instance = null;

    public static State getState() {

        if(instance == null)

            instance = new AuthState();

        return instance;

    }

    /**

     * 由给定的url获取数据。

     * @param url

     * @return

     */

    private String getAuthData(String url)

    {

        return "acb";

    }

    

    /* (non-Javadoc)

     * @see State#doAuth(Auth)

     */

    @Override

    public boolean doAuth(Auth auth,String path) {

        

        if(!getAuthData(path).equals("abc"))

        {

            return false;

        }

        return true;

    }

}

auth的认证类:

/**
 * 认证类
 * @author jevan
 * @version (1.0 at 2013-7-4)
 */
public class Auth {
    private State mState;     public Auth()
    {
        mState = LocalCheckState.instance;
    }
    public boolean check()
    {
        mState = LocalCheckState.instance;
        /**
         * 其实可以对State基类进行细分;
         * 网络State、认证State。选取的这个例子并不适合用State模式(子状态太多)。
         */
        mState.doAuth(this, null);
        return true;
    }
    
    public boolean doAuth(String url)
    {
        mState.doAuth(this,url);
        return true;
    }
    
    
    public void changeState(State state)
    {
        mState = state;
    } }

用户类,使用例子:

/**
 * 用户类,使用实例。
 * @author jevan
 * @version (1.0 at 2013-7-4)
 */
public class User {      Auth auth = new Auth();
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        new User().doAuth("www.abc.com/auth");
    }
    
    public  boolean doAuth(String path)
    {
        if(auth.check())
        {
            return false;
        }
        if(!auth.doAuth(path))
        {
            return false;
        }
        return true;
    }
    
}

插入个图:

State模式学习笔记-LMLPHP

05-08 08:35