1. 程式人生 > >Java常用設計模式學習筆記

Java常用設計模式學習筆記

作為一名Java開發者,瞭解並學習一些常用的設計模式是很有必要的,不常用的就可以先不管它了,要用到的時候再去了解,現在學習瞭解一下常用的幾種設計模式,單例模式、工廠模式、建造模式、介面卡模式、代理模式、觀察者模式

一、單例模式

單例模式的主要目的是使記憶體中始終保持一個物件,Demo如下:

public class Singleton {
	
	//將自身的例項物件設定為一個屬性,並加上Static和final修飾符
	private static final Singleton instance = new Singleton();

	//將構造方法設定成私有形式
	private Singleton() {
		
	}

	//通過一個靜態方法向外界提供這個類的例項
	public static Singleton getInstance() {
		return instance;
	}
}

這樣每次都使用Singleton.getInstance()方法來獲得一個物件,記憶體中始終就保持著一個物件,這就是單例模式。

二、工廠模式

工廠模式主要目的是統一提供例項物件的引用,Demo如下:

public class Factory {
	public ClassesDao getClassesDao() {
		ClassesDao cd = new ClassesDaoImpl();
		return cd;
	}
}

interface ClassesDao {
	public String getClassesName();
}

class ClassesDaoImpl implements ClassesDao {
	public String getClassesName() {
		System.out.println("A班");
	}
}

class test {
	public static void main(String[] args) {
		Factory f = new Factory();
		f.getClassesDao().getClassesName();
	}
}

這樣子,使用工廠來獲得物件例項的引用,即每次都使用f.getClassesDao()獲得物件例項的引用。

三、建造模式

將產品的內部表象和產品的生成過程分割開來,從而使一個建造過程生成具有不同的內部表象的產品物件。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。

public interface Builder {
	// 建立部件A 比如建立汽車車輪
	void buildPartA();

	// 建立部件B 比如建立汽車方向盤 
	void buildPartB();
	// 建立部件C 比如建立汽車發動機
	void buildPartC();
	// 返回最後組裝成品結果 (返回最後裝配好的汽車)
	// 成品的組裝過程不在這裡進行,而是轉移到下面的Director類別中進行。
	// 從而實現瞭解耦過程和部件
	Product getResult();
}

public class Director {
	private Builder builder;

	public Director( Builder builder ) {      
		this.builder = builder;   
	}

	// 將部件partA partB partC最後組成複雜物件
	// 這裡是將車輪 方向盤和發動機組裝成汽車的過程
	public void construct() {
		builder.buildPartA();
		builder.buildPartB();
		builder.buildPartC();
	}
}}

這樣就將產品的內部表象和產品的生成過程分割開了,從而使一個建造過程生成具有不同的內部表象的產品物件。

四、介面卡模式

把一個類的介面變換為客戶端所期待的另一種介面,從而使原本因介面不匹配造成無法一起工作的兩個雷可以一起工作,介面卡可以根據引數返還一個合適的例項給客戶端。

public interface IRoundPeg {
	public void insertIntoHole(String msg);
}

public interface ISquarePeg {
	public void insert(String str);
}

public class PegAdapter implements IRoundPeg, ISquarePeg {
	private RoundPeg roundPeg;
	private SquarePeg squarePeg;

	// 構造方法
	public PegAdapter(RoundPeg peg) {
		this.roundPeg = peg;
	}

	// 構造方法
	public PegAdapter(SquarePeg peg) {
		this.squarePeg = peg;
	}

	public void insert(String str) {
		roundPeg.insertIntoHole(str);
	}

	public void insertIntoHole(String str) {
		SquarePeg.insert(str);
	}
}

這樣就可以根據引數來返還IRoundPeg或者是ISquarePeg例項給客戶端了。

五、代理模式

代理模式有兩種實現方式,一種是靜態代理,另一種是動態代理,各大框架都喜歡用動態代理。

靜態代理

public interface Subject {
    void visit();
}
//實現Subject介面的兩個類
public class RealSubject implements Subject {

    private String name = "byhieg";
    @Override
    public void visit() {
        System.out.println(name);
    }
}

