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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

java的几个设计模式

發(fā)布時間:2023/12/10 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java的几个设计模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1.簡單工廠
  • 2.工廠模式:
  • 3.單例模式
  • 適配器模式
  • 裝飾器模式
  • 代理模式

1.簡單工廠

又叫做靜態(tài)工廠方法(StaticFactory Method)模式,但不屬于23種GOF設(shè)計模式之一。

簡單工廠模式的實質(zhì)是由一個工廠類根據(jù)傳入的參數(shù),動態(tài)決定應(yīng)該創(chuàng)建哪一個產(chǎn)品類。

spring中的BeanFactory就是簡單工廠模式的體現(xiàn),根據(jù)傳入一個唯一的標(biāo)識來獲得bean對象,但是否是在傳入?yún)?shù)后創(chuàng)建還是傳入?yún)?shù)前創(chuàng)建這個要根據(jù)具體情況來定。如下配置,就是在 HelloItxxz 類中創(chuàng)建一個 itxxzBean。

<beans><bean id="singletonBean" class="com.itxxz.HelloItxxz"><constructor-arg><value>Hello! 這是singletonBean!value></constructor-arg></ bean><bean id="itxxzBean" class="com.itxxz.HelloItxxz" singleton="false"><constructor-arg><value>Hello! 這是itxxzBean! value></constructor-arg></bean> </beans>

2.工廠模式:

簡介:
工廠模式(Factory Pattern)是java中最常用的設(shè)計模式之一。這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。
在工廠模式中,我們在創(chuàng)建對象時不會對客戶端暴露創(chuàng)建邏輯,并且是通過使用一個共同的接口來指向新創(chuàng)建的對象。
意圖:
定義一個創(chuàng)建對象的接口,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創(chuàng)建過程延遲到子類進行。

主要解決:
主要解決接口選擇的問題。

何時使用:
明確地計劃不同條件下創(chuàng)建不同實例時。

如何解決:
讓其子類實現(xiàn)工廠接口,返回的也是一個抽象的產(chǎn)品。

關(guān)鍵代碼:
創(chuàng)建過程在其子類執(zhí)行。

應(yīng)用實例:
1、你需要一輛汽車,可以直接沖工廠里面提貨,而不同去管這輛汽車時怎么做出來的,以及這個汽車?yán)锩娴木唧w實現(xiàn)。2、Hibernate換數(shù)據(jù)庫只需要換方言和驅(qū)動就可以。

優(yōu)點:
1、一個調(diào)用者想創(chuàng)建一個對象,只要知道其名稱就可以了。2、擴展性高,如果想增加一個產(chǎn)品,只要擴展一個工廠類就可以。3、屏蔽產(chǎn)品的具體實現(xiàn),調(diào)用者只關(guān)心產(chǎn)品的接口。

缺點:
每次增加一個產(chǎn)品時,都需要增加要給具體類和對象實現(xiàn)工廠,使得系統(tǒng)中類的個數(shù)成倍增加,在一定程度上增加了系統(tǒng)的復(fù)雜度,同時也增加了系統(tǒng)具體類的依賴。

使用場景:
1、日志記錄器:記錄可能記錄到本地硬盤,系統(tǒng)事件、遠(yuǎn)程服務(wù)器等,用戶可以選擇記錄日志到什么地方。2、數(shù)據(jù)庫訪問,當(dāng)用戶不知道最后系統(tǒng)采用哪一類數(shù)據(jù)庫,以及數(shù)據(jù)庫可能有變化時。3、設(shè)計一個連接服務(wù)器的框架,需要三個協(xié)議,“POP3"、“IMAP”、“HTTP”,可以把這三個作為產(chǎn)品類,共同實現(xiàn)一個接口。

注意事項:
作為一種創(chuàng)建類模式,在任何需要生成復(fù)雜對象的地方,都可以使用工廠方法模式。有一點需要注意的地方就是復(fù)雜對象適合使用工廠模式,而簡單對象,特別時只需要通過new就可以完成創(chuàng)建的對象,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統(tǒng)的復(fù)雜度。

實現(xiàn):

創(chuàng)建一個Shape接口和實現(xiàn)Shape接口的實體類。下一步時定義工廠類ShapeFactory。FactoryPatternDemo類使用ShapeFactory來獲取Shape對象。它將向ShapeFactory傳遞信息,以便獲取它所需對象的類型。

