溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

常用的web設(shè)計模式有哪些

發(fā)布時間:2021-11-15 15:50:03 來源:億速云 閱讀:179 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹“常用的web設(shè)計模式有哪些”,在日常操作中,相信很多人在常用的web設(shè)計模式有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”常用的web設(shè)計模式有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

單例模式

簡單點說,就是一個應(yīng)用程序中,某個類的實例對象只有一個,你沒有辦法去new,因為構(gòu)造器是被private修飾的,一般通過getInstance()的方法來獲取它們的實例。getInstance()的返回值是一個對象的引用,并不是一個新的實例,所以不要錯誤的理解成多個對象。單例模式實現(xiàn)起來也很容易,直接看demo吧

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

按照我的習(xí)慣,我恨不得寫滿注釋,怕你們看不懂,但是這個代碼實在太簡單了,所以我沒寫任何注釋,如果這幾行代碼你都看不明白的話,那你可以洗洗睡了,等你睡醒了再來看我的博客說不定能看懂。

上面的是最基本的寫法,也叫懶漢寫法(線程不安全)下面我再公布幾種單例模式的寫法:


懶漢式寫法(線程安全)

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

餓漢式寫法

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

靜態(tài)內(nèi)部類

public class Singleton {  
	private static class SingletonHolder {   
		private static final Singleton INSTANCE = new Singleton();  
	}   
	private Singleton (){}  
	public static final Singleton getInstance() { 
		return SingletonHolder.INSTANCE;  
	} 
}

枚舉

public enum Singleton {    
	INSTANCE;   
	public void whateverMethod() { }  
}

這種方式是Effective Java作者Josh Bloch 提倡的方式,它不僅能避免多線程同步問題,而且還能防止反序列化重新創(chuàng)建新的對象,可謂是很堅強的壁壘啊,不過,個人認為由于1.5中才加入enum特性,用這種方式寫不免讓人感覺生疏。


雙重校驗鎖

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

總結(jié):我個人比較喜歡靜態(tài)內(nèi)部類寫法和餓漢式寫法,其實這兩種寫法能夠應(yīng)付絕大多數(shù)情況了。其他寫法也可以選擇,主要還是看業(yè)務(wù)需求吧。

觀察者模式

對象間一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。

常用的web設(shè)計模式有哪些

觀察者模式UML圖

看不懂圖的人端著小板凳到這里來,給你舉個栗子:假設(shè)有三個人,小美(女,28),老王和老李。小美很漂亮,很風(fēng)騷,老王和老李是兩個中年男屌絲,時刻關(guān)注著小美的一舉一動。有一天,小美說了一句:我老公今天不在家,一個人好無聊啊~~~,這句話被老王和老李聽到了,結(jié)果樂壞了,蹭蹭蹭,沒一會兒,老王就沖到小美家門口了,于是進門了…………………….. 帕啪帕啪啪~ 在這里,小美是被觀察者,老王和老李是觀察者,被觀察者發(fā)出一條信息,然后觀察者們進行相應(yīng)的處理,看代碼:

public interface Person { 
//老王和老李通過這個接口可以接收到小美發(fā)過來的消息   
	void getMessage(String s);
}

這個接口相當(dāng)于老王和老李的電話號碼,小美發(fā)送通知的時候就會撥打getMessage這個電話,撥打電話就是調(diào)用接口,看不懂沒關(guān)系,先往下看

public class LaoWang implements Person { 
	private String name = "老王";  
	public LaoWang() {    }   
 	@Override  
	public void getMessage(String s) {   
		System.out.println(name + "接到了小美打過來的電話,電話內(nèi)容是:" + s);  
	} 
} 
	public class LaoLi implements Person {  
	private String name = "老李"; 
	public LaoLi() {    }  
	@Override  
	public void getMessage(String s) {  
		System.out.println(name + "接到了小美打過來的電話,電話內(nèi)容是:->" + s);  
	} 
}

代碼很簡單,我們再看看小美的代碼:

