基于PhoneBook的MVC模式学习

  MVC设计模式,即模型-视图-控制的设计模式,下面的这个例子是MVC模式在用户界面导航开发中所应用的开发框架,在下面这个例子中,将以电话簿为例,这个基于MIDlet的电话薄应用允许用户浏览,添加,编辑和删除联系人。

因为这个例子中MIDlet类在生命周期内只有一个实例,所以让其类实现Controller接口。

  首先,定义我们需要的数据类型,即联系人Entry类:

public class Entry
{
 private static int id_seq=0;
 
 private int id;
 private String name;
 private String mobile;
 private String phone;
 private String email;
 
 private static int nextID()
 {
  id_seq++;
  return id_seq;
 }
 
 public Entry(String name,String mobile,String phone,String email)
 {
  this.id =nextID();
  this.name=name;
  this.mobile=mobile;
  this.phone=phone;
  this.email=email;
 }
 
 public int getID()
 {
  return id;
 }
 //工厂模式
 public String getName()
 {
  return name;
 }
  public void setName(String updateName)
 {
  name=updateName;
 }

.......

.......
 
 
 public boolean equal(Object obj)
 {
  if(obj==this)
   return true;
  if(obj instanceof Entry)
  {
   return ((Entry)obj).id ==this.id;
  }
  return false;
 
 }
 public int hashCode()
 {
  return id;
 }
}

在定义了需要的数据Entry后,我们在Model类实现对Entry的管理,Model类

public class Model
{
 private Vector entries=new Vector();
 
 //添加联系人
 public void addEntry(Entry e)
 {
  entries.addElement(e);
 }
 
 //读取联系人信息
 public Entry getEntry(int index)
 {
  return (Entry)entries.elementAt(index);
 }
 
 //更新联系人信息
 public void updateEntry(Entry e)
 {
  for(int i=0;i<entries.size();i++)
  {
   Entry entry=(Entry)entries.elementAt(i);
   if(entry.getID()==e.getID())
   {
    entry.setE_mail(e.getE_mail());
    entry.setmobile(e.getMobile());
    entry.setName(e.getName());
    entry.setPhone(e.getPhone());
    return;
   }
  }
 
 }
 
 //读取所有联系人
 public Entry [] getAll()
 {
  Entry [] ret=new Entry[entries.size()];
  entries.copyInto(ret);
  return ret;
 }
 
 //返回联系人个数
 public int size()
 {
  return entries.size();
 }
 
 //删除联系人
 public void removeEntry(Entry entry)
 {
  for(int i=0;i<entries.size();i++)
  {
   Entry e=(Entry)entries.elementAt(i);
   if(e.getID()==entry.getID())
   {
    entries.removeElementAt(i);
    return ;
   }
  }
 }
}

对于控制类Controller我们先定义为接口类型,并定义各种命令按钮,函数void handleCommand(int Command,Object obj)让实现了该接口的类具体这个方法:
public interface Controller
{
  //定义各种命令含义
  static final int SHOW_ADD_ENTRY=0;
  static final int SHOW_EDIT_ENTRY=1;
  static final int SHOW_LIST_ENTRY=2;
  static final int SHOW_DETAIL_ENTRY=3;
  static final int DO_ADD_ENTRY=4;
  static final int DO_UPDATE_ENTRY=5;
  static final int DO_REMOVE_ENTRY=6;
  static final int DO_EXIT=7;
  static final int OK=8;
  static final int Back=9;
 
  void handleCommand(int Command,Object obj);
}

现在我们让MIDlet这个类实现这个接口,并具体化接口的方法,实现不同视图的切换:

