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

歡迎訪問 生活随笔!

生活随笔

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

asp.net

java常用设计模式详解及应用

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

java常用設計模式詳解及應用
java有23種設計模式,用于解決在編程當中遇到的實際問題。本文主要講解單例模式、工廠模式、適配器模式、裝飾模式、代理模式、模板模式、策略模式、觀察者模式、委托模式。
(1)單例模式
定義:確保一個類只有一個實例,而且自行實例化并向整個系統提供這個實例。
類圖:

Singleton 是一個自關聯的類。
單例模式實例化對象的機制分兩種一種是懶漢式,一種是餓漢式模式。懶漢式就是在調用的時候才實例化對象,而餓漢模式是在加載類的時候就已經實例化對象了。
1、懶漢式單例

public class Singleton {private Singleton(){}private static Singleton singleton=null;public static Singleton getInstance(){if (singleton ==null){return new Singleton();}return singleton;} }

這里將Singleton類的構造函數限定為private,來避免外部對象直接創建Singleton的對象 ,只能通過getInstance()方法來實例化對象。
上面這種情況在多線程是也有可能創建出多個對象,
下面是多線程時的改進。

public class Singleton {private Singleton(){}private static Singleton singleton=null;public static Singleton getInstance(){if (singleton ==null){synchronized (Singleton.class){if (singleton ==null){singleton= new Singleton();}}}return singleton;} }

這里利用synchronized 同步鎖,并進行非空雙重校驗。
2、餓漢式單例
餓漢式單例模式,初始化時就已經實例化對象。

public class Singleton {private Singleton(){}private static final Singleton singleton=new Singleton();public static Singleton getInstance(){return singleton;} }

餓漢式在類創建的同時就已經創建好一個靜態對象供系統使用,以后就不會變化,所以始終是線程安全的。
餓漢式和懶漢式區別
餓漢式就是類一旦加載,單例初始化就完成了,保證在調用getInstance方法的時候,單例已經存在了;而懶漢式,只在調用getInstance方法的時候才去實例化對象。
實際項目中的應用
例如A系統要通過接口去訪問B系統進行數據交互,但是在訪問B系統之前要先登錄,為了避免在A項目中出現多個登錄對象,這個時候就可以使用單例模式將B的登錄對象設置成單例。這樣可以保證一個應用上面有一個登錄實例,但是在集群的環境下,還是會出現多個登錄對象。
(2)工廠模式
定義:定義一個創建對象的接口,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創建過程延遲到子類進行。
類圖:

(1)新建Shape接口

public interface Shape {public void draw(); }

(2)新建Circle類

public class Circle implements Shape{@Overridepublic void draw() {System.out.println("I am Circle");} }

(3)新建Square類

public class Square implements Shape{@Overridepublic void draw() {System.out.println("I am Square");} }

(4)新建Rectangle

public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("I am Rectangle");} }

(5)新建ShapeFactory類

public class ShapeFactory{public Shape getShape(String shapeType){if ("CIRCLE".equals(shapeType)) {return new Circle();}else if ("SQUARE".equals(shapeType)) {return new Square();}else if ("RECTANGLE".equals(shapeType)) {return new Rectangle();}return null;} }

然后調用寫一個test類來測試一下

public class factoryTest { public static void main(String[] args) {ShapeFactory shapeFactory=new ShapeFactory();Shape shape= shapeFactory.getShape("CIRCLE");shape.draw(); } }

打印的結果是I am Circle。
還有抽象工廠模式,實際是就是對ShapeFactory進行了抽象,這里就不在介紹。
實際項目中的應用
工廠模式在實際項目中的應用會結合后面的策略模式和模板模式一起比較著來介紹。
(3)適配器模式
定義:是作為兩個不兼容的接口之間的橋梁。
類圖:上圖為對象型適配器模式的類圖,
1、Client(客戶端):外部使用程序;
2、Target(目標抽象類):定義用戶需要的相關接口,作為接口或者抽象類存在;
3、Adaptee(適配者):要被適配的角色,定義類一系列的接口,實現用戶需要的一些業務功能;
4、Adapter(適配器):將Adaptee適配到Target上,適配器通常繼承目標抽象類,并通過組合(本實例)或者實現適配者接口,從而實現了目標類和適配者之間形成關聯關系。
實際項目中的應用
適配器模式在對一些老的項目進行改造升級時很有用,之前在做項目時要對用戶登錄驗證方式進行改造,以前用戶登錄都是通過CAS,改造后要通過統一用戶管理系統對用戶進行驗證和管理,在這個過程中有本系統的LocalRedisServer和統一用戶管理系統的RemoteRedisServer,為了將這二種結合起來使用,就采用了適配器模式,使用新的AdapterRedisServer從而將問題解決。
(4)裝飾模式
定義:動態地給一個對象添加一些額外的職責。
類圖:
裝飾者模式中的角色有:
1、抽象構建(Component)角色:抽象接口,被裝飾對象的接口;
2、具體構建(ConcreateComponent)角色:被裝飾的實際對象;
3、裝飾(Decorator)角色:裝飾者接口;
4、具體裝飾(ConcreateComponent)角色:裝飾者對象;
(1)新建Component

