构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

因果推断综述-A Survey on Causal Inference 最近读到一篇讲述很全面的综述文献-《A Survey on Causal Inference》,对于接触因果推断不久的同学而言是特别详细的介绍和科普。文献很长,我会分成几部分介绍。 目录 摘要 第一部分:简介 第二部分:因果推断基础知识 第三部分:基于三种假设的因果推断方法 第四部分:实验 第五部分:应用 摘要 几十年来,因果推理是一个跨许多领域的关键研究主题,如统计、计算机科学、教育、公共政策和经济学。与随机对照试验相比,研究方向由于可用数据量大且预算要求低,如今,从观测数据.. 阅读详情

构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)

Author: 孙东风

Date:03/12/2007

        在上一讲中,我们利用MVC+Observer模式设计了移动开发框架。那么,这一节里我们会以一个"媒体播放"为具体实例来实现这个框架。

        首先,可以利用UML建模工具进行如下类的设计:

 

        这个类图对应上节我们所讲解的框架设计。

 

       以下是根据这个类图进行的具体coding:

import javax.microedition.lcdui.Graphics;


public class Controls {
 
 boolean isActive = false;
 
 public Controls()
 {
 
 }
 
 public void draw(Graphics g)
 {
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:09
 */

public class MediaPlayerControl implements MediaPlayerObserver{

 public MediaPlayerView m_view;
 public MediaPlayerModel m_model;
 
 public MediaPlayerControl()
 {
  m_view = new MediaPlayerView();
  m_model = new MediaPlayerModel(this);
 }
 
 public void SreenUpDate()
 {
  m_view.CanvasStatusChange();
 }
}


/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:40:31
 */

public class MediaPlayerModel implements Runnable{

 public MediaPlayerControl m_control;
 Queue tempEventsQueue;
 
 public MediaPlayerModel(MediaPlayerControl control)
 {
  m_control = control;
  tempEventsQueue = MediaPlayerView.eventsQueue;
 }

 public void parseEventsQueue()
 {
  Object event = tempEventsQueue.get();
  int eventID = 0; //event.id;
 
  switch(eventID)
  {
  case 0:
   break;
  case 1:
   break;
  case 2:
   break;
   default:
    break;
  }
 
  m_control.SreenUpDate();
 }
 
 public void run() {
  // TODO Auto-generated method stub
  parseEventsQueue();
 }
 
 
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:34
 */

public interface MediaPlayerObserver {

 public void SreenUpDate();
}

 

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:43
 */

public class MediaPlayerView extends Canvas implements Runnable{

 static Queue controlsQueue;
 
 static Queue eventsQueue;
 
 public MediaPlayerView()
 {
  controlsQueue = new Queue();
 
  if(!initControlsQueue())
   System.out.println("Maybe the ControlsQueue is full!");
 }
 
 public boolean initControlsQueue()
 {
  return controlsQueue.put(new Controls())
    &&controlsQueue.put(new Controls());
  //continue...
 }
 
 protected void CanvasStatusChange()
 {
 
 }
 
 protected void paint(Graphics g) {
  // TODO Auto-generated method stub
 
  for(int i = 0;i < controlsQueue.length();i++)
  {
   Controls tempCon = (Controls)controlsQueue.get();
   if(tempCon != null&& tempCon.isActive)
   {
    tempCon.draw(g);
   }else
   {
    System.out.println("The "+tempCon+" is not activity!");
   }
  }
 
 }

 public void run() {
  // TODO Auto-generated method stub
 
 }
}

 

/**
 *
 * @author jerry.sun
 * @date 2007-11-29 下午12:43:57
 */

public class Queue {
    /** 队列的最大长度 */
    public static final int MAX_SIZE = 32;
    private Object queueArr[] = null;
   
    private int queueHeadId = 0;
    private int queueTailId = 0;
    private int queueLength = 0;
   
    /** 初始化 */
    private void init() {
        queueHeadId = 0;
        queueTailId = 0;
        queueArr = new Object[MAX_SIZE];
        for ( int ii = 0; ii < queueArr.length; ii ++) {
            queueArr[ii] = null;
        }
    }

    /** 取下一个节点的下标 */
    private static int nextID(int id) {
        return ( id + 1  ) % MAX_SIZE;
    }
   
    /** 取前一个节点的下标 */
    private static int preId(int id) {
        return ( id + MAX_SIZE - 1) % MAX_SIZE;
    }
   
    /** 添加一个 obj 到队列,如果队列满,返回false,正常返回true */
    public synchronized boolean put(Object obj) {
        if ( isFull() )
            return false;
        queueArr[queueTailId] = obj;
        queueTailId = nextID(queueTailId);
        queueLength ++;
        return true;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj弹出队列
     */
    public synchronized Object get() {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        queueHeadId = nextID(queueHeadId);
        queueLength --;
        return obj;
    }
   
    /**
     * 队列中取出一个 obj,如果队列空,返回 null
     * 取出的obj不弹出队列
     */
    public synchronized Object getWithoutPop()
    {
        if ( isEmpty())
            return null;
       
        Object obj = queueArr[queueHeadId];
        return obj;
    }
   
    /**
     * 当前队列中Obj个数
     */
    public int length() {
        return queueLength;
    }
   
    /**
     * 是否队列已经满了
     */
    public boolean isFull() {
        return queueLength == queueArr.length;
    }
   
    /**
     * 是否队列是空队列
     */
    public boolean isEmpty() {
        return queueLength == 0;
    }
   
    /** Creates a new instance of Queue */
    public Queue() {
        init();
    }
   
}

 

        其实在一个软件工程的实施中,前期设计是最占用时间的,一旦程序的框架能清晰的给出来。整个项目也就完成了至少60%,剩余的coding就比较简单了。这也是为什么架构师比程序员值钱的原因!呵呵,说了点题外话,希望能对大家有所启发。

       那么这一讲里具体给出了整个程序的框架接口,在剩余的几讲里会具体利用这些框架接口来整合整个项目。还有一些设计的具体细节需要在以后说明,比如前端UI如何设计才能把"耦合度"降低到最低?




联邦学习中的差分隐私保护详解及python实现 随着数据隐私法规(如 GDPR、CCPA)日益严格,传统将数据集中到云端训练模型的方式面临合规与安全风险。联邦学习通过让各客户端保留本地数据,仅共享模型更新,缓解了数据流动带来的隐私风险。但模型更新仍可能泄露个体信息。为进一步保障隐私,可在本地更新中引入差分隐私(DP)机制,通过向梯度或模型更新中注入随机噪声,防止反向推断原始数据citeturn0search9。 阅读详情

相关推荐

Oracle 19c RAC安装踩坑实录:OpenSSH 8.x版本与OUI的“兼容性战争”及一劳永逸的解决思路

本文深入解析Oracle 19c RAC在Linux8环境中部署时遇到的OpenSSH 8.x版本兼容性问题,特别是[INS-06006]错误的根源与解决方案。从协议层分析冲突本质,提供SCP包装器技术、官方补丁应用指南及现代化部署体系构建三种解决方案,帮助企业高效完成RAC安装并规避类似问题。

weixin_42648844的博客 459

MVC模式的好处以及MVC工程初体验

一、MVC模式介绍 模型Model:业务逻辑层,业务流程/状态的处理以及数据模型的制定。 视图View:表示层,与用户实现交互的界面,视图上数据的采集和处理以及用户请求的处理。不能有任何业务逻辑。 控制层Controller:控制层,控制业务流程,让Model和View协调工作。可以看作是一个分发器,不做数据判断、处理,完成所有的请求、流程控制。 MVC的优势:数据和显示分离,有利于松耦合方法的实现(详见松耦合的理解和第一问)。 松耦合的理解:软件设计中的“耦合”指,两个功能函数之间的依赖程度。“松耦合

fanqyoo的博客 506

Simulink单相桥式有源逆变电路仿真:从器件选型到波形分析(MATLAB 2018a实战)

本文基于MATLAB 2018a的Simulink平台,详细演示了单相桥式有源逆变电路的完整仿真流程。从Simscape/Power Systems库的器件选型、参数配置,到触发脉冲设置与电路连接,逐步指导搭建仿真模型。通过调整触发角α,直观展示了电路从整流到有源逆变的工作状态切换,并深入分析了负载电压、电流波形,以及逆变颠覆现象的产生条件与特征。

cake8的博客 1162

Laview MVA框架使用及简单说明

Laview MVA框架使用及简单说明 【下载地址】LaviewMVA框架使用及简单说明 Laview MVA框架是一个基于LabVIEW AF框架的软件架构模式,专注于提高应用程序的模块化和可维护性。通过模型(Model)、视图(View)和适配器(Adapter)三个核心组件的分离与协作,MVA框架为构建复杂且可扩展...

gitblog_06788的博客 1457

有限状态机FSM详解(一)

有限状态机在维基百科中的解释是: 有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。 至于为什么要学FSM,FSM可以把模型的多状态、多状态间的转换条件解耦。可以使维护变得容易,代码也更加具有可读性,也更加艺术。 理解有限状态机首先需要理解整个模型。我们把灯的开关作为示例,...

benjonc的博客 5万+

ESD放电路径分析

当金属外壳接地情况下,大部分外部干扰信号将会通过外壳,外壳到接地点,再由接地点回到干扰信号的地,实现干扰信号的回流,这点不仅仅适用于​ESD,对于其他的RI类干扰,也同样适合。发现内部金属板跟外壳的搭接处存在较多的缝隙点,该缝隙点对于频率较高的信号能够实现较为理想的回流,但是对于频率没有那么高的信号,则较难以实现回流,我们尝试将这些缝隙用铜箔包裹住,充分降低该金属板跟外壳的接触阻抗​。我们分析,路径3其实是不期望的路径,我们最期望的路径是1,或者2的内部金属部件跟外壳良好接触情况下的路径。

domen_pan的博客 2233

labview叠加白噪声_聊聊实时音视频中的技术难点:回声消除+噪声消除

文 | 菊风媒体引擎资深研究团队在各个实时音视频互动场景中,回声和噪声对于影响用户体验而言都是很大的问题。音视频正在发展成为互联网线上沟通的必然趋势,在自然的交流环境中,回声和噪声是非常影响沟通体验的。不论是社交、教育、直播场景中的“疑难杂症”或是智能硬件通话中的“痛点问题”还是银行视频客服和企业视频会议的“严格要求”,都与回声噪音有关,因为人对音频都很敏感,声音一旦有任何瑕疵,人耳都会特别容易感...

weixin_39849930的博客 1009

TongWeb微服务部署实战:Nacos注册与网关路由的疑难解析

本文分享了将Spring Cloud微服务迁移至TongWeb应用服务器时,解决Nacos服务注册失败与Spring Cloud Gateway路由失效的实战经验。针对Nacos注册问题,通过实现ApplicationRunner接口并利用JMX获取容器端口,实现了手动注册;针对网关路由问题,建议将基于WebFlux的Gateway模块改为JAR包独立部署,以保障其原生运行环境。文章为在TongWeb上进行微服务部署提供了关键的问题排查思路与混合架构部署的最佳实践。

weixin_29209801的博客 240

设计模式: Observer 观察者模式

设计模式: Observer 观察者模式 文章目录设计模式: Observer 观察者模式简介从 MVC 到 MVVM参考完整示例代码正文场景模式结构代码示例Subject 可订阅对象/主题Observer 观察者测试代码结语 简介 目的 创建型 结构型 行为型 类 Factory Method 工厂方法 Adapter 适配器 Interpreter 解释器Template Method 模版方法 对象 Abstract Factory 抽象工厂Builder 生成器Prototype

超悠閒的博客 333

5.1 rocr-runtime libhsakmt event 机制全景—从 Doorbell 到 Signal

本文介绍了ROCm/KFD中的Event机制架构,主要解决GPU异步计算中的反馈问题。Event机制分为三层:硬件层触发事件,内核层管理事件通知,用户态接收处理。事件类型分为三大类:同步类事件(如SIGNAL、QUEUE_EVENT)用于任务完成通知,异常类事件(如MEMORY、HW_EXCEPTION)报告错误,拓扑类事件(如NODECHANGE)处理设备变更。该机制通过共享内存和中断实现高效通信,避免CPU轮询开销。后续文章将深入内核实现、Thunk层封装和多队列完成检测实战。

图形/计算GPU的驱动与虚拟化技术分享园地 1308

YOLOv11改进策略【卷积层】| ICCV-2023 LSK大核选择模块 包含二次独家创新

LSK module是。

Limiiiing的博客 1388

国内外LabVIEW开发的区别

​分析国内外在LabVIEW开发中的差异需要从多个方面进行比较,包括界面设计、架构设计、注释与文档、调试方法、维护策略以及升级与迭代管理等。

bjcyck的博客 543

【SI案例分享】1000 BASE-T1共模终端的分析与评估

以太网的MDI接口应用中,共模端接网络的应用广泛,并且,其电路参数从100 BASE-T1到1000 BASE-T1保持了相同的参数定义,这就不得不引起使用者的怀疑,毕竟百兆和千兆以太网的工作频段差异巨大,这样的设计真的可以做到上下兼容吗?本文针对此问题,进行了深入的探讨。

一只豌豆象的博客 1367
上一篇: 基于Java Socket的文件UpLoad代码
下一篇: 构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(一)
techweb
博客等级 码龄19年 226粉丝 3842原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值