public  class PhoneBook extends MIDlet implements Controller
{
 private Display display=null;
 //模型类
 private Model model;
 //视图类
 private AddEntryUI addentryUI;
 private DetailUI detailUI;
 private EditEntryUI editEntry;
 private ListEntryUI listEntryUI;
 
 
 public PhoneBook() {
  // TODO 自动生成构造函数存根
  super();
  display=Display.getDisplay(this);
  model=new Model();
  addentryUI=new AddEntryUI(this);
  detailUI=new DetailUI(this);
  editEntry=new EditEntryUI(this);
  listEntryUI= new ListEntryUI(this);
 }
 protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
  // TODO 自动生成方法存根

 }

 protected void pauseApp() {
  // TODO 自动生成方法存根

 }

 protected void startApp() throws MIDletStateChangeException {
  // TODO 自动生成方法存根
  Entry [] all=model.getAll();
  listEntryUI.load(all);
  display.setCurrent(listEntryUI);
  handleCommand(Controller.SHOW_ADD_ENTRY,null);

 }
 
 public void handleCommand(int Command,Object obj)
 {
  switch(Command)
  {
  case Controller.SHOW_LIST_ENTRY:
   show(listEntryUI);
   break;
  case Controller.SHOW_ADD_ENTRY:
  {
   addentryUI.clear();
   show(addentryUI);
  }break;
  case Controller.DO_ADD_ENTRY:
  {
   model.addEntry((Entry)obj);
   refresh();
   show("号码添加完成", listEntryUI);
  }break;
  case Controller.SHOW_EDIT_ENTRY:
  {
   editEntry.load((Entry)obj);
   show(editEntry);
  
  }break;
  case Controller.DO_UPDATE_ENTRY:
  {
   Entry e=(Entry)obj;
   model.updateEntry(e);
   refresh();
   show("信息已更新",listEntryUI);
  
  }break;
  case Controller.SHOW_DETAIL_ENTRY:
  {
   detailUI.load((Entry)obj);
   show(detailUI);
  }
  break;
  case Controller.Back:
  {
   show(listEntryUI);
  }break;
  case Controller.DO_REMOVE_ENTRY:
  {
   model.removeEntry((Entry)obj);
   refresh();
   show("删除成功",listEntryUI);
  }break;
  case Controller.DO_EXIT:
  {
   try {
    destroyApp(true);
   } catch (MIDletStateChangeException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
   }
            notifyDestroyed();
  }
  break;
  default:;
 
  }
 }
 
// 提示信息
    private void show(String msg, Displayable d) {
           }
 //更新联系人界面
 private void refresh() {
          }
 private void show(Displayable d)
 {
  }

}

最后对于各种不同的视图类,我们可以根据需要实现:

编辑视图(EditEntryUI):
public class EditEntryUI extends Form implements CommandListener
{
  private Command cmdOK=new Command("确定",Command.OK,1);;
  private Command cmdCancel=new Command("返回",Command.BACK,1);;
 
  private Entry entry;
 
  private Controller controller;
 
  private TextField name = new TextField("姓 名:", "", 20, TextField.ANY);
  private TextField mobile = new TextField("移动电话:", "", 20, TextField.PHONENUMBER);
  private TextField phone = new TextField("固定电话:", "", 20, TextField.PHONENUMBER);
  private TextField email = new TextField("电子信箱:", "", 20, TextField.EMAILADDR);
 
  public EditEntryUI(Controller controller)
  {
   super("编辑联系人");
   this.controller=controller;
   this.append(name);
   ..............

   this.addCommand(cmdOK);
   this.addCommand(cmdCancel);
   this.setCommandListener(this);
  
  }
 
  public void load(Entry e)
  {
   .........

   ................

     .....................
  }
 
  public void commandAction(Command c,Displayable d)
  {
   if(c==cmdOK)
   {
    ......

    ..............

    ...................
   }
   if(c==cmdCancel)
   {

        ...............
         }
  }
}

其他视图:

ListEntryUI
AddEntryUI

DetailUI

    总结:对于MVC模式用于导航界面的框架,让程序更易于维护,并且很容易添加新的界面而不影响Model类,但是这种模式使得对每一个事件都需要一个唯一的标记,而且控制器中的switch-case语句会随着界面的增加而增加变得难以维护,还有Controller类引用了所有的View类,使得在程序启动的时候就被初始化,导致了较大开销。

你可能感兴趣的:(基于PhoneBook的MVC模式学习)