public interface Component {void sampleOperation(); }

(2)新建ConcreateComponent

public class ConcreateComponent implements Component {@Overridepublic void sampleOperation() {System.out.println("I am Component object");} }

(3)新建Decorator

public class Decorator implements Component {private Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void sampleOperation() {component.sampleOperation();} }

(4)新建ConcreateDecoratorA

public class ConcreateDecoratorA extends Decorator {public ConcreateDecoratorA(Component component) {super(component);}@Overridepublic void sampleOperation() {super.sampleOperation();System.out.println("裝飾附加業務功能!");} }

(5)新建test

public class test {public static void main(String[] args) {Component component = new ConcreateComponent();ConcreateDecoratorA concreateDecoratorA = new ConcreateDecoratorA(component);concreateDecoratorA.sampleOperation();} }

測試結果為:

I am Component object 裝飾附加業務功能!

裝飾器模式就是在不改變原結構的基礎之上,對原結構添加新的功能,這種設計模式在對項目升級改造或者需求變更的時候很有用處。
(5)代理模式
定義:代理模式給某一個對象提供一個代理對象,并由代理對象控制對原對象的引用。通俗的來講代理模式就是我們生活中常見的中介。
1、靜態代理
靜態代理是指預先確定了代理與被代理者的關系。那映射到編程領域的話,就是指代理類與被代理類的依賴關系在編譯期間就確定了。
類圖:
(1)新建一個subject接口

public interface subject {public void method(); }

(2)新建realSubject

public class realSubject implements subject {@Overridepublic void method() {System.out.println("realSubject");} }

(3)新建proxySubject

public class proxySubject implements subject {private subject subject;@Overridepublic void method() {if (subject == null) {subject = new realSubject();}subject.method();} }

(4)新建測試類

public class staticProxyTest {public static void main(String[] args) {proxySubject proxySubject = new proxySubject();proxySubject.method();} }

這樣就可以通過代理類proxySubject 來調用實際類realSubject。
2、動態代理
動態代理:代理類并不是在java代碼中定義的,而是在運行時動態創建的。
動態代理簡單實現
在java的java.lang.reflect包下面提供了一個Proxy類和一個InvocationHandler接口,通過這個類和接口可以生成JDK動態代理類和動態代理對象。
InvocationHandler接口是給動態代理類實現的,負責處理被代理對象的操作的,而proxy是用來創建動態代理類實例對象的,因為只有得到了這個對象我們才能調用哪些需要代理的方法。
動態代理的實現以訴訟代理為例。
(1)創建一個訴訟接口ILawSuit

public interface ILawSuit {void submit(String proof);//提起訴訟void defend();//法庭辯護 }

(2)新建代理類LitigationCategory

public class LitigationCategory implements ILawSuit{@Overridepublic void submit(String proof) {System.out.println("提起訴訟!"+proof);}@Overridepublic void defend() {System.out.println("辯護"); } }

(3)新建動態代理類DynProxyLawyer

public class DynProxyLawyer implements InvocationHandler{private Object target;public DynProxyLawyer(Object obj) {this.target=obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("案件進展"+method.getName());Object res=method.invoke(target, args);return res;} }

(4)新建動態代理工廠類

public class ProxyFactory {public static Object getDynProxy(Object target){InvocationHandler handler=new DynProxyLawyer(target);return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),handler);} }

(5)新建測試類

public class DynTest { public static void main(String[] args) {ILawSuit proxy=(ILawSuit) ProxyFactory.getDynProxy(new LitigationCategory());proxy.submit("動態代理");proxy.defend(); } }

測試結果:

案件進展submit 提起訴訟!動態代理 案件進展defend 辯護

以上是jdk的動態代理,jdk提供的動態代理伊依賴接口,首先使用接口定義好操作規范。然后通過Proxy類產生的代理對象調用被代理對象的操作,而這個操作又被分發給InvocationHandler接口的invoke方法具體執行。
cglib的動態代理實現
由于jdk只能針對實現了接口的類做動態代理,而不能對沒有實現接口的類做動態代理,所以就有了cglib。cglib是一個強大、高性能的code生成類庫,它可以在程序運行期間動態擴展類和接口,他的底層實現是使用java字節碼操作SAM。這里就不在展開舉例了。
動態代理的實際運用:輸出日志,賬本溯源,性能監控等。
(6)模板模式
定義:完成一組算法,需要分多個步驟,每個步驟根據對象的不同,而實現細節不同,就可以在父類中定義一個完成該事情的總方法,按照完成事件需要的步驟去調用其每個步驟的實現。每個步驟的具體的實現,由子類完成。
類圖:
(1)定義Template接口

public abstract class Template {protected void dodish() {this.pre();this.dojob();this.last();}public abstract void pre();public abstract void dojob();public abstract void last(); }

(2)定義Cake類

public class Cake extends Template {@Overridepublic void pre() {System.out.println("cake pre");}@Overridepublic void dojob() {System.out.println("cake dojob");}@Overridepublic void last() {System.out.println("cake alst");}}

