心脏起搏器——MVC的一个简单例子

MVC是多种设计模式结合起来的复合模式。

心脏起搏器——MVC的一个简单例子_第1张图片



下面的心脏起搏器是参考《head first设计模式》写得一个mvc小练习。
心脏起搏器——MVC的一个简单例子_第2张图片
代码:

package heart_driver;

public class HeartDriver {
    public static void main(String[] args) {
        new HeartDriver();
    }
	public HeartDriver() {
		Controller controller = new Controller();
		Model model = new Model();
		View view = new View();		
		
		view.setController(controller);
		controller.setModel(model);
		controller.setView(view);
		model.addHeartBeatListener(view);
		
		view.slider.setValue(75);
		model.frequency = 75;
	}

}

Model(以及模型的观察者要实现的接口):

package heart_driver;

import java.util.ArrayList;

interface HeartBeatListener {
	public void onHeartBeat();
}

class Model {

	int frequency;
	boolean on;
	ArrayList<HeartBeatListener> listeners = new ArrayList<>();
	public void addHeartBeatListener(HeartBeatListener listener) {
		listeners.add(listener);
	}
	public void removeHeartBeatListener(HeartBeatListener listener) {
		listeners.remove(listener);
	}
	public void setFrequency(int freq) {
		this.frequency = freq;
	}
	public void on() {
        on = true;
		new Thread(new Runnable() {			
			@Override
			public void run() {
				while(on) {
					for(HeartBeatListener listener : listeners)
						listener.onHeartBeat();
					try {
						Thread.sleep(60000/frequency);
					} catch (InterruptedException e) {}
				}
				
			}
		}).start();		
	}
	public void off() {
		on = false;
	}
}

View: 

package heart_driver;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class View extends JFrame implements HeartBeatListener,ActionListener,ChangeListener {

	Controller controller;
	JButton onButton,offButton;
	JSlider slider;
	JProgressBar bar;

	public View() {
		
		JPanel buttonPanel = new JPanel();
		onButton = new JButton("on");
		offButton = new JButton("off");
		onButton.addActionListener(this);
		offButton.addActionListener(this);
		buttonPanel.add(onButton);
		buttonPanel.add(offButton);
		add(buttonPanel,BorderLayout.NORTH);
		
		bar = new JProgressBar();
		bar.setForeground(Color.RED);
		add(bar,BorderLayout.CENTER);
		
		slider = new JSlider();
		slider.setMaximum(200);
		slider.setMinimum(1);
		slider.setValue(70);
		slider.addChangeListener(this);
		JPanel sliderPanel = new JPanel();
		sliderPanel.add(new JLabel("频率:"));
		sliderPanel.add(slider);
		add(sliderPanel,BorderLayout.SOUTH);
		
		pack();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setTitle("心脏起搏器");
		off();
		setVisible(true);
	}
	public void setController(Controller controller) {
		this.controller = controller;
	}
	public void on() {
		offButton.setEnabled(true);
		onButton.setEnabled(false);
	}
	public void off() {
		offButton.setEnabled(false);
		onButton.setEnabled(true);
	}
	@Override
	public void onHeartBeat() {	
		try {
			for(int i=0;i<bar.getMaximum();i+=bar.getMaximum()/5) {
				bar.setValue(i);
				Thread.sleep(20);			
			}
			for(int i=bar.getMaximum();i>=0;i-=bar.getMaximum()/5) {
				bar.setValue(i);
				Thread.sleep(20);
			}
		} catch (InterruptedException e) {}				
	}
	@Override
	public void stateChanged(ChangeEvent e) {
		int freq = ((JSlider)e.getSource()).getValue();
		controller.setFrequency(freq);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==onButton) 
			controller.on();
		else if(e.getSource()==offButton)
			controller.off();
	}
}

Controller:

package heart_driver;

class Controller {

	View view;
	Model model;
	public void setView(View view) {
		this.view = view;
	}
	public void setModel(Model model) {
		this.model = model;
	}
	public void setFrequency(int freq) {
		model.setFrequency(freq);
	}
	public void on() {
		view.on();
		model.on();
	}
	public void off() {
		view.off();
		model.off();
	}
}

你可能感兴趣的:(设计模式,mvc)