Java ME Canvas基础应用程式的设计样式

这一篇是我在Design Pattern for Java ME Canvas based applications的中文翻译,总共翻译了15天,中间虽然夹杂着更改工作达人的布景,不过仍算是久的了,网址在Java ME Canvas基础应用程式的设计样式
为了备份,并转贴在此:

问题

每个使用Java ME工作的人必定会碰到在切换可显示的物件时这个“一闪而过(flicker)”的问题,例如从已经在View的一个画布设定一个新的画布,你会仔细想过 可显示的画布不应该一次又一次地设定,我们在整个应用程式中应该只使用一个画布设定,而这样会产生一个长期不可管理的Canvas类别,这个类别会有很长 的键盘按下/释放、绘制方法及一堆的Switch case / if then else等等,这样可会影响程式的效率及可读性。

解决方案

我们必须以这样的一个方式设计一个解决方案,这个方案就是只有一个Canvas(BaseCanvas – 键下面的程式码)只有一次被midlet设为目前可显示的,且对不同的应用程式模组使用物件导向方法来建构不同的Canvas荧幕,这些模组可以藉由一个 共同的介面类别物件在BaseCanvas传递而不用flicker,每个荧幕处理绘制及式键的程式码用这样不同的荧幕类别来分隔,这样可因此变得较易阅 读及效率。

优点

  • 容易扩展
  • 教友效率的程式码
  • 较可阅读的程式码
  • 较低的记忆体占用

程式码

BaseCanvas会在下面

import javax.microedition.lcdui.*;
public class BaseCanvas extends Canvas
{
        /**Singleton Instance**/
        private static BaseCanvas mCanvas;

        /** Singleton Accessor Method with lazy initialization**/
        public static Canvas getCanvas()
        {if(mCanvas==null)
               mCanvas=new BaseCanvac();
         return mCanvas;
        }

        public CanvasScreen setCurrentScreen(CanvasScreen aCs)
        {
                 CanvasScreen old=mCs;
                 mCs=aCs;
                 return old;
        }

	public void paint(Graphics g)
	{
		if(null!=mCs) mCs.paint(g);
	}

	public void keyPressed(int keyCode)
	{
		if(null!=mCs) mCs.keyPressed(keyCode);
	}

	public void keyRepeated(int keyCode)
	{
		if(null!=mCs) mCs.keyRepeated(keyCode);
	}

        /**Stratergy Object **/
	private CanvasScreen mCs=null;

	private BaseCanvas()
	{
		setFullScreenMode(true);
	}
}

CanvasScreen介面会在下面

import javax.microedition.lcdui.*;
public interface CanvasScreen
{
	public void paint(Graphics g);
	public void keyPressed(int keyCode);
	public void keyRepeated(int keyCode);
}

所有应用程式不同的模组的其他荧幕或canvas类别会在下面
(例如,SplashScreen)

import javax.microedition.lcdui.*;
public class SplashScreen implements CanvasScreen
{
	BaseCanvas bc;
	public SplashScreen()
	{
		this.bc=BaseCanvas.getCanvas();
                bc.setCurrentScreen(this);
                // do what you want to paint on splash screen and load your assests.
	}

	public void keyRepeated(int keyCode){ }

	public void paint(Graphics g)
	{
		// paint your Splash Screen
		// paint Loader(g);			
	}

	public void keyPressed(int keyCode)
	{
                // do what you need
	}

	private void repaint()
	{
		bc.repaint();
	}
}

所有其他的荧幕类别将实做CanvasScreen介面,来执行他们自己的绘制及事件处理。

执行绪的安全

上面所说的存取BaseCanvas类别不是执行绪安全,不同执行绪的同时存取会造成不可预测的结果,所以假如一个应用程式从不同的执行绪存取这个类别那么存取它应该是同步的。

–Linux achi于2009/9/15 15:38翻译.