java常用設計模式總結
掌握常用的幾種(最起碼單例模式、工廠模式),瞭解其他的設計模式即可,做到手裡有糧,心裡不慌。首先,掌握每種模式的定義及使用場景。其次,掌握一個形象的例子,簡單的過一遍程式碼。
學習設計模式的真正目的:程式設計時,有意識地面向介面程式設計,多用封裝、繼承、組合、多型等OOP思想,而不僅僅是死記幾類設計模式。
常用的設計模式分類:
建立型(建立一個物件):單例模式、工廠模式、抽象工廠模式
結構型(將幾個物件組織成一個結構):橋接模式、外觀模式、代理模式
行為型(多個物件間的通訊):觀察者模式、策略模式
其中,工廠模式、橋接模式、策略模式有點像,放在一起理解(幾個物件具有共同特徵,因此繼承共同的介面,然後通過工廠、橋去訪問
參考引用:
設計模式定義
被反覆使用的,程式碼設計經驗的總結。
設計模式的原則
總結起來,就是多用介面/抽象類,從而增加程式碼的可擴充套件性(減少修改程式碼)。降低模組間的依賴和聯絡。
體現了OOP的模組化、可擴充套件性等特徵。
工廠模式
定義與使用場合:現在需要建立幾個物件,且這幾個物件有共同特徵,則不需要具體建立各個物件,而是建立物件工廠類即可。
一般常用靜態工廠模式。
例子:傳送郵件和簡訊(共同特徵:傳送的訊息)
public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send () {
System.out.println("this is sms sender!");
}
}
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
抽象工廠模式
工廠方法模式有一個問題就是,類的建立依賴工廠類,也就是說,如果想要拓展程式,必須對工廠類進行修改,這違背了閉包原則。
定義與使用場景:同上。
例子:同上。
public interface Provider {
public Sender produce();
}
public class SendMailFactory implements Provider {
@Override
public Sender produce(){
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.Send();
}
}
總結:如果要新增傳送微信,則只需做一個實現類,實現Sender介面,同時做一個工廠類,實現Provider介面,就OK了,無需去改動現成的程式碼。這樣做,拓展性較好!
所有工廠模式中,抽象工廠模式最先進。
策略模式及與工廠模式的區別
定義與使用場合:一個系統需要動態地在幾種類似的演算法中選擇一種。
與工廠模式異同:例項化一個物件的位置不同。對工廠模式而言,例項化物件是放在了工廠類裡面。而策略模式例項化物件的操作在呼叫的地方。本質都是繼承與多型。
例子: 現有 加/減/乘 幾種演算法,輸入引數返回值都一樣(可以理解成類似的演算法)。現在需要在呼叫時動態配置演算法策略,實現對不同演算法的呼叫。
public interface Strategy {
public int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
//例項化物件的位置在呼叫處
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
單例模式
定義及使用場合:只有一個物件被建立。
例子:
建議採用 餓漢式 建立方法。執行緒安全,容易實現。初始化慢一點。
public class SingleObject {
//建立 SingleObject 的一個物件
private static SingleObject instance = new SingleObject();
//讓建構函式為 private,這樣該類就不會被例項化
private SingleObject(){}
//獲取唯一可用的物件
public static SingleObject getInstance(){
return instance;
}
}
觀察者模式
定義與使用場景:一個物件(subject)被其他多個物件(observer)所依賴。則當一個物件變化時,發出通知,其它依賴該物件的物件都會收到通知,並且隨著變化。
比如 聲音報警器和閃光燈報警器分別訂閱熱水器溫度,熱水器溫度過高時,發出通知,兩個報警器分別發聲、閃光以實現報警。
又比如很多人訂閱微信公眾號,該公眾號有更新文章時,自動通知每個訂閱的使用者。
**實現:**1,多個觀察者要訂閱這個物件 2,這個物件要發出通知
例子:
public interface Observer {
public void update();
}
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
public interface Subject {
/*增加觀察者*/
public void add(Observer observer);
/*刪除觀察者*/
public void del(Observer observer);
/*通知所有的觀察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("update self!");
notifyObservers();
}
}
public class ObserverTest {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1()); //訂閱這個物件
sub.add(new Observer2());
sub.operation(); //發出改變的一個通知
}
}
代理模式
定義與使用場景:一個代理類代表一個真實類的功能,通過訪問代理類來實現對真實類的訪問。
比如買火車票這件小事:黃牛相當於是火車站的代理,我們可以通過黃牛買票,但只能去火車站進行改簽和退票。
又比如需要對原有的方法進行修改,就是採用一個代理類呼叫原有的方法,以避免修改原有程式碼。
例子:
一個真實物件realSubject提供一個代理物件proxy。通過proxy可以呼叫realSubject的部分功能*,並新增一些額外的業務處理*,同時可以遮蔽realSubject中未開放的介面。
1、RealSubject 是委託類,Proxy 是代理類;
2、Subject 是委託類和代理類的介面;
3、request() 是委託類和代理類的共同方法;
interface Subject {
void request();
}
class RealSubject implements Subject {
public void request(){
System.out.println("RealSubject");
}
}
class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject){
this.subject = subject;
}
public void request(){
System.out.println("begin");
subject.request();
System.out.println("end");
}
}
public class ProxyTest {
public static void main(String args[]) {
RealSubject subject = new RealSubject();
Proxy p = new Proxy(subject);
p.request();
}
}
橋接模式及與策略模式的區別
定義與使用場景:訪問多種資料庫驅動(多個具有共同特徵的資料庫驅動),不是直接訪問,而是通過DriverManager橋來訪問。
例子: 不再具體實現了。
與策略模式的區別:(個人覺得較複雜,瞭解即可。本質都是面向介面程式設計,體現繼承與多型)
策略模式:我要畫圓,要實心圓,我可以用solidPen來配置,畫虛線圓可以用dashedPen來配置。這是strategy模式。
橋接模式:同樣是畫圓,我是在windows下來畫實心圓,就用windowPen+solidPen來配置,在unix下畫實心圓就用unixPen+solidPen來配置。如果要再windows下畫虛線圓,就用windowsPen+dashedPen來配置,要在unix下畫虛線圓,就用unixPen+dashedPen來配置。
所以相對策略模式,橋接模式要表達的內容要更多,結構也更加複雜。
外觀模式
定義與使用場景:見例子。又比如,去醫院看病,可能要去掛號、門診、劃價、取藥,讓患者或患者家屬覺得很複雜,如果有提供接待人員,只讓接待人員來處理,就很方便。
例子:計算機啟動,需要先啟動CPU,再啟動memory,最後啟動disk。這三個類之間具有先後關係(依賴關係)。
與工廠模式的區別:工程模式多個類具有共同特徵(繼承一個共同的介面),是並列的。而外觀模式多個類是有先後關係,是序列的,用組合。
貼部分程式碼:
public class Computer {
//是組合,而非繼承。這是與工程模式的顯著區別。
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer(){
cpu = new CPU();
memory = new Memory();
disk = new Disk();
}
public void startup(){
System.out.println("start the computer!");
cpu.startup();
memory.startup();
disk.startup();
System.out.println("start computer finished!");
}
public void shutdown(){
System.out.println("begin to close the computer!");
cpu.shutdown();
memory.shutdown();
disk.shutdown();
System.out.println("computer closed!");
}
}
public class User {
public static void main(String[] args) {
Computer computer = new Computer();
//將計算機的啟動過程封裝成一個類
computer.startup();
computer.shutdown();
}
}
生產者-消費者模式
定義與使用場景:生產者把資料放入緩衝區,而消費者從緩衝區取出資料。
例子:緩衝區一般為佇列(FIFO),但在生產消費較為頻繁時,佇列push,pop記憶體消耗較大,此時可以考慮環形緩衝區(以陣列、連結串列方式實現)。
通過互斥鎖防止緩衝區同時讀寫。通過訊號量控制緩衝區大小(滿的時候不允許寫,空的時候不允許讀)
相關推薦
java常用設計模式總結
掌握常用的幾種(最起碼單例模式、工廠模式),瞭解其他的設計模式即可,做到手裡有糧,心裡不慌。首先,掌握每種模式的定義及使用場景。其次,掌握一個形象的例子,簡單的過一遍程式碼。 學習設計模式的真正目的:程式設計時,有意識地面向介面程式設計,多用封裝、繼承、組合、
JAVA常用設計模式
ipp targe aec atd jmh 設計模式 模式 java left 巴揭殼景枚嫡倚濫煽吠徑http://www.docin.com/vxuo069 蔚贍卣碩狼吠亢照某嶽魏徹http://www.docin.com/idj90593 黃濁偃由友兔兆凍寺敬踴酌沮持h
Java常用設計模式——觀察者模式
ray stat param servers face oid println override 角色 觀察者模式又叫做發布-訂閱-模式、模型-視圖-模式、源-監聽器-模式或者從屬者模式。觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對
Java常用設計模式——策略模式
nts static 管理 選擇 span disco rri contex 由於 策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換,策略模式讓算法獨立於使用它的客戶而獨立變化。策略模式使這些算法在客戶端調用它們的時候能夠互不影響地變化
java常用設計模式--觀察者模式簡單例子
package com.ruanyun;import java.util.List;import java.util.Vector;/** * @Auther: maxw * @Date: 2018/11/10 16:14 * @Description:觀察者模式 * 基本概念: * 觀察者模式屬於行為型模式
java常用設計模式--單例模式簡單例子
package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/10 17:29 * @Description: */public class Test4 { public static void main(String args[]){
java常用設計模式--工廠方法模式簡單例子
package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:02 * @Description:工廠方法模式:有四個角色,抽象工廠模式,具體工廠模式,抽象產品模式,具體產品模式。不再是由一個工廠類去例項化具體的產品,而是由抽象工廠的子類去例項化
java常用設計模式--抽象工廠模式簡單例子
package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:23 * @Description:抽象工廠模式:與工廠方法模式不同的是,工廠方法模式中的工廠只生產單一的產品,而抽象工廠模式中的工廠生產多個產品。 * 還有個抽象工廠方法模式 只需要
java常用設計模式--享元模式簡單例項
package com.ruanyun;import java.util.HashMap;import java.util.Map;/** * @Auther: maxw * @Date: 2018/11/21 09:47 * @Description:享元模式:“享”就是分享之意,指一物被眾人共享,而這也正
java常用設計模式連結
轉自:作者:dreamOwn https://www.cnblogs.com/wabi87547568/p/5280905.html Java中常用的設計模式 1.單例模式 單例模式有以下特點: 1、單例類只能有一個例項。 2、單例類必須自己
常用設計模式總結(面試常問)
Singleton(單例模式) 一句話總結:一個類在Java虛擬機器中只有一個物件,並提供一個全域性訪問點。 生活中例子:太陽、月亮、國家主席等。 解決什麼問題:物件的唯一性,效能浪費太多。 專案裡面怎麼用:資料庫連線物件,屬性配置檔案的讀取物件。 模式結構:分為餓漢式和懶漢式(
Java常用設計模式————觀察者模式
引言 作為設計模式中常用的行為型模式,其主要解決的是一個複合物件(或組合物件)的基礎依賴物件的通知問題。 簡單的說,當一個複合物件依賴多個其他物件時,我們稱這種關係為一對多的關係。當這個複合物件狀態發生了改變,其他組成它的物件都可以收到來自複合物件的通知。 依賴物件中存在一個指向複合
java常用設計模式10—裝飾模式
我的設計模式學習系列專案地址: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/DesignPatternStudy 介紹: 裝飾模式也稱為包裝模式,結構型設計
java常用設計模式9——代理模式
介紹:代理模式也稱為委託模式。 定義:為其它物件提供一種代理以控制對這個物件的訪問。 程式碼舉例: 山中有一個大王,大王有一個嘍囉,大王需要巡山來保證自己的地盤不被入侵,但是大王怎麼能自己去巡山呢?所以就要嘍囉代替大王來巡山。 我們用代理模式描述這個場景 //任務 publi
java常用設計模式8——模板方法模式
這個設計模式應該是最簡單的設計模式,因為大家平時都在使用,可能只是不知道它還是個設計模式吧 相關程式碼下載: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/Desi
java常用設計模式7——責任鏈模式
嘿嘿,這次介紹一個好玩的設計模式 — — 責任鏈模式 相關程式碼下載: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/DesignPatternStudy
java常用設計模式6——狀態模式
狀態模式介紹: 1、狀態模式中的行為是由狀態來決定的,不同的狀態下有不同的行為。 2、狀態模式和策略模式的結構幾乎完全一樣,但它們的目的、本質卻完全不一樣。狀態模式的行為是平行的,不可替換的,策略模式的行為是彼此獨立,可相互替換的。 3、狀態模式把物件的行為包裝在不同的狀態物件裡,每一個
java常用設計模式5——策略模式
通常一個問題有多個解決方案的時候,我們會把每個解決方案封裝到自己的類裡面,這樣可以避免在同一個類裡通過if,else或者switch來判斷使用哪種方案。 比如: if(type == 1){ return fun1(); }else if(type == 2){ return f
java常用設計模式4——觀察者模式
當被觀察者的狀態傳送改變的時候,所有觀察它的物件都會得到通知並自動更新。 觀察者模式UML圖: Subject: 抽象主題。把所有觀察者物件的引用儲存在一個集合裡,每個主題都可以有任意數量的觀察者,抽象主題提供一個介面,可以增加和刪除物件。 ConcreteSubject:具體主題
java常用設計模式3——工廠方法模式
1、工廠方法模式定義:定義一個用於建立物件的介面,讓子類決定例項化哪個類 2、工廠方法模式的使用場景:在任何需要生成複雜物件的地方,都可以使用工廠方法模式。複雜物件適合使用工廠模式,用new就可以完成建立的物件無需使用工廠模式 多工廠方法模式 程式碼示例: 1、定義一個抽象的產品