------- android教育訓練、java教育訓練、期待與您交流! ----------
設計模式概述: •設計模式這個術語是由Erich Gamma等人在1990年代從建築設計領域引入到計算機科學的。它是對軟體設計中普 遍存在(反複出現)的各種問題,所提出的解決方案。 •設計模式并不直接用來完成代碼的編寫,而是描述在各種不同情況下,要怎麼解決問題的一種方案。面向對象設 計模式通常以類或對象來描述其中的關系和互相作用,但不涉及用來完成應用程式的特定類或對象。設計模式能使 不穩定依賴于相對穩定、具體依賴于相對抽象,避免會引起麻煩的緊耦合,以增強軟體設計面對并适應變化的能 力。 設計模式分類: •建立型模式,共五種: -工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。 •結構型模式,共七種: -擴充卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。 •行為型模式,共十一種: -政策模式、模闆方法模式、觀察者模式、疊代子模式、責任鍊模式、指令模式、備忘錄模式、狀态模式、訪 問者模式、中介者模式、解釋器模式。 •課上遇到的設計模式:
(1)、單例設計模式
在整個應用中有且僅有一個執行個體對象
典型案例:
RunTime
/*
* 定義單例Person
*
* 懶漢式單例
*/
public class Person {
//定義靜态私有的本類型成員變量,并建立對象供方法傳回
private static Person p;
//私有化構造方法,讓外界無法直接建立對象
private Person() {
}
// //對外提供靜态公共的擷取執行個體方法,不考慮安全,不考慮效率
public static Person getInstance1() {
//判斷是否已經有執行個體對象
if(p==null) {
//如果沒有對象,才建立
p = new Person();
}
return p;
}
//對外提供靜态公共的擷取執行個體方法,考慮安全,不考慮效率
public synchronized static Person getInstance2() {
//判斷是否已經有執行個體對象
if(p==null) {
//如果沒有對象,才建立
p = new Person();
}
return p;
}
//對外提供靜态公共的擷取執行個體方法,考慮安全,不考慮效率
public static Person getInstance3() {
synchronized (Person.class) {
//判斷是否已經有執行個體對象
if(p==null) {
//如果沒有對象,才建立
p = new Person();
}
}
return p;
}
//對外提供靜态公共的擷取執行個體方法,考慮安全,考慮效率
public static Person getInstance4() {
//為了判斷是否執行同步
if(p==null) {
synchronized (Person.class) {
//為了判斷是否建立對象
if(p==null) {
//如果沒有對象,才建立
p = new Person();
}
}
}
return p;
}
}
/*
* 定義單例Person
*
* 餓漢式單例
*/
public class Person {
//定義靜态私有的本類型成員變量,并建立對象供方法傳回
private static Person p = new Person();
//私有化構造方法,讓外界無法直接建立對象
private Person() {
}
//對外提供靜态公共的擷取執行個體方法
public static Person getInstance() {
return p;
}
}
(2)、擴充卡設計模式
将一個類的接口根據使用者的需求,适配成便于使用的類/抽象類
典型案例:
GUI監聽器
以WindowAdapter()為例進行學習:
WindowListener:用于接收視窗事件的偵聽器接口。
WindowAdapter: 接收視窗事件的抽象擴充卡類。
由于WindowListener接口中抽象方法太多,在事件監聽時一般隻使用其中的一個或幾個,為了簡化操作,用 WindowAdapter實作WindowListener接口,但是WindowAdapter中的方法體為空,在使用時,我們隻需要将 用到的方法進行重寫即可,簡化了操作。
//添加監聽器
//使用擴充卡完成事件監聽
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//添加監聽器
//使用監聽器接口完成事件監聽
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
});
(3)、裝飾設計模式
添加一個修飾類包裹原來的類,在運作時便可以擴充其新的功能
典型案例:
高效緩沖IO流
public class MyBufferedReader {
//定義Reader類型的成員變量,用來接收Reader對象
private Reader reader;
public MyBufferedReader(Reader reader) {
this.reader = reader;
}
//定義readLine方法
public String readLine() throws IOException {
//定義變量,用來緩沖每行的内容,讀到一行結束就傳回
StringBuilder sb = new StringBuilder();
int c;
while((c=reader.read())!=-1) {
//如果遇到了一行當中的\r,不存到該行中,直接讀取下一個字元
if(c=='\r') {
continue;
}
//如果遇到了一行當中的\n,不存到該行中,直接将該行傳回了
if(c=='\n') {
return sb.toString();
}
//将改行非回車換行的字元加入到該行的緩沖區中
sb.append((char)c);
}
//如果跳出了循環,但是緩沖區内有内容,說明最後一行有内容但沒有回車換行,此時傳回該緩沖區内容
if(sb.length()!=0) {
return sb.toString();
}
//如果該行沒有任何内容,就傳回null
return null;
}
public void close() throws IOException {
reader.close();
}
}
(4)、工廠設計模式
使用工廠建立某些類的執行個體對象,進而取代之前自身調用構造new的操作
典型案例:
線程池
//使用工廠類調用方法,傳回線程池對象
ExecutorService threadPool = Executors.newFixedThreadPool(3);
(5)、模闆設計模式
将一個完整功能分隔成不同步驟,對多個實作類共同的操作使用具體的實作,對多個類的差異操作使用抽象。
每次建立新的視窗時隻需要完善method方法中的代碼即可。
public class Test2 {
public static void main(String[] args) {
//建立窗體對象
Frame frame = new Frame("唐嫣歡迎您!");
//設定屬性
before(frame);
//完成通過滑鼠移動到指定按鈕上時,改變窗體背景色
method(frame);
//窗體可見
after(frame);
}
//業務邏輯方法,完成通過滑鼠移動到指定按鈕上時,改變窗體背景色
private static void method(final Frame frame) {
//添加元件
Button btn = new Button("小紅");
Button btn2 = new Button("小蘭");
Button btn3 = new Button("大黃");
frame.add(btn);
frame.add(btn2);
frame.add(btn3);
// 為按鈕添加滑鼠監聽
btn.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("我進來了,我臉紅了");
//設定窗體為紅色
frame.setBackground(new Color(255, 0, 0));
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("我又出來了");
frame.setBackground(new Color(255, 255, 255));
}
});
// 為按鈕添加滑鼠監聽
btn2.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("我進來了,我臉藍了");
//設定窗體為藍色
frame.setBackground(new Color(0, 0, 255));
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("我又出來了");
frame.setBackground(new Color(255, 255, 255));
}
});
// 為按鈕添加滑鼠監聽
btn3.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("我進來了,我臉黃了");
//設定窗體為黃色
frame.setBackground(new Color(255, 255, 0));
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("我又出來了");
frame.setBackground(new Color(255, 255, 255));
}
});
}
//為窗體設定基本屬性
public static void before(Frame frame) {
//設定窗體屬性
frame.setSize(600,400);
//1366 768
int width = frame.getWidth();
int height = frame.getHeight();
int x = 1366/2 - width/2;
int y = 768/2 - height/2;
frame.setLocation(x, y);
//設定窗體布局
frame.setLayout(new FlowLayout());
//完成窗體關閉
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
//為窗體設定基本屬性
public static void after(Frame frame) {
//讓窗體可見
frame.setVisible(true);
}
}