public class XiaoMei {  
	List<Person> list = new ArrayList<Person>();   
	public XiaoMei(){     }   
	public void addPerson(Person person){   
		list.add(person); 
	}    
//遍歷list,把自己的通知發(fā)送給所有暗戀自己的人  
	public void notifyPerson() {   
		for(Person person:list){     
			person.getMessage("今天家里就我一個人,你們過來吧,誰先過來誰就能得到我!");   
		}   
	}
}

我們寫一個測試類來看一下結(jié)果對不對

public class Test {  
	public static void main(String[] args) {  
		XiaoMei xiao_mei = new XiaoMei();    
		LaoWang lao_wang = new LaoWang();    
		LaoLi lao_li = new LaoLi();   
		//老王和老李在小美那里都注冊了一下  
		xiao_mei.addPerson(lao_wang); 
		xiao_mei.addPerson(lao_li); 
		//小美向老王和老李發(fā)送通知    
		xiao_mei.notifyPerson();   
	}
}

運行結(jié)果我截圖了

常用的web設(shè)計模式有哪些

運行結(jié)果

完美~~~

裝飾者模式

對已有的業(yè)務(wù)邏輯進一步的封裝,使其增加額外的功能,如Java中的IO流就使用了裝飾者模式,用戶在使用的時候,可以任意組裝,達到自己想要的效果。 舉個栗子,我想吃三明治,首先我需要一根大大的香腸,我喜歡吃奶油,在香腸上面加一點奶油,再放一點蔬菜,最后再用兩片面包夾一下,很豐盛的一頓午飯,營養(yǎng)又健康。(ps:不知道上海哪里有賣好吃的三明治的,求推薦~)那我們應(yīng)該怎么來寫代碼呢? 首先,我們需要寫一個Food類,讓其他所有食物都來繼承這個類,看代碼:

public class Food {   
	private String food_name;  
	public Food() {    }   
	public Food(String food_name) {   
		this.food_name = food_name; 
	}    
	public String make() {    
		return food_name;  
	};
}

代碼很簡單,我就不解釋了,然后我們寫幾個子類繼承它:

//面包類
public class Bread extends Food { 
	private Food basic_food;   
	public Bread(Food basic_food) {  
		this.basic_food = basic_food;  
	}   
	public String make() { 
		return basic_food.make()+"+面包"; 
	}
} 
//奶油類
public class Cream extends Food {  
	private Food basic_food;  
	public Cream(Food basic_food) {  
		this.basic_food = basic_food;  
	}  
	public String make() {  
		return basic_food.make()+"+奶油"; 
	}
} 
//蔬菜類
public class Vegetable extends Food {
	private Food basic_food;   
	public Vegetable(Food basic_food) { 
		this.basic_food = basic_food; 
	}    
	public String make() { 
		return basic_food.make()+"+蔬菜"; 
	} 
}

這幾個類都是差不多的,構(gòu)造方法傳入一個Food類型的參數(shù),然后在make方法中加入一些自己的邏輯,如果你還是看不懂為什么這么寫,不急,你看看我的Test類是怎么寫的,一看你就明白了

public class Test { 
	public static void main(String[] args) { 
		Food food = new Bread(new Vegetable(new Cream(new Food("香腸"))));        				System.out.println(food.make()); 
	}
}

看到?jīng)]有,一層一層封裝,我們從里往外看:最里面我new了一個香腸,在香腸的外面我包裹了一層奶油,在奶油的外面我又加了一層蔬菜,最外面我放的是面包,是不是很形象,哈哈...這個設(shè)計模式簡直跟現(xiàn)實生活中一摸一樣,看懂了嗎? 我們看看運行結(jié)果吧

常用的web設(shè)計模式有哪些

運行結(jié)果

一個三明治就做好了~~~

適配器模式

將兩種完全不同的事物聯(lián)系到一起,就像現(xiàn)實生活中的變壓器。假設(shè)一個手機充電器需要的電壓是20V,但是正常的電壓是220V,這時候就需要一個變壓器,將220V的電壓轉(zhuǎn)換成20V的電壓,這樣,變壓器就將20V的電壓和手機聯(lián)系起來了。

