关于JAVA中状态设计模式的讲解示例代码

为了使同一个方法调用可以产生不同的行为,State 模式在代理(surrogate)的生命周期内切换它所对应的实现(implementation)。当你发现,在决定如何实现任何一个方法之前都必须作很多测试的情况下,这是一种优化实现代码的方法。     --     对象去耦(Object decoupling)

例如:童话故事青蛙王子就包含一个对象(一个生物),这个对象的行为取决于它自己所处 的状态。你可以用一个布尔(boolean)值来表示它的状态,测试程序如下:

import junit.framework.*;

/**
 *@author focusClouds
 */
class Creature  {  
    private boolean isFrog = true;  
  
    public void greet()  
    {  
        if (isFrog)  
            System.out.println("Ribbet!");  
        else  
            System.out.println("Darling!");  
    }  
  
    public void kiss()  
    {  
        isFrog = false;  
    }  
}

public class KissingPrincess extends TestCase  {  
    Creature creature = new Creature();  
  
    public void test()  
    {  
        creature.greet();  
        creature.kiss();  
        creature.greet();  
    }  
  
    public static void main(String args[])  
    {  
        junit.textui.TestRunner.run(KissingPrincess.class);  
    }  
} // /:~  

状态模式:改变对象的行为, 一个用来改变类的(状态的)对象。
迹象:几乎所有方法里都出现(相同的)条件(表达式)代码。但是,greet() 方法(以及其它所有在完成操作之前必须测试 isFrog 值的那些方法)最终要产生一大堆难以处理的代码。   如果把这些操作都委托给一个可以改变的状 态对象(State object),那代码会简单很多。

import junit.framework.*;

/**
 *@author focusClouds
 */
class Creature2  {  
  
    private interface State  
    {  
        String response();  
    }  
  
    private class Frog implements State  
    {  
        public String response()  
        {  
            return "Ribbet!";  
        }  
    }  
  
    private class Prince implements State  
    {  
        public String response()  
        {  
            return "Darling!";  
        }  
    }  
  
    private State state = new Frog();  
  
    public void greet()  
    {  
        System.out.println(state.response());  
    }  
  
    public void kiss()  
    {  
        // 改变对象状态  
        state = new Prince();  
    }  
}

public class KissingPrincess2 extends TestCase  
{  
    Creature2 creature = new Creature2();  
  
    public void test()  
    {  
        creature.greet();  
        creature.kiss();  
        creature.greet();  
    }  
  
    public static void main(String args[])  
    {  
        junit.textui.TestRunner.run(KissingPrincess2.class);  
    }  
} // /:~
下面的代码演示了 State 模式的基本结构:
import org.junit.Test;  
import junit.framework.*;

/**
 *@author focusClouds
 */
interface State  {  
    void operation1();  
  
    void operation2();  
  
    void operation3();  
}

class ServiceProvider  {  
    private State state;  
  
    public ServiceProvider(State state)  
    {  
        this.state = state;  
    }  
  
    public void changeState(State newState)  
    {  
        state = newState;  
        System.out.println("========changeState==========="  
                + newState.getClass().getSimpleName());  
    }  
  
    // 通过方法调用实现  
    public void service1()  
    {  
        // ...  
        state.operation1();  
        // ...  
        state.operation3();  
    }  
  
    public void service2()  
    {  
        // ...  
        state.operation1();  
        // ...  
        state.operation2();  
    }  
  
    public void service3()  
    {  
        // ...  
        state.operation3();  
        // ...  
        state.operation2();  
    }  
}

class Implementation1 implements State  {  
    public void operation1()  
    {  
        System.out.println("Implementation1.operation1()");  
  
    }  
  
    public void operation2()  
    {  
        System.out.println("Implementation1.operation2()");  
    }  
  
    public void operation3()  
    {  
        System.out.println("Implementation1.operation3()");  
    }  
}

class Implementation2 implements State  {  
    public void operation1()  
    {  
        System.out.println("Implementation2.operation1()");  
    }  
  
    public void operation2()  
    {  
        System.out.println("Implementation2.operation2()");  
    }  
  
    public void operation3()  
    {  
        System.out.println("Implementation2.operation3()");  
    }  
}

public class StateDemo extends TestCase  {  
    static void run(ServiceProvider sp)  
    {  
        sp.service1();  
        sp.service2();  
        sp.service3();  
    }  
  
    ServiceProvider sp = new ServiceProvider(new Implementation1());  
  
    @Test  
    public void test()  
    {  
        run(sp);  
        sp.changeState(new Implementation2());  
        run(sp);  
    }  
  
    /*  
     * public static void main(String args[]) {  
     * junit.textui.TestRunner.run(StateDemo.class); }  
     */  
} // /:~ 

在 main( )函数里,先用到的是第一个实现,然后转入第二个实现。 当你自己实现 State 模式的时候就会碰到很多细节的问题,你必须根据自己的需要选择合适的实现方法,比如用到的状态(State)是否要暴露给调用的客户,以及如 何使状态发生变化。有些情况下(比如 Swing 的LayoutManager),客户端可以直接传对象进来,但是在KissingPrincess2.java 那个例子里,状态对于客户端来说是不可见的。
此外,用于改变状态的机制可能很简单也可能很复杂-比如状态机制(State Machine),那里会讲到一系列的状态以及改变状态的不同机制。 上面提到 Swing 的 LayoutManager 那个例子非常有趣,它同时体现了Strategy 模 式和 State 模式的行为。Proxy 模式和 State 模式的区别在于它们所解决的问题不同。《设计模式》里是这 么描述的。
Proxy 模式的一般应用的:
1> 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代理。 RMI 编译器(rmic)在创建 stubs 和 skeletons 的时候会自动为你创建一 个远端代理。

2> 虚代理(Virtual proxy),根据需要,在创建复杂对象时使用
“延迟初 始化(lazy initialization)” 。
3> 保护代理(protection proxy) 用于你不希望客户端程序员完全控制被代
理对象(proxied object)的情况下。
4> 智能引用(smart reference). 当访问被代理对象时提供额外的动作。
例如:
它可以用来对特定对象的引用进行计数,从而实现写时复制 (copy-on-write),进而避免对象别名(object aliasing)。 更简单的一个例子是用来记录一个特定方法被调用的次数。 你可以把 java 里的引用(reference)看作是一种保护代理,它控制对分配在堆(heap)上的实际对象的访问(而且可以保证你不会用到一个空引用(null reference))。 『重写:在《设计模式》一书里,Proxy 模式和State 模式被认为是互不相干的, 因为那本书给出的用以实现这两种模式的结构是完全不同的(我认为这种实现有点武 断)。尤其是 State模式,它用了一个分离的实现层次结构,但我觉着完全没有必 要,除非你认定实现代码不是由你来控制的(当然这也是一种可能的情况,但是如果代码是由你来控制的,那还是用一个单独的基类更简洁实用)。此外,Proxy 模式的实现不需要用一个公共的基类,因为代理对象只是控制对被代理对象的访问。尽管有细 节上的差异,Proxy 模式和 State模式都是用一个代理(surrogate)把方法调用传递 给实现对象。』






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值