public class ProxySubject implements Subject{

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void visit() {
        subject.visit();
    }
}

//然後如下方式呼叫
public class Client {

    public static void main(String[] args) {
        ProxySubject subject = new ProxySubject(new RealSubject());
        subject.visit();
    }
}

通過上面的代理程式碼,我們可以看出代理模式的特點,代理類接受一個Subject介面的物件,任何實現該介面的物件,都可以通過代理類進行代理,增加了通用性。但是也有缺點,每一個代理類都必須實現一遍委託類(也就是realsubject)的介面,如果介面增加方法,則代理類也必須跟著修改。其次,代理類每一個介面物件對應一個委託物件,如果委託物件非常多,則靜態代理類就非常臃腫,難以勝任。

動態代理

動態代理有別於靜態代理,是根據代理的物件,動態建立代理類。這樣,就可以避免靜態代理中代理類介面過多的問題。動態代理是實現方式,是通過反射來實現的,藉助Java自帶的java.lang.reflect.Proxy,通過固定的規則生成。

接上面程式碼

public class DynamicProxy implements InvocationHandler {
    private Object object;
    public DynamicProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        return result;
    }
}

然後建立動態代理物件

Subject realSubject = new RealSubject();
DynamicProxy proxy = new DynamicProxy(realSubject);
ClassLoader classLoader = realSubject.getClass().getClassLoader();
Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new  Class[]{Subject.class}, proxy);
subject.visit();


六、觀察者模式

觀察者模式又稱為釋出/訂閱(Publish/Subscribe)模式,因此我們可以用報紙期刊的訂閱來形象的說明:

    報社方負責出版報紙.

    你訂閱了該報社的報紙,那麼只要報社釋出了新報紙,就會通知你,或發到你手上.

    如果你不想再讀報紙,可以取消訂閱,這樣,報社釋出了新報紙就不會再通知你.

  理解其實以上的概念,就可以理解觀察者模式,觀察者模式中有主題(Subject)和觀察者(Observer),分別對應報社和訂閱使用者(你).觀察者模式定義了物件之間的一對多的依賴關係,這樣,當"一"的一方狀態發生變化時,它所依賴的"多"的一方都會收到通知並且自動更新.

package com.wang.observer;
//主題介面
 interface Subject {
     //新增觀察者
     void addObserver(Observer obj);
     //移除觀察者
     void deleteObserver(Observer obj);
     //當主題方法改變時,這個方法被呼叫,通知所有的觀察者
     void notifyObserver();
}
package com.wang.observer;

interface Observer {
    //當主題狀態改變時,會將一個String型別字元傳入該方法的引數,每個觀察者都需要實現該方法
    public void update(String info);
}
package com.wang.observer;

import java.util.ArrayList;
import java.util.List;

public class TeacherSubject implements Subject {
    //用來存放和記錄觀察者
    private List<Observer> observers=new ArrayList<Observer>();
    //記錄狀態的字串
    private String info;
    
    @Override
    public void addObserver(Observer obj) {
        observers.add(obj);
    }

    @Override
    public void deleteObserver(Observer obj) {
        int i = observers.indexOf(obj);
        if(i>=0){
            observers.remove(obj);
        }
    }

    @Override
    public void notifyObserver() {
        for(int i=0;i<observers.size();i++){
            Observer o=(Observer)observers.get(i);
            o.update(info);
        }
    }
    //佈置作業的方法,在方法最後,需要呼叫notifyObserver()方法,通知所有觀察者更新狀態
    public void setHomework(String info){
        this.info=info;
        System.out.println("今天的作業是"+info);
        this.notifyObserver();
    }

}
package com.wang.observer;

public class StudentObserver implements Observer {

    //儲存一個Subject的引用,以後如果可以想取消訂閱,有了這個引用會比較方便
    private TeacherSubject t;
    //學生的姓名,用來標識不同的學生物件
    private String name;
    //構造器用來註冊觀察者
    public Student(String name,Teacher t) {
        this.name=name;
        this.t = t;
        //每新建一個學生物件,預設新增到觀察者的行列
        t.addObserver(this);
    }


    @Override
    public void update(String info) {
        System.out.println(name+"得到作業:"+info);
        
    }

}

