日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java常用设计模式总结及应用场景分析

發布時間:2023/12/10 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java常用设计模式总结及应用场景分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

掌握常用的幾種(最起碼單例模式、工廠模式),了解其他的設計模式即可,做到手里有糧,心里不慌。首先,掌握每種模式的定義及使用場景。其次,掌握一個形象的例子,簡單的過一遍代碼。
學習設計模式的真正目的:編程時,有意識地面向接口編程,多用封裝、繼承、組合、多態等OOP思想,而不僅僅是死記幾類設計模式。

常用的設計模式分類:
創建型(創建一個對象):單例模式、工廠模式、抽象工廠模式
結構型(將幾個對象組織成一個結構):橋接模式、外觀模式、代理模式
行為型(多個對象間的通信):觀察者模式、策略模式
其中,工廠模式、橋接模式、策略模式有點像,放在一起理解(幾個對象具有共同特征,因此繼承共同的接口,然后通過工廠、橋去訪問)。另外,工廠模式和外觀模式(幾個對象間有先后關系,是串行的,而非工廠模式中的并行,因此幾個對象組合成一個外觀類,通過這個外觀類來訪問)區別很明顯,也因此放在一起理解。

參考引用:

http://www.runoob.com/design-pattern/proxy-pattern.html
https://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html
https://www.cnblogs.com/chinajava/p/5880870.html

設計模式定義

被反復使用的,代碼設計經驗的總結。

設計模式的原則

總結起來,就是多用接口/抽象類,從而增加代碼的可擴展性(減少修改代碼)。降低模塊間的依賴和聯系。
體現了OOP的模塊化、可擴展性等特征。

工廠模式

定義與使用場合:現在需要創建幾個對象,且這幾個對象有共同特征,則不需要具體創建各個對象,而是創建對象工廠類即可。
一般常用靜態工廠模式。
例子:發送郵件和短信(共同特征:發送的消息)

public interface Sender { public void Send(); }
  • 1
  • 2
  • 3
public class MailSender implements Sender { @Override public void Send() { System.out.println("this is mailsender!"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
public class SmsSender implements Sender { @Override public void Send() { System.out.println("this is sms sender!"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class SendFactory { public static Sender produceMail(){ return new MailSender(); } public static Sender produceSms(){ return new SmsSender(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
public class FactoryTest { public static void main(String[] args) { Sender sender = SendFactory.produceMail(); sender.Send(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

抽象工廠模式

工廠方法模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則
定義與使用場景:同上。
例子:同上。

public interface Provider { public Sender produce(); }
  • 1
  • 2
  • 3
public class SendMailFactory implements Provider { @Override public Sender produce(){ return new MailSender(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class SendSmsFactory implements Provider{ @Override public Sender produce() { return new SmsSender(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class Test { public static void main(String[] args) { Provider provider = new SendMailFactory(); Sender sender = provider.produce(); sender.Send(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

總結:如果要新增發送微信,則只需做一個實現類,實現Sender接口,同時做一個工廠類,實現Provider接口,就OK了,無需去改動現成的代碼。這樣做,拓展性較好!
所有工廠模式中,抽象工廠模式最先進。

策略模式及與工廠模式的區別

定義與使用場合:一個系統需要動態地在幾種類似的算法中選擇一種。
與工廠模式異同:實例化一個對象的位置不同。對工廠模式而言,實例化對象是放在了工廠類里面。而策略模式實例化對象的操作在調用的地方。本質都是繼承與多態。
例子: 現有 加/減/乘 幾種算法,輸入參數返回值都一樣(可以理解成類似的算法)。現在需要在調用時動態配置算法策略,實現對不同算法的調用。

public interface Strategy {public int doOperation(int num1, int num2); }
  • 1
  • 2
  • 3
public class OperationAdd implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
public class OperationSubstract implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
public class OperationMultiply implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
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));} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

單例模式

定義及使用場合:只有一個對象被創建。
例子:
建議采用 餓漢式 創建方法。線程安全,容易實現。初始化慢一點。

public class SingleObject {//創建 SingleObject 的一個對象private static SingleObject instance = new SingleObject();//讓構造函數為 private,這樣該類就不會被實例化private SingleObject(){}//獲取唯一可用的對象public static SingleObject getInstance(){return instance;}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

觀察者模式

定義與使用場景:一個對象(subject)被其他多個對象(observer)所依賴。則當一個對象變化時,發出通知,其它依賴該對象的對象都會收到通知,并且隨著變化。
比如 聲音報警器和閃光燈報警器分別訂閱熱水器溫度,熱水器溫度過高時,發出通知,兩個報警器分別發聲、閃光以實現報警。
又比如很多人訂閱微信公眾號,該公眾號有更新文章時,自動通知每個訂閱的用戶。
**實現:**1,多個觀察者要訂閱這個對象 2,這個對象要發出通知

例子:

public interface Observer { public void update(); }
  • 1
  • 2
  • 3
public class Observer1 implements Observer { @Override public void update() { System.out.println("observer1 has received!"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class Observer2 implements Observer { @Override public void update() { System.out.println("observer2 has received!"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
public interface Subject { /*增加觀察者*/ public void add(Observer observer); /*刪除觀察者*/ public void del(Observer observer); /*通知所有的觀察者*/ public void notifyObservers(); /*自身的操作*/ public void operation(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
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(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
public class MySubject extends AbstractSubject { @Override public void operation() { System.out.println("update self!"); notifyObservers(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
public class ObserverTest { public static void main(String[] args) { Subject sub = new MySubject(); sub.add(new Observer1()); //訂閱這個對象sub.add(new Observer2()); sub.operation(); //發出改變的一個通知} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

代理模式

定義與使用場景:一個代理類代表一個真實類的功能,通過訪問代理類來實現對真實類的訪問。
比如買火車票這件小事:黃牛相當于是火車站的代理,我們可以通過黃牛買票,但只能去火車站進行改簽和退票。
又比如需要對原有的方法進行修改,就是采用一個代理類調用原有的方法,以避免修改原有代碼。
例子:

一個真實對象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();} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

橋接模式及與策略模式的區別

定義與使用場景:訪問多種數據庫驅動(多個具有共同特征的數據庫驅動),不是直接訪問,而是通過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!"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
public class User { public static void main(String[] args) { Computer computer = new Computer(); //將計算機的啟動過程封裝成一個類computer.startup(); computer.shutdown(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

生產者-消費者模式

定義與使用場景:生產者把數據放入緩沖區,而消費者從緩沖區取出數據。
例子:緩沖區一般為隊列(FIFO),但在生產消費較為頻繁時,隊列push,pop內存消耗較大,此時可以考慮環形緩沖區(以數組、鏈表方式實現)。
通過互斥鎖防止緩沖區同時讀寫。通過信號量控制緩沖區大小(滿的時候不允許寫,空的時候不允許讀)


作者:qq_14827935
來源:CSDN
原文:https://blog.csdn.net/qq_14827935/article/details/78618652

總結

以上是生活随笔為你收集整理的Java常用设计模式总结及应用场景分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。