(3)定義Bread類

public class Bread extends Template {@Overridepublic void pre() {System.out.println("Bread pre");}@Overridepublic void dojob() {System.out.println("Bread dojob");}@Overridepublic void last() {System.out.println("Bread last");}}

(4)定義模板模式測試類

public class TemplateTest { public static void main(String[] args) {Template template=new Cake();template.dodish();Template template2=new Bread();template2.dodish(); }

測試結果:

cake pre cake dojob cake alst Bread pre Bread dojob Bread last

模板模式在實際項目運用中很容易和策略模式混淆,主要是看完成一個事情是不是分多個步驟,而且都需要延遲到子類中完成。如果只有一個步驟那么就可考慮采用策略模式。
(7)策略模式
定義:將一組算法封裝到鞠具有共同接口的獨立的類中。
類圖:

(1)實現Strategy接口

public interface Strategy {void calc(int num1,int num2); }

(2)實現AddStrategy

public class AddStrategy implements Strategy{@Overridepublic void calc(int num1, int num2) {System.out.println("和: "+(num1+num2));} }

(3)實現SubStrategy

public class SubStrategy implements Strategy {@Overridepublic void calc(int num1, int num2) {System.out.println("減: "+(num1 - num2));} }

(4)新建測試類

public class testStrategy {public static void main(String[] args) {Strategy strategy = new AddStrategy();strategy.calc(3, 2);Strategy strategy2 = new SubStrategy();strategy2.calc(3, 2);} }

測試結果:

和: 5 減: 1

策略模式的應用
策略模式在系統中用的比較多,就個人目前的經驗來看已經在2個大型系統的核心模塊中使用了,一個是費用報銷系統中生成憑證,這里不同的報賬類型生成憑證的算法是不一樣,但都可以抽象為生成憑證;另外一種是在一個考核系統中不同的考核指標計算考核分數是不一樣的,但都可以抽象為績效考核分數計算,在實際的運用中會比較復雜,就績效考核項目中由于數據源不一致還采用了泛型。
(8)觀察者模式
定義:觀察者模式定義了一個一對多的依賴關系,讓一個或多個觀察者對象監聽一個主題對象。這樣一來,當被觀察者狀態發生改變時,需要通知相應的觀察者,使這些觀察者對象能夠自動更新。
類圖:
觀察者模式的實現:
(1)新建一個Observer,Observer是觀察者對象的接口

public interface Observer {void update(float price); }

(2)新建一個Person,Person為觀察者實際對象

public class Person implements Observer {private String name;public Person(String name) {this.name = name;}@Overridepublic void update(float price) {System.out.println(name + "價格更新為:" + price);} }

(3)新建一個被觀察者對象接口Observable

public interface Observable {// 注冊一個觀察者public void registerObserver(Observer observer);// 取消觀察者public void removeObserver(Observer observer);// 通知所有觀察者public void notifyObservers(); }

(4)新建一個被觀察者實際對象Cup

public class Cup implements Observable {// 被觀察者對象private Vector<Observer> vector = new Vector<>();private float price;public Cup(float price) {this.price = price;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;notifyObservers();}// 注冊觀察者@Overridepublic void registerObserver(Observer observer) {vector.add(observer);}// 刪除觀察者@Overridepublic void removeObserver(Observer observer) {vector.remove(observer);}// 通知觀察者@Overridepublic void notifyObservers() {for (Observer observer : vector) {observer.update(price);}}}

(5)新建一個觀察者模式測試類ObserverTest

public class ObserverTest {public static void main(String[] args) {// 創建一個被觀察者對象Cup cup = new Cup(30);// 創建2個觀察者Person person1 = new Person("person1");Person person2 = new Person("person2");// 注冊觀察者cup.registerObserver(person1);cup.registerObserver(person2);// 價額變動通知觀察者cup.setPrice(2);} }

(9)委托模式
定義:有兩個對象參與處理同一個請求,接受請求的對象將請求委托給另一個對象來處理。
簡單委托模式實現:
(1)新建RealPrinter

public class RealPrinter {public void print() {System.out.println("RealPrinter is run");} }

(2)新建Printer類

public class Printer {RealPrinter realPrinter = new RealPrinter();public void print() {realPrinter.print();} }

(3)新建Test類

public class Test {public static void main(String[] args) {Printer printer = new Printer();printer.print();} }

執行結果:

RealPrinter is run

以上只是簡單介紹了常用的設計模式的類圖,并根據類圖給出了一定的實例和應用的場景,在實際的運用中情況可能會很復雜,比如多個設計模式聯合使用,例如工廠模式+策略模式一起用來解決一組算法問題等等,所以我們需要對常用的設計模式比較了解,然后才能做到在項目中靈活運用,好的代碼結構是需要不停雕琢的。本次設計模式的講解就到此為止,不足之處還請大家批評指正。本文在寫作過程中借鑒了其他博客的內容,沒有一一列出,在此表示感謝。
未完待續,下一篇會重點介紹不同設計模式的比較。

總結

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

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