測試:

package com.wang.observer;

public class TestObserver {

    public static void main(String[] args) {
        
        TeacherSubject teacher=new TeacherSubject();
        StudentObserver zhangSan=new StudentObserver("張三", teacher);
        StudentObserver LiSi=new StudentObserver("李四", teacher);
        StudentObserver WangWu=new StudentObserver("王五", teacher);
        
        teacher.setHomework("第二頁第六題");
        teacher.setHomework("第三頁第七題");
        teacher.setHomework("第五頁第八題");
    }
}

列印結果:

今天的作業是第二頁第六題
張三得到作業:第二頁第六題
李四得到作業:第二頁第六題
王五得到作業:第二頁第六題
今天的作業是第三頁第七題
張三得到作業:第三頁第七題
李四得到作業:第三頁第七題
王五得到作業:第三頁第七題
今天的作業是第五頁第八題
張三得到作業:第五頁第八題
李四得到作業:第五頁第八題
王五得到作業:第五頁第八題

從列印結果看,每當老師佈置作業的狀態改變,就會通知每一個學生.以上就是一個簡單的觀察者模式的實現.

推薦大家一個Java的學習網站:Java知識學習網,Java資料下載,Java學習路線圖,網址:https://www.java1010.com

相關推薦

Java常用設計模式學習筆記

作為一名Java開發者,瞭解並學習一些常用的設計模式是很有必要的,不常用的就可以先不管它了,要用到的時候再去了解,現在學習瞭解一下常用的幾種設計模式,單例模式、工廠模式、建造模式、介面卡模式、代理模式、觀察者模式 一、單例模式 單例模式的主要目的是使記憶體中始終保持一個物

7 種 Javascript 常用設計模式學習筆記

7 種 Javascript 常用設計模式學習筆記 由於 JS 或者前端的場景限制,並不是 23 種設計模式都常用。 有的是沒有使用場景,有的模式使用場景非常少,所以只是列舉 7 個常見的模式 本文的脈絡: 設計與模式 5 大設計原則 7 種常見的設計模式 一句話解釋含

java/android 設計模式學習筆記(10)---建造者模式

  這篇部落格我們來介紹一下建造者模式(Builder Pattern),建造者模式又被稱為生成器模式,是創造性模式之一,與工廠方法模式和抽象工廠模式不同,後兩者的目的是為了實現多型性,而 Builder 模式的目的則是為了將物件的構建與展示分離。Builder

java/android 設計模式學習筆記(15)---責任鏈模式

  這篇部落格我們來介紹一下責任鏈模式(Chain-of-responsibility Pattern),責任聯模式又稱為職責鏈模式,是行為型設計模式之一。顧名思義,責任鏈模式中存在一個鏈式結構,多個節點首尾相連,每個節點都可以被拆開再連線,因此,鏈式結構具有很

java/android 設計模式學習筆記(20)---迭代器模式

  我們這篇部落格來介紹一下迭代器模式(Iterator Pattern),又稱為遊標(Cursor Pattern)模式,是行為型設計模式之一。迭代器模式算是一個比較古老的設計模式,其源於對容器的訪問,比如 Java 中的 List、Map、陣列等,我們知道對

java/android 設計模式學習筆記(12)---組合模式

  這篇我們來介紹一下組合模式(Composite Pattern),它也稱為部分整體模式(Part-Whole Pattern),結構型模式之一。組合模式比較簡單,它將一組相似的物件看作一個物件處理,並根據一個樹狀結構來組合物件,然後提供一個統一的方法去訪問相

Java 設計模式學習筆記1——策略模式(Duck例子)

利用 實例化 top 而是 實現 學習筆記 left ng- 多個 0、假設現有工程(Duck)中遇到為類添加功能的問題,如何設計類添加新的功能? 1、利用繼承提供的Duck(鴨子)的行為會導致哪些缺點? (1)代碼在多個子類中重復 (2)很多男知道所有鴨子的全部行為

Java設計模式學習筆記,三:建造者模式

() stat sys pri builder 統一 return tengine str 建造者模式:實現了構建和裝配的解耦,即對象的各個子組件單獨構建,再進行裝配,從而建造完整對象。 該模式適用於構建較為復雜的對象(多個子組件)。 不同的構建者,使用相同的裝配者,可以建

