[转载]MVC模式简单讲解 – 设计模式 – Java – JavaEye论坛.
意图
最终目标就是:分离视图和模型,让多个视图可以共用一个模型
类图
时序图
Test
- package mvc;
- /**
- * MVC模式,最终目标就是:分离视图和模型,让多个视图可以共用一个模型
- * alex295111
- * 2010-8-5
- */
- public class Test {
- public static void main(String[] args){
- /* 模型可以重用*/
- IModel model = new ModelImpl();
- ViewTextAndControl viewText = new ViewTextAndControl();
- IController controller = new Controller();
- /*视图要委托给控制器处理请求,所以需要有个控制器的引用*/
- viewText.setController(controller);
- /*控制器选择模型去处理业务逻辑,所以需要有个模型的引用*/
- controller.setModel(model);
- /*为模型注册观察者,当模型变化时,及时通知给观察者*/
- model.registerObserver(viewText);
- ViewHtml viewHtml = new ViewHtml();
- /*这个html视图,只接受模型的数据
- IController controller2 = new Controller();
- viewHtml.setController(controller2);
- controller2.setModel(model);
- */
- model.registerObserver(viewHtml);
- /*模拟视图层的操作*/
- Test t = new Test();
- t.test(viewText);
- }
- private void test(ViewTextAndControl v){
- v.start(100);
- try {
- Thread.sleep(1000);
- v.add();
- Thread.sleep(1000);
- v.add();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
IModel
- package mvc;
- /**
- * 模型接口,被观察者
- * alex295111
- * 2010-8-5
- */
- public interface IModel {
- public void start(int startCount);
- public void stop();
- public void add();
- public int getCount();
- public void registerObserver(Observer observer);
- public void removeObserver(Observer observer);
- }
ModelImpl
- package mvc;
- import java.util.ArrayList;
- import java.util.Iterator;
- /**
- * 模型层实现
- * alex295111
- * 2010-8-5
- */
- public class ModelImpl implements IModel {
- private int count;
- private ArrayList observers = new ArrayList();
- public void add() {
- count++;
- notifyObservers();
- }
- public int getCount() {
- return count;
- }
- public void registerObserver(Observer observer) {
- observers.add(observer);
- }
- public void removeObserver(Observer observer) {
- if(observers.indexOf(observer)<0){
- observers.remove(observer);
- }
- }
- public void start(int startCount) {
- count = startCount;
- notifyObservers();
- }
- private void notifyObservers(){
- for(Iterator it = observers.iterator(); it.hasNext();){
- Observer observer = (Observer) it.next();
- observer.update(this);
- }
- }
- public void stop() {
- }
- }
IController
- package mvc;
- /**
- * 控制器接口
- * alex295111
- * 2010-8-5
- */
- public interface IController {
- /**开始计数器*/
- public void start(int startCount);
- /** 停止计数器*/
- public void stop();
- /**数值增加*/
- public void add();
- public void setModel(IModel model);
- }
Controller
- package mvc;
- /**
- * 控制器选择模型去处理业务逻辑,所以需要有个模型的引用
- * alex295111
- * 2010-8-5
- */
- public class Controller implements IController{
- private IModel model;
- public void add() {
- model.add();
- }
- public void start(int startCount) {
- model.start(startCount);
- }
- public void stop() {
- }
- public void setModel(IModel model) {
- this.model = model;
- }
- }
Observer
- package mvc;
- /**
- * 观察者接口,在这里主要供给视图实现,因为视图要及时反映模型的状态
- * alex295111
- * 2010-8-5
- */
- public interface Observer {
- public void update(IModel model);
- }
ViewTextAndControl(视图1)
- package mvc;
- /**
- * 视图,处理展现还带有控制功能
- * 视图持有模型层和控制层引用
- * 将请求委托给控制器,由控制器决定使用哪个模型处理该请求
- * alex295111
- * 2010-8-5
- */
- public class ViewTextAndControl implements Observer {
- private IController controller;
- public void setController(IController controller) {
- this.controller = controller;
- }
- /*启动计数器*/
- public void start(int startCount){
- controller.start(startCount);
- }
- /*计数器加1*/
- public void add(){
- controller.add();
- }
- public void update(IModel model) {
- System.out.println(“我是文本格式ViewText:刚刚获得模型层数据count:”+model.getCount());
- }
- }
ViewHtml(视图2)
- package mvc;
- /**
- * html形式的视图,只接收数据
- * alex295111
- * 2010-8-5
- */
- public class ViewHtml implements Observer {
- public void update(IModel model) {
- System.out.println(“<h1>我是Html格式View2,刚刚获得模型层数据count:”+model.getCount()+“</h1>”);
- }
- }
以下为了有个用户界面,添加了个Swing视图ViewSwingAndControl(视图3)
- package mvc_swing;
- import java.awt.FlowLayout;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JTextField;
- public class ViewSwingAndControl implements Observer {
- private IController controller;
- public void setController(IController controller) {
- this.controller = controller;
- }
- private JFrame frame = new JFrame(“我是swing视图”);
- private JTextField countField = new JTextField(“count暂无值”);
- private JButton startButton = new JButton(“开始”);
- private JButton addButton = new JButton(“+1”);
- public ViewSwingAndControl(){
- frame.setLayout(new FlowLayout());
- frame.add(countField);
- frame.add(startButton);
- frame.add(addButton);
- frame.setLocation(500, 300);
- frame.setSize(200,200);
- frame.setVisible(true);
- addListener();
- setAddButtonDisable();
- }
- public void addListener(){
- startButton.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e) {
- controller.start(100);
- setAddButtonEnable();
- }
- });
- addButton.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e) {
- controller.add();
- }
- });
- }
- public void setAddButtonDisable(){
- this.addButton.setEnabled(false);
- }
- public void setAddButtonEnable(){
- this.addButton.setEnabled(true);
- }
- public void update(IModel model) {
- countField.setText(Integer.toString(model.getCount()));
- }
- }
Test
- package mvc_swing;
- /**
- * MVC模式,最终目标就是:分离视图和模型,让多个视图可以共用一个模型
- * alex295111
- * 2010-8-5
- */
- public class Test {
- public static void main(String[] args){
- /* 模型可以重用*/
- IModel model = new ModelImpl();
- ViewTextAndControl viewText = new ViewTextAndControl();
- IController controller = new Controller();
- /*视图要委托给控制器处理请求,所以需要有个控制器的引用*/
- viewText.setController(controller);
- /*控制器选择模型去处理业务逻辑,所以需要有个模型的引用*/
- controller.setModel(model);
- /*为模型注册观察者,当模型变化时,及时通知给观察者*/
- model.registerObserver(viewText);
- /*创建一个swing视图*/
- ViewSwingAndControl viewSwing = new ViewSwingAndControl();
- IController controller2 = new Controller();
- viewSwing.setController(controller2);
- controller2.setModel(model);
- model.registerObserver(viewSwing);
- ViewHtml viewHtml = new ViewHtml();
- /*这个html视图,只接受模型的数据
- IController controller2 = new Controller();
- viewHtml.setController(controller2);
- controller2.setModel(model);
- */
- model.registerObserver(viewHtml);
- /*模拟视图层的操作*/
- /*
- Test t = new Test();
- t.test(viewText);
- */
- }
- private void test(ViewTextAndControl v){
- v.start(100);
- try {
- Thread.sleep(1000);
- v.add();
- Thread.sleep(1000);
- v.add();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }