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