Java設計模式(一)普通工場模式 抽象工場模式

設計模式

設計模式是前人總結的,爲了解決一類問題而總結的代碼設計經驗。最初可能爲了使用而使用,後面就會發現,很多沒想到的問題因爲使用了正確的設計模式已經爲你考慮到了。《design patterns設計模式》這本書是程序員進階必學。

(一)工廠模式  

工廠模式的意義在於定義一個用於創建對象的接口,並控制返回哪個類的實例。網上比較流行的一個普通工廠模式的例子。

interface Sender{
	public void send();
}
class MainSender implements Sender{
	public void send (){
		System.out.println("MainSender");
	}
}
class SnsSender implements Sender{
	public void send(){
		System.out.println("SnsSender");
	}
}
class SendFactory{
	public Sender product(String type){
		if("Main".equals(type)){
			return new MainSender();
		}else if("Sns".equals(type)){
			return new SnsSender();
		}else{
			System.out.println("請輸入正確類型");
			return null;
		}
	}
}
public class Factory {
	public static void main(String[] args){
		SendFactory factory = new SendFactory();
		Sender sender = factory.product("Main");
		sender.send();
	}
}
但是個人感覺這個沒啥用處。在《java設計模式》中對於工廠模式的定義感覺比較好,工廠模式使得客戶端代碼無須關心使用哪個類的實例,但是上面的例子需要調用者決定返回哪個類的實例。工廠模式不僅要求有一個能夠創建新對象的方法,還要讓客戶代碼無須瞭解具體實例化的類。返回的相同的抽象類型,但實際實例化了不同的類,由哪個類實例化取決於工廠對象接收創建請求時的行爲。所以我的理解是,工廠模式的意圖是讓服務的提供者確定實例化哪個類,而不是客戶代碼。修改下上面的代碼。

interface Sender{
	public void send();
}
class MainSender implements Sender{
	public void send (){
		System.out.println("MainSender");
	}
}
class SnsSender implements Sender{
	public void send(){
		System.out.println("SnsSender");
	}
}
class SendFactory{
	public int day = 0;
	public SendFactory(){
		day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
	}
	public Sender product(){
		if(day%2 == 0){
			return new MainSender();
		}else{
			return new SnsSender();
		}
	}
}
public class Factory {
	public static void main(String[] args){
		SendFactory factory = new SendFactory();
		Sender sender = factory.product();
		sender.send();
	}
}
(二)抽象工廠模式

抽象工廠相比於上面的工廠模式,多了一個抽象接口就是,上面的工廠類是無法擴展的,如果要擴展必須修改工廠類,違背閉包原則。如果將工廠也抽象出來就是一個抽象工廠模式,需要擴展時候直接擴展一個新的工廠。

優點:1、封裝性好,產品實現類高層模塊不關係,只要找到合適的工廠類。2、產品族內約束爲非公開。

缺點:擴展困難,添加一個新工廠,並且新工廠需要一個新接口,那麼需要修改抽象類接口,而且前面的每個工廠也要相應的修改。所以對於抽象工廠模式橫向擴展簡單,縱向擴展困難。在使用的時候可以注意。

interface Sender{
	public void send();
}
interface Provider{
	public Sender product();
}
class MainSender implements Sender{
	public void send (){
		System.out.println("MainSender");
	}
}
class SnsSender implements Sender{
	public void send(){
		System.out.println("SnsSender");
	}
}
class SendMainFactory implements Provider{
	public int day = 0;
	public SendMainFactory(){
		day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
	}
	public Sender product(){
		if(day%2 == 0){
			return new MainSender();
		}
		return null;
	}
}
class SendSnsFactory implements Provider{
	public int day = 0;
	public SendSnsFactory(){
		day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
	}
	public Sender product(){
		if(day%2 == 0){
			return new SnsSender();
		}
		return null;
	}
}
public class Factory {
	public static void main(String[] args){
		Provider factory = new SendSnsFactory();
		Sender sender = factory.product();
		sender.send();
	}
}
上面的例子,如果增加一個新工廠只要新建一個工廠繼承Provider ,擴展很簡單,但是如果需要增加Provider的接口,那麼
SendMainFactory
SendSnsFactory
也要相應修改。




發佈了58 篇原創文章 · 獲贊 14 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章