java設計模式學習筆記(三) --- 行為型模式

文章目錄 責任鏈模式 策略模式 命令模式 直譯器模式 迭代器模式 中介者模式 備忘錄模式 觀察者模式 狀態模式 模板方法模式 訪問者模式 責任鏈模式 我獲取了一個物件,現在需要根據物件

java設計模式學習筆記(二)--- 結構型模式

文章目錄 介面卡模式 組合模式 裝飾模式 代理模式 什麼時候使用代理模式 享元模式 外觀模式(門面模式) 橋樑模式 介面卡模式 介面卡是一個介面轉換器,用於在接收不同的輸入時,得到一致

java設計模式學習筆記(一)--- 建立型模式

文章目錄 簡介 設計模式所遵循的幾個原則 一、工廠方法模式 簡單工廠模式 工廠方法模式 抽象工廠模式 工廠模式小結 單例模式 單例模式小結 建造者模式

JAVA設計模式學習筆記(一)

2018年11月03日 12:14:18 築夢^_^ 閱讀數:6 個人分類: JAVA

Java設計模式學習筆記(觀察者模式

觀察者模式說起來很簡單,就是一個訂報紙的模式。但是實際上這部分我覺得還是很有意思的,《Head First設計模式》裡還有一些還沒看完,也是因為理解的不夠深吧。     觀察者模式會包含兩個元件:觀察者和主題。     這段程式碼是主題的介面: package

Java設計模式學習筆記(單例模式

最近一直在看《Head First設計模式》,這本書寫的確實是很不錯的,專注於怎麼用最簡單的方式最通俗的語言讓人瞭解設計模式。據說GoF的設計模式那本書寫的很好,是一本經典,但是就是難懂,這本書應該就是我們這些一看經典書就困的人的寶貝了。     不過Head First系列並不專注於

java設計模式學習筆記--抽象工廠模式

1. 什麼是抽象工廠模式 抽象工廠模式提供一個介面,用於建立相關或依賴物件的家族,而不需要明確指定具體類。 也就是說抽象工廠模式是用來 建立產品的家族的。 為了理解這個定義,我們先要搞清楚什麼是產品的家族。 那麼什麼是產品的家族哪,我的理解就是一群相

java設計模式學習筆記--簡單工廠模式

1. 什麼是簡單工廠模式 簡單工廠模式是屬於建立型模式,又叫做靜態工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的例項。但是嚴格來說,簡單工廠模式不是設計模式,它更像是一種程式設計習慣。 2.

java設計模式學習筆記--原型模式(淺克隆和深克隆)

1. 什麼是原型模式 原型模式屬於物件的建立模式。。原型模式允許你通過複製現有的例項來建立新的例項。 這個模式的重點在於,客戶端的程式碼在不知道要例項化何種特定類的情況下,可以製造出新的例項。在java中,一般使用clone()的方法,或者序列化。 2

java設計模式學習筆記--代理模式

1. 什麼是代理模式 代理模式是物件的結構模式。代理模式給某一個物件提供一個代理物件,並由代理物件控制對原物件的引用。 2.代理模式的結構 代理模式有兩種:靜態代理和動態代理。 先來看一下靜態代理: 2.1 靜態代理: 在代理模式中,有三個角色:

java 設計模式 學習筆記(17) 橋接模式

 橋接模式:           將抽象部分與它的實現部分分離,使他們多可以獨立的變化。抽象與實現分離,表示抽象類和他的派生類用來實現自己的物件。        在系統中,可能有多角度分類,每一種分類都有可能變化,這時就把這種多角度分離出來讓他們獨立變化,減少各個角度的耦合。

java設計模式學習筆記--介面卡模式

1、什麼是介面卡模式 介面卡模式:將一個類的介面,轉換成客戶端 期望的另一個介面。介面卡讓原本介面不相容的類可以合作無間。 這個模式可以通過建立介面卡進行介面轉換,讓不相容的介面變成相容。可以讓客戶端從從實現的介面解耦,如果在一段時間後,想要改變介面,