1. 程式人生 > >《Head First 設計模式》學習筆記——復合模式

《Head First 設計模式》學習筆記——復合模式

listener 解讀 out 部件 register != file 窗體 event

模型-視圖-控制器(MVC模式)是一種很經典的軟件架構模式。在UI框架和UI設計思路中扮演著很重要的角色。從設計模式的角度來看,MVC模式是一種復合模式。它將多個設計模式在一種解決方式中結合起來,用來解決很多設計問題。MVC模式把用戶界面交互分拆到不同的三種角色中,使應用程序被分成三個核心部件:Model(模型)、View(視圖)、Control(控制器)。————題記
設計模式 復合模式:結合兩個或以上的模式,組成一個解決方式,解決一再發生的一般性問題。如MVC和Model 2
模型-視圖-控制器 模型:模型持有全部的數據、狀態和程序邏輯。模型沒有註意到視圖和控制器。盡管他提供了操縱和檢索狀態的接口。並發送狀態改變給觀察者。 控制器:取得用戶的輸入並解讀其對模型的意思。

視圖:用來呈現模型,視圖通常直接從模型中取得它須要顯示的狀態和數據。 從模式角度看: 模型利用“觀察者”讓控制器和視圖能夠隨最新的狀態改變而更新。 還有一方面。視圖和控制器則實現了“策略模式”。

控制器是視圖的行為。假設你希望有不同的行為。能夠直接換一個控制器。 視圖內部使用組合模式管理窗體、button以及其它顯示組件。
MVC與WEB——Model 2 Web開發者也都在適配MVC,使他符合瀏覽器/server模型。使用Servlet和JSP技術的組合。達到MVC的分離效果。就像傳統的GUI。

(1)客戶發出一個會被Servlet收到的HTTP請求。

(2)Servlet扮演控制器,處理請求。一般會向模型(通常是數據庫)發出請求。處理結果往往以JavaBean的形式打包。 (3)控制器將控制權交給視圖JSP。

JSP的唯一工作就是產生頁面表現模型的視圖,以及進一步動作所須要的全部控件。

(4)視圖通過HTTP將頁面返回瀏覽器。

//MVC
//模型
public interface BeatModelInterface {
	//這些方法讓控制器調用。控制器依據用戶的操作對模型做出適當的處理
	void initialize();
	void on();
	void off();
	void setBPM(int bpm);

	//這些方法同意視圖和控制器取得狀態,而且成為觀察者。
	int getBPM();
	void registerObserver(BeatObserver o);
	void removeObserver(BeatObserver o);
	void registerObserver(BPMObserver o);
	void removeObserver(BPMObserver o);
}

public class BeatModel implements BeatModelInterface, MetaEventListener {
	Sequencer sequencer;
	//兩種觀察者。一種觀察節拍,一種觀察BPM變化
	ArrayList<BeatObserver> beatObservers = new ArrayList<BeatObserver>();
	ArrayList<BPMObserver> bpmObservers = new ArrayList<BPMObserver>();
	int bpm = 90;
	Sequence sequence;
	Track track;

	public void initialize() {
		setUpMidi();
		buildTrackAndStart();
	}

	public void on() {
		sequencer.start();
		setBPM(90);
	}

	public void off() {
		setBPM(0);
		sequencer.stop();
	}

	public void setBPM(int bpm) {
		this.bpm = bpm;
		sequencer.setTempoInBPM(getBPM());
		notifyBPMObservers();
	}

	public int getBPM() {
		return bpm;
	}

	void beatEvent() {
		notifyBeatObservers();
	}

	//註冊觀察者、通知觀察者的代碼
	
	//處理節拍的MIDI代碼
}

//視圖
public class DJView implements ActionListener, BeatObserver, BPMObserver {
	//視圖持有模型和控制器的引用
	BeatModelInterface model;
	ControllerInterface controller;
	//顯示控制button
	JFrame viewFrame;
	JPanel viewPanel;
	BeatBar beatBar;
	JLabel bpmOutputLabel;
	JFrame controlFrame;
	JPanel controlPanel;
	JLabel bpmLabel;
	JTextField bpmTextField;
	JButton setBPMButton;
	JButton increaseBPMButton;
	JButton decreaseBPMButton;
	JMenuBar menuBar;
	JMenu menu;
	JMenuItem startMenuItem;
	JMenuItem stopMenuItem;

	public DJView(ControllerInterface controller, BeatModelInterface model) {
		this.controller = controller;
		this.model = model;
		model.registerObserver((BeatObserver) this);
		model.registerObserver((BPMObserver) this);
	}

	public void createView() {
		// Create all Swing components here
		
	}

	//模型發生變化是,updateBPM()方法會被調用
	public void updateBPM() {
		if (model != null) {
			int bpm = model.getBPM();
			if (bpm == 0) {
				if (bpmOutputLabel != null) {
					bpmOutputLabel.setText("offline");
				}
			} else {
				if (bpmOutputLabel != null) {
					bpmOutputLabel.setText("Current BPM: " + model.getBPM());
				}
			}
		}
	}

	public void updateBeat() {
		if (beatBar != null) {
			beatBar.setValue(100);
		}
	}
}

//控制器
public interface ControllerInterface {
	//視圖能調用全部的控制器方法都在麗麗
	void start();
	void stop();
	void increaseBPM();
	void decreaseBPM();
	void setBPM(int bpm);
}

//實現ControllerInterface接口
public class BeatController implements ControllerInterface {
	BeatModelInterface model;
	DJView view;

	public BeatController(BeatModelInterface model) {
		this.model = model;
		
		//把控制器當參數傳入創建視圖的構造器中
		view = new DJView(this, model);
		view.createView();
		view.createControls();
		view.disableStopMenuItem();
		view.enableStartMenuItem();
		model.initialize();
	}

	public void start() {
		model.on();
		view.disableStartMenuItem();
		view.enableStopMenuItem();
	}

	public void stop() {
		model.off();
		view.disableStopMenuItem();
		view.enableStartMenuItem();
	}

	public void increaseBPM() {
		int bpm = model.getBPM();
		model.setBPM(bpm + 1);
	}

	public void decreaseBPM() {
		int bpm = model.getBPM();
		model.setBPM(bpm - 1);
	}

	public void setBPM(int bpm) {
		model.setBPM(bpm);
	}
}

public class DJTestDrive {

	public static void main(String[] args) {
		BeatModelInterface model = new BeatModel();
		//由控制器創建視圖
		ControllerInterface controller = new BeatController(model);
	}
}



《Head First 設計模式》學習筆記——復合模式