代碼示例:

//創(chuàng)建一個Shape接口 public interface Shape{void draw(); }//實現(xiàn)接口的實體類 public class Rectangle implements Shape{@Overridepublic void draw(){System.out.println("inside rectangle::draw()");} }public class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");} }public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");} } //創(chuàng)建一個工廠,生成基于給定信息的實體類的對象public class ShapeFactory {//使用 getShape 方法獲取形狀類型的對象public Shape getShape(String shapeType){if(shapeType == null){return null;} if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}return null;} } //使用該工廠,通過傳遞類型信息來獲取實體類的對象 public class FactoryPatternDemo {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();//獲取 Circle 的對象,并調(diào)用它的 draw 方法Shape shape1 = shapeFactory.getShape("CIRCLE");//調(diào)用 Circle 的 draw 方法shape1.draw();//獲取 Rectangle 的對象,并調(diào)用它的 draw 方法Shape shape2 = shapeFactory.getShape("RECTANGLE");//調(diào)用 Rectangle 的 draw 方法shape2.draw();//獲取 Square 的對象,并調(diào)用它的 draw 方法Shape shape3 = shapeFactory.getShape("SQUARE");//調(diào)用 Square 的 draw 方法shape3.draw();} }

3.單例模式

單例模式是java中最簡單的設(shè)計模式之一。這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。這種模式涉及到一個單一的類,該負(fù)責(zé)創(chuàng)建自己的對象,同時確保只有單個對象被創(chuàng)建。這個類提供了一種訪問其唯一的對象方式,可以直接訪問,不需要實例化該類的對象。

注意:

單例類只能有一個實例。
單例類必須自己創(chuàng)建自己的唯一實例。
單例類必須給所有其他對象提供這一實例。

意圖:
保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。

主要解決:
一個全局使用的類頻繁地創(chuàng)建于銷毀。

何時使用:
需要控制實例數(shù)目,節(jié)省系統(tǒng)資源的時候。

如何解決:
判斷系統(tǒng)是否已經(jīng)有這個單例,如果有則返回,如果沒有則創(chuàng)建。

關(guān)鍵代碼:
構(gòu)造函數(shù)是私有的。

應(yīng)用實例:

一個班級只有一個班主任。
Windows是進程多線程的,在操作一個文件的時候,就不可避免地出現(xiàn)多個進程或線程同時操作一個文件的現(xiàn)象,所有有文件的處理必須通過唯一的實例來進行。
一些設(shè)備管理器常常設(shè)計為單例模式,比如一個電腦有兩臺打印機,在輸出的時候就要處理不能兩臺打印機打印同一個文件。
優(yōu)點:
在內(nèi)存里只有一個實例,減少了內(nèi)存的開銷,尤其是頻繁的創(chuàng)建和銷毀實例(比如管理學(xué)院首頁頁面緩存)。
避免對資源的多重占用(比如寫文件操作)。

缺點:
沒有接口,不能繼承,與單一職責(zé)原則沖突,一個類應(yīng)該只關(guān)心內(nèi)部邏輯,而不關(guān)心外面怎么樣來實例化。

使用場景:
要求生產(chǎn)唯一序列號。
WEB中的計數(shù)器,不用每次刷新都在數(shù)據(jù)庫里加一次,用單例先緩存起來。
創(chuàng)建的一個對象需要消耗的資源過多,比如I/O與數(shù)據(jù)庫的連接等。
注意事項:getInstance()方法中需要使用同步鎖synchronized(Singleton.class)防止多線程同時進入造成instance被多次實例化。

實現(xiàn):
創(chuàng)建一個SingleObject類。SingleObject類有它的私有構(gòu)造函數(shù)和本身一個靜態(tài)實例。

SingleObject類提供了一個靜態(tài)方法,供外界獲取它的靜態(tài)實例。SingletonPatternDemo類使用SingleObject類來獲取SingleObject對象。

流程:

代碼:

