zoukankan      html  css  js  c++  java
  • java 状态模式 解说演示样例代码

    package org.rui.pattern;
    
    import junit.framework.*;
    
    /**
     * 为了使同一个方法调用能够产生不同的行为,State 模式在代理(surrogate)的
     * 生命周期内切换它所相应的实现(implementation)。当你发现,在决定怎样实现任 对象去耦(Object decoupling)
     * http://blog.csdn.net/lxwde 28 何一个方法之前都必须作非常多測试的情况下,这是一种优化实现代码的方法。比如,
     * 童话故事青蛙王子就包括一个对象(一个生物),这个对象的行为取决于它自己所处 的状态。你能够用一个布尔(boolean)值来表示它的状态,測试程序例如以下:
     * 
     * @author Administrator
     *
     */
    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);
    	}
    } // /:~

    package org.rui.pattern;
    
    import junit.framework.*;
    
    /**
     * 状态模式:改变对象的行为 一个用来改变类的(状态的)对象。 迹象:差点儿全部方法里都出现(同样的)条件(表达式)代码。
     * 
     * 
     * 可是,greet() 方法(以及其他全部在完毕操作之前必须測试 isFrog 值的那些方
     * 法)终于要产生一大堆难以处理的代码。
     * 假设把这些操作都托付给一个能够改变的状 态对象(State object),那代码会简单非常多。
     * 
     * @author Administrator
     *
     */
    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);
    	}
    } // /:~

    package org.rui.pattern;
    
    import org.junit.Test;
    
    import junit.framework.*;
    
    /**
     * 以下的代码演示了 State 模式的基本结构
     */
    
    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),,client能够直接 传对象进来,可是在 KissingPrincess2.java 那个样例里,状态对于client来说是不
     * 可见的。此外,用于改变状态的机制可能非常easy也可能非常复杂-比方本书后面将要提 到的状态机(State
     * Machine),那里会讲到一系列的状态以及改变状态的不同机制。 上面提到 Swing 的 LayoutManager 那个样例非常有趣,它同一时候体现了
     * Strategy 模 式和 State 模式的行为。 Proxy 模式和 State 模式的差别在于它们所解决的问题不同。《设计模式》里是这 么描写叙述
     * Proxy 模式的一般应用的: 1. 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代理。 RMI 编译器(rmic)在创建
     * stubs 和 skeletons 的时候会自己主动为你创建一 个远端代理。 2. 虚代理(Virtual proxy),依据须要,在创建复杂对象时使用
     * “延迟初 始化(lazy initialization)” . 3. 保护代理(protection proxy) 用于你不希望client程序猿全然控制被代
     * 理对象(proxied object)的情况下。 4. 智能引用(smart reference). 当訪问被代理对象时提供额外的动作。
     * 比如,它能够用来对特定对象的引用进行计数,从而实现写时复制 (copy-on-write),进而避免对象别名(object aliasing). 更简单的
     * 一个样例是用来记录一个特定方法被调用的次数。 你能够把 java 里的引用(reference)看作是一种保护代理,它控制对分配在堆
     * (heap)上的实际对象的訪问(并且能够保证你不会用到一个空引用(null reference))。 『重写:在《设计模式》一书里,Proxy 模式和
     * State 模式被觉得是互不相干的, 由于那本书给出的用以实现这两种模式的结构是全然不同的(我觉得这样的实现有点武 断)。尤其是 State
     * 模式,它用了一个分离的实现层次结构,但我觉着全然没有必 要,除非你认定实现代码不是由你来控制的(当然这也是一种可能的情况,可是假设
     * 代码是由你来控制的,那还是用一个单独的基类更简洁有用)。此外,Proxy 模式的实
     * 现不须要用一个公共的基类,由于代理对象仅仅是控制对被代理对象的訪问。虽然有细 节上的差异,Proxy 模式和 State
     * 模式都是用一个代理(surrogate)把方法调用传递 给实现对象。』
     */
    

  • 相关阅读:
    HTML5智能表单
    HTML表单
    CSS文档统筹
    二分查找/折半查找(C++实现)
    实验6:Problem H: 字符串类(II)
    实验6:Problem G: 字符串类(I)
    实验6:Problem F: 时间和日期类(IV)
    实验6:Problem E: 时间和日期类(III)
    实验6:Problem D: 时间和日期类(II)
    实验6:Problem C: 时间和日期类(I)
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3962898.html
Copyright © 2011-2022 走看看