public class Test { 
	public static void main(String[] args) {  
		Phone phone = new Phone();     
		VoltageAdapter adapter = new VoltageAdapter();   
		phone.setAdapter(adapter);     
		phone.charge();  
	}
} 
// 手機類
class Phone { 
	public static final int V = 220;
// 正常電壓220v,是一個常量 
	private VoltageAdapter adapter; 
// 充電   
	public void charge() {   
		adapter.changeVoltage(); 
	}    
	public void setAdapter(VoltageAdapter adapter) { 
		this.adapter = adapter;   
	}
}
// 變壓器
class VoltageAdapter {  
// 改變電壓的功能  
	public void changeVoltage() {  
		System.out.println("正在充電...");   
		System.out.println("原始電壓:" + Phone.V + "V");   
		System.out.println("經(jīng)過變壓器轉(zhuǎn)換之后的電壓:" + (Phone.V - 200) + "V");  
	}
}

常用的web設(shè)計模式有哪些

工廠模式

簡單工廠模式:一個抽象的接口,多個抽象接口的實現(xiàn)類,一個工廠類,用來實例化抽象的接口

// 抽象產(chǎn)品類
abstract class Car { 
	public void run();  
	public void stop();
} 
// 具體實現(xiàn)類
class Benz implements Car {  
	public void run() { 
		System.out.println("Benz開始啟動了。。。。。");  
	}  
	public void stop() {  
		System.out.println("Benz停車了。。。。。"); 
	}
}
class Ford implements Car { 
	public void run() {   
		System.out.println("Ford開始啟動了。。。");   
	}    
	public void stop() { 
		System.out.println("Ford停車了。。。。");  
	}
} 
// 工廠類
class Factory {  
	public static Car getCarInstance(String type) {  
		Car c = null;   
	if ("Benz".equals(type)) {   
		c = new Benz();     
	}      
	if ("Ford".equals(type)) {  
		c = new Ford();     
	}     
		return c; 
	}
}
public class Test {  
	public static void main(String[] args) {  
		Car c = Factory.getCarInstance("Benz");   
	if (c != null) {   
		c.run();    
		c.stop();   
	} else {      
		System.out.println("造不了這種汽車。。。");   
	}  
}
}

工廠方法模式:有四個角色,抽象工廠模式,具體工廠模式,抽象產(chǎn)品模式,具體產(chǎn)品模式。不再是由一個工廠類去實例化具體的產(chǎn)品,而是由抽象工廠的子類去實例化產(chǎn)品

// 抽象產(chǎn)品角色
	public interface Moveable {
		void run();
	} 
// 具體產(chǎn)品角色
public class Plane implements Moveable {   
	@Override  
    public void run() {   
		System.out.println("plane....");  
	}
} 
public class Broom implements Moveable { 
	@Override 
	public void run() {  
		System.out.println("broom.....");
	}
} 
// 抽象工廠
	public abstract class VehicleFactory { 
		abstract Moveable create();
	} 
// 具體工廠
public class PlaneFactory extends VehicleFactory { 
	public Moveable create() {   
		return new Plane(); 
	}
} 
public class BroomFactory extends VehicleFactory { 
	public Moveable create() {    
		return new Broom();  
	}
} 
// 測試類
public class Test {   
	public static void main(String[] args) {   
		VehicleFactory factory = new BroomFactory();   
		Moveable m = factory.create();  
		m.run(); 
	}
}

抽象工廠模式:與工廠方法模式不同的是,工廠方法模式中的工廠只生產(chǎn)單一的產(chǎn)品,而抽象工廠模式中的工廠生產(chǎn)多個產(chǎn)品

/抽象工廠類
public abstract class AbstractFactory {  
	public abstract Vehicle createVehicle();  
	public abstract Weapon createWeapon();  
	public abstract Food createFood();
}
//具體工廠類,其中Food,Vehicle,Weapon是抽象類,
public class DefaultFactory extends AbstractFactory{ 
	@Override  
	public Food createFood() {   
		return new Apple(); 
	}   
	@Override   
	public Vehicle createVehicle() { 
		return new Car();  
	}  
	@Override   
	public Weapon createWeapon() {  
		return new AK47();  
	}
}
//測試類
public class Test {  
	public static void main(String[] args) { 
		AbstractFactory f = new DefaultFactory();   
		Vehicle v = f.createVehicle();    
		v.run();   
		Weapon w = f.createWeapon(); 
		w.shoot();  
		Food a = f.createFood(); 
		a.printName();
	}
}