//創(chuàng)建一個Singleton類 //SingleObject.java public class SingleObject{//創(chuàng)建SingleObject的一個對象private static SingleObject instance = new SingleObject();//讓構(gòu)造函數(shù)為private,這樣該類就不會被實例化private SingleObject(){}//獲取唯一可用的對象public static SingleObject getInstance(){return instance;}public void showMessage(){System.out.println("hello world");} } //從singleton類獲取唯一的對象 //SingletonPatternDemo.java public static void main(String[] args){//獲取唯一可用的對象SingleObject object = SingleObject.getInstance();//顯示消息object.showMessge(); }

適配器模式

適配器模式(Adapter Pattern)是作為兩個不兼容的接口之間的橋梁。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式,它結(jié)合了兩個獨立接口的功能。這種模式涉及到一個單一的類,該類負(fù)責(zé)加入獨立的或不兼容的接口功能。比如,讀卡器是作為內(nèi)存卡和筆記本之間的適配器。將內(nèi)存卡插入讀卡器,再將讀卡器插入筆記本,這樣就可以通過筆記本來讀取內(nèi)存卡。

意圖:
將一個類的接口轉(zhuǎn)換成客戶系統(tǒng)的另外一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。

主要解決:
主要解決在軟件系統(tǒng)中,常常要將一些“現(xiàn)存對象”放到新的環(huán)境中,而新環(huán)境要求的接口是現(xiàn)對象不能滿足的。

何時使用:
系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。
想要建立一個可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定由一致的接口。
通過接口轉(zhuǎn)換,將一個類插入另一個類中,比如老虎和飛禽,現(xiàn)在多了一個飛虎,在不增加實體的需求下,增加一個適配器,在里面包容一個虎對象,實現(xiàn)飛的接口。
如何解決:繼承或依賴

關(guān)鍵代碼
適配器繼承或依賴已有的對象,實現(xiàn)想要的目標(biāo)接口。

應(yīng)用實例:
美國電器110v,中國220v,就需要一個適配器將110v轉(zhuǎn)化為220v。
優(yōu)點:
可以讓任何兩個沒有關(guān)聯(lián)的類一起運行。
提高了類的復(fù)用。
增加了類的透明度。
靈活性好。
缺點:
過多地使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把我。如此如果不是很有必要,可以不適用適配器,而是直接對系統(tǒng)進行重構(gòu)。
由于JAVA至多繼承一個類,所以之多只能適配一個適配者類,而且目標(biāo)類必須是抽象類。
使用場景:有動機地修改一個正常運行的系統(tǒng)的接口,這時應(yīng)該考慮使用適配器模式。

注意事項:
適配器不是在詳細(xì)設(shè)計時添加的,而是解決正在服役的項目的問題。

實現(xiàn)

有一個MediaPlayer接口和一個實現(xiàn)了MediaPlayer接口的實體類AudioPlayer。默認(rèn)情況下,AudioPlayer可以播放map3格式的音頻文件。還有另一個接口AdvancedMediaPlayer和實現(xiàn)了AdvancedMediaPlayer接口的實體類。該類可以播放vlc和mp4格式的文件。

我們想讓AudioPlayer播放其他格式的音頻文件。為了實現(xiàn)這個功能,我們需要創(chuàng)建一個實現(xiàn)了MediaPlayer接口的適配器類MediaAdapter,并使用AdvancedMediaPlayer對象來播放所需的格式。

AudioPlayer使用適配器類MediaAdapter傳遞所需的音頻類型,不需要知道所能播放所需格式音頻的實際類。AdapterPatternDemo類使用AudioPlayer類來播放各種格式。

//為媒體播放器和更高級的媒體播放器創(chuàng)建接口: //MediaPlayer.java public interface MediaPlayer{public void play(String audioType,String fileName); } //AdvancedMediaPlayer.java public interface AdvancedMediaPlayer{public void playVlc(String fileName);public void playMap4(String fileName); } //創(chuàng)建實現(xiàn)了AdvancedMediaPlayer接口的實體類: //VlcPlayer.java public class VlcPlayer implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName){System.out.println("Playing vlc file. Name: "+ fileName); }@Overridepublic void playMp4(String fileName){//do nothing} } //Mp4Player.java public class Mp4Player implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName){//do nothing}@Overridepublic void playMap4(String fileName){System.out.println("Playing mp4 file. Name: "+ fileName); } } //創(chuàng)建實現(xiàn)了MediaPlayer接口的適配器類 //MediaAdapter.java public class MediaAdapter implements MediaPlayer{AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType){if (audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer = new VlcPlayer();}else if (audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer = new Mp4Player();}}@Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer.playVlc(fileName);}else if(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer.playMp4(fileName);}}} //實現(xiàn)了MediaPlayer接口的實體類: //AudioPlayer.java public class AudioPlayer implements MediaPlayer{MediaAdapter mediaAdapter;@Overridepblic void paly(String audioType,String fileName){//播放mp3音樂文件的內(nèi)置支持if (audioType.equalsIgnoreCase("mp3")){System.out.println("playing mp3 file.name:"+fileName);}//mediaAdapter提供了播放其他文件格式的支持else if (audioType.equalsIgnoreCase("vlc")||audioType.equalsIgnoreCase("mp4")){mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType,fileName);}else{System.out.println("Invalid media. "+audioType + " format not supported");}} } //使用AudioPlayer來播放不同類型的音頻格式: //AdapterPatternDemo.java public class AdapterPatternDemo{public static void main(String[] args){AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "beyond the horizon.mp3");audioPlayer.play("mp4", "alone.mp4");audioPlayer.play("vlc", "far far away.vlc");audioPlayer.play("avi", "mind me.avi");} }

執(zhí)行程序,輸出結(jié)果:

Playing mp3 file. Name: beyond the horizon.mp3 Playing mp4 file. Name: alone.mp4 Playing vlc file. Name: far far away.vlc Invalid media. avi format not supported

裝飾器模式

裝飾器模式(Decorator Pattern)允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個包裝。

這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。

意圖:
動態(tài)地給一個對象添加一些額外的職責(zé)。就增加功能來說,裝飾器模式相比生成子類更為靈活。

主要解決:
一般的,為了擴展一個類經(jīng)常使用繼承方式實現(xiàn),由于繼承為類引入靜態(tài)特征,并且隨著擴展功能的增多,子類會很膨脹。

何時使用:
在不想增加很多子類的情況下擴展類。

如何解決:
將具體功能職責(zé)劃分,同時繼承裝飾者模式。

關(guān)鍵代碼:

Commponent類充當(dāng)抽象角色,不應(yīng)該具體實現(xiàn)。
修飾類引用和繼承Commponent類,具體擴展類重寫父類方法。
應(yīng)用實例:
孫悟空有72變,當(dāng)他變成“廟宇”后,他根本上還是一只猴子,但是又有了廟宇的功能。
無論一幅畫有沒有畫框都可以改在墻上,但是通常都是有畫框的,并且實際上是畫框被掛在墻上。在掛在墻上之前,畫可以被蒙上玻璃,裝到框子里;這時畫、玻璃和畫框形成了一個物體。
優(yōu)點:裝飾類和被裝飾類可以獨立發(fā)展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾可以動態(tài)擴展一個實現(xiàn)類的功能。

缺點:
多層裝飾比較復(fù)雜。

使用場景:
擴展一個類的功能。
動態(tài)增加功能,動態(tài)撤銷。
注意事項:可代替繼承。

實現(xiàn):
創(chuàng)建一個Shape接口和實現(xiàn)了Shape接口的實體類。然后創(chuàng)建一個實現(xiàn)了Shape接口的抽象裝飾類ShapeDecorator,并把Shape對象作為它的實例變量。

RedShapeDecorator是實現(xiàn)了ShapeDecorator的實體類。DecoratorPatternDemo類使用RedShapeDecorator來裝飾Shape對象。

//創(chuàng)建Shape接口: //Shape.java public interface Shape{void draw(); } //創(chuàng)建實現(xiàn)Shape接口的實體類: //Rectangle.java public class Rectangle implements Shape{@Overridepublic void draw(){System.out.println("Shape:Rectangle");} } //Circle.java public class Circle implements Shape{@Overridepublic void draw(){System.out.println("Shape: Circle");} } // 創(chuàng)建實現(xiàn)了Shape接口的抽象裝飾類: //ShapeDecorator.java public abstract class ShapeDecorator implements Shape{protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape){this.decoratedShape = decoratedShape;}public void draw(){decoratedShape.draw();} } //創(chuàng)建擴展了ShapeDecorator類的實體裝飾類: //RedShapeDecorator.java public class RedShapeDecorator extends ShapeDecorator{public RedShapeDecorator(Shape decoratedShape){super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw(); setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape){System.out.println("Border Color: Red");} } //使用RedShapeDecorator來裝飾Shape對象 //DecoratorPatternDemo.java pulblic class DecoratorPatternDemo{public class void main(String[] args){Shape circle = new Circle();ShapeDecorator redCircle = new RedShapeDecorator(new Circle());ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());//Shape redCircle = new RedShapeDecorator(new Circle());//Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();} }