代理模式(proxy)

有兩種,靜態(tài)代理和動態(tài)代理。先說靜態(tài)代理,很多理論性的東西我不講,我就算講了,你們也看不懂。什么真實角色,抽象角色,代理角色,委托角色。。。亂七八糟的,我是看不懂。之前學(xué)代理模式的時候,去網(wǎng)上翻一下,資料一大堆,打開鏈接一看,基本上都是給你分析有什么什么角色,理論一大堆,看起來很費勁,不信的話你們可以去看看,我是看不懂他們在說什么。咱不來虛的,直接用生活中的例子說話。(注意:我這里并不是否定理論知識,我只是覺得有時候理論知識晦澀難懂,喜歡挑刺的人一邊去,你是來學(xué)習(xí)知識的,不是來挑刺的) 到了一定的年齡,我們就要結(jié)婚,結(jié)婚是一件很麻煩的事情,(包括那些被父母催婚的)。有錢的家庭可能會找司儀來主持婚禮,顯得熱鬧,洋氣~好了,現(xiàn)在婚慶公司的生意來了,我們只需要給錢,婚慶公司就會幫我們安排一整套結(jié)婚的流程。整個流程大概是這樣的:家里人催婚->男女雙方家庭商定結(jié)婚的黃道即日->找一家靠譜的婚慶公司->在約定的時間舉行結(jié)婚儀式->結(jié)婚完畢 婚慶公司打算怎么安排婚禮的節(jié)目,在婚禮完畢以后婚慶公司會做什么,我們一概不知。。。別擔(dān)心,不是黑中介,我們只要把錢給人家,人家會把事情給我們做好。所以,這里的婚慶公司相當(dāng)于代理角色,現(xiàn)在明白什么是代理角色了吧。 代碼實現(xiàn)請看:

//代理接口
public interface ProxyInterface { 
//需要代理的是結(jié)婚這件事,如果還有其他事情需要代理,比如吃飯睡覺上廁所,也可以寫 void marry();
//代理吃飯(自己的飯,讓別人吃去吧)
//void eat(); 
//代理拉屎,自己的屎,讓別人拉去吧 
//void shit();
}

文明社會,代理吃飯,代理拉屎什么的我就不寫了,有傷社會風(fēng)化~~~能明白就好 好了,我們看看婚慶公司的代碼:

public class WeddingCompany implements ProxyInterface { 
	private ProxyInterface proxyInterface; 
	public WeddingCompany(ProxyInterface proxyInterface) {
		this.proxyInterface = proxyInterface;
	} 
	@Override
	public void marry() {  
		System.out.println("我們是婚慶公司的"); 
		System.out.println("我們在做結(jié)婚前的準備工作"); 
		System.out.println("節(jié)目彩排..."); 
		System.out.println("禮物購買..."); 
		System.out.println("工作人員分工..."); 
		System.out.println("可以開始結(jié)婚了"); 
		proxyInterface.marry(); 
		System.out.println("結(jié)婚完畢,我們需要做后續(xù)處理,你們可以回家了,其余的事情我們公司來做"); 
	}
}

看到?jīng)]有,婚慶公司需要做的事情很多,我們再看看結(jié)婚家庭的代碼:

public class NormalHome implements ProxyInterface{ 
	@Override 
	public void marry() {  
		System.out.println("我們結(jié)婚啦~"); 
	}
}

這個已經(jīng)很明顯了,結(jié)婚家庭只需要結(jié)婚,而婚慶公司要包攬一切,前前后后的事情都是婚慶公司來做,聽說現(xiàn)在婚慶公司很賺錢的,這就是原因,干的活多,能不賺錢嗎? 來看看測試類代碼:

public class Test {
	public static void main(String[] args) { 
		ProxyInterface proxyInterface = new WeddingCompany(new NormalHome());  					proxyInterface.marry();
	}
}

運行結(jié)果如下:

常用的web設(shè)計模式有哪些

到此,關(guān)于“常用的web設(shè)計模式有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

web
AI