執(zhí)行程序,輸出結(jié)果:

Circle with normal border Shape: CircleCircle of red border Shape: Circle Border Color: RedRectangle of red border Shape: Rectangle Border Color: Red

代理模式

在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式。在代理模式中,我們創(chuàng)建具有現(xiàn)有對象的對象,以便向外界提供功能接口。

意圖:
為其他對象提供一種代理以控制對這個對象的訪問。

主要解決:
在直接訪問對象時帶來的問題,比如說:要訪問的對象在遠(yuǎn)程的機器上。在面向?qū)ο笙到y(tǒng)中,有些對象由于某些原因(比如對象創(chuàng)建開銷很大,或者某些曹祖需要安全控制,或者需要進程外的訪問),直接訪問會給使用者或者系統(tǒng)結(jié)構(gòu)帶來很多麻煩,我們可以在訪問此對象時加上一個對此對象的訪問層。

何時使用:
想在訪問一個類時做一些控制。

如何解決:
增加中間層。

關(guān)鍵代碼:
實現(xiàn)與被代理類組合。

應(yīng)用實例:

Windows里面的快捷方式。
豬八戒去找高翠蘭結(jié)果時孫悟空變的,可以這樣理解:把高翠蘭的外貌抽象出來,高翠蘭本人和孫悟空都實現(xiàn)了這個接口,豬八戒訪問高翠蘭的時候看不出來這個是孫悟空,所以所孫悟空是高翠蘭代理類。
買火車票不一定在火車站買,也可以去代售點。
一張支票或銀行存單是賬戶中資金的代理。支票在市場交易中用來代替現(xiàn)金,并提供對簽發(fā)人賬號上資金的控制。
Sping AOP。
優(yōu)點:
職責(zé)清晰。
高擴展性。
智能化。
缺點:
由于在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。
實現(xiàn)代理模式需要額外的工作,有些代理模式的實現(xiàn)非常復(fù)雜。

使用場景:
遠(yuǎn)程代理。
虛擬代理。
Copy-on-Write代理。
保護代理。
Cache代理。
防火墻代理。
同步化代理。
智能引用代理。

注意事項:
和適配器模式的區(qū)別:適配器模式主要改變所考慮對象的接口,而代理模式不能改變所代理類的接口。
和裝飾器模式的區(qū)別:裝飾器模式為了增強功能,而代理模式是為了加以控制

實現(xiàn):
創(chuàng)建一個Image接口和實現(xiàn)了Image接口的實體類。ProxyImage是一個代理類,減少RealImage對象加載的內(nèi)存占用。

ProxyPatternDemo類使用ProxyImage來獲取要加載的Image對象,并按照要求進行顯示。

//創(chuàng)建Image.java接口: //Image.java public interface Image {void display(); } //創(chuàng)建實現(xiàn)接口的實體類: //RealImage.java public class RealImage implements Image {private String fileName;public RealImage(String fileName){this.fileName = fileName;loadFromDisk(fileName);}@Overridepublic void display() {System.out.println("Displaying " + fileName);}private void loadFromDisk(String fileName){System.out.println("Loading " + fileName);} } //當(dāng)被請求時,使用PorxyImage來獲取RealImage類的對象: //ProxyPatternDemo.java public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ProxyImage("test_10mb.jpg");// 圖像將從磁盤加載image.display(); System.out.println("");// 圖像不需要從磁盤加載image.display(); } }

執(zhí)行程序,輸出結(jié)果:

Loadingproxy.png Displayingproxy.pngDisplayingproxy.png

參考

總結(jié)

以上是生活随笔為你收集整理的java的几个设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。