1. 程式人生 > 程式設計 >從買車到工廠設計模式(三件套)

從買車到工廠設計模式(三件套)

上文回顧:

簡單工廠模式連結:juejin.im/post/5d4d39…

簡單工廠模式核心程式碼:

public class CarFactory {
	
	public Car getCar(String name){
		if("Porsche".endsWith(name)){
			return new PorscheCar();
		}
		else if("Bugatti".endsWith(name)){
			return new BugattiCar();
		}
		return new PorscheCar();
	
	}
	
}
複製程式碼

同時,和我們之前系列文章不止一次的強調的那樣,如果把要維護物件的數量提升到一個很高的量級,即我們簡單工廠模式需要維護成千上萬的物件,那麼我們程式肯定會爆炸的。

這麼一想,的確是這樣,當維護物件比較多的時候確實會比較麻煩,所以天才的科學家們呢肯定不會放任這個問題坐視不管的,於是簡單工廠模式plus升級版本誕生了,不過我個人感覺工廠方法模式並沒有解決最本質的問題,可以說是換湯不換藥,披著工廠方法模式的單例模式。

我剛才說了什麼?工廠方法模式?我想起來了,今天要寫工廠方法模式。

合著你剛才說半天都不知道要寫啥啊?!

走,走,讓你來說相聲來了?

對,我們下面來看工廠方法模式

工廠方法模式定義:

工廠方法模式是簡單工廠的進一步深化, 在工廠方法模式中,我們不再提供一個統一的工廠類來建立所有的物件,而是針對不同的物件提供不同的工廠。也就是說每個物件都有一個與之對應的工廠。

這裡就不設什麼微劇場了,我相信天才的讀者們看到程式碼就自然瞭解了。

應用場景:

  • 客戶端不知道要創建出來的類是什麼,但是知道對應的工廠是什麼。
  • 客戶端可以通過子類來指定建立對應的物件

程式碼實戰:

我們在原來簡單工廠模式例項的基礎上,新增一個Factory介面類,用於規範我們工廠的行為。

public interface Factory {
	
	public Car getCar();

}

複製程式碼

然後編寫他們的相關實現:

//布加迪
public class BugattiFactory implements Factory {

	@Override
	public Car getCar
()
{ // TODO Auto-generated method stub return new BugattiCar(); } } //保時捷 public class PorscheFactory implements Factory{ @Override public Car getCar() { // TODO Auto-generated method stub return new PorscheCar(); } } 複製程式碼

測試:

public class Test {
	
	public static void main(String[] args) {

		Factory bugattiFactory  = new BugattiFactory();
		Car car = bugattiFactory.getCar();
		car.description();
		
		Factory porschFactory = new PorscheFactory();
		car = porschFactory.getCar();
		car.description();
	}

}

複製程式碼

輸出:

布加迪跑車
保時捷汽車
複製程式碼

這..這..這看起來有點像那個什麼,那個什麼來著,單例,單例模式?

的確是有點像的,確實在設計模式裡面有很多模式之間是運作流程是有點類似的,這點在代理模式和裝飾者模式之間的爭論有所提及,感興趣的朋友可以看一下我的那篇筆記。

當然,工廠模式這麼看起來確實是有點尷尬了,原來一個工廠造所有車,但是型號多了維護不過來,現在是每一個型號都建了一個單獨的工廠生產,這麼一來型號多了工廠就會變得有點多,萬一我同時買個十幾種不同型號的車,那豈不是要跑去十多個工廠?太累了,不行,不行,難道就沒有更好的方法了嗎?

叮叮叮叮,噹噹噹當

抽象工廠模式!(請讀者自行腦補哆啦A夢的語氣)。

抽象工廠模式:

**抽象工廠模式(**Abstract Factory Pattern)是圍繞一個超級工廠建立其他工廠。該超級工廠又稱為其他工廠的工廠。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

在抽象工廠模式中,介面是負責建立一個相關物件的工廠,不需要顯式指定它們的類。每個生成的工廠都能按照工廠模式提供物件。

工廠模式發展到抽象工廠模式,才真的有點設計模式家族的樣子,抽象工廠設計模式在工廠模式上再加一層,做一個超級工廠,從超級工廠獲取工廠,然後在從工廠中獲取具體的物件。

頭有點暈,不廢話,碼上看程式碼

等等,我剛才說了什麼?碼上?歡迎關注本人或本人的java技術部落格【碼上】jdkcb.com 碼上開始行動!

廣告,滾。

在看程式碼前我們先來說一下抽象工廠模式的應用場景:

  • 和工廠方法一樣客戶端不需要知道它所建立的物件的類
  • 需要一組物件共同完成某種功能時。並且可能存在多組物件完成不同功能的情況。
  • 程式碼結構穩定,不需要頻繁修改和擴充套件產品功能。

應用例項:

  • 王者榮耀換面板,一次換一套
  • QQ秀換面板,一套一次換
  • 英雄聯盟換面板,換一套一次

官方吐槽:除了換面板你就不能換點別的????!!

不能

程式碼實戰

現在我們讓客戶的需求更加刁鑽一些,客戶現在需要不同的顏色的法拉利跑車。

首先宣告一個Color介面類,用於規範我們顏色的行為。

public interface Color {
   void name();
}

複製程式碼

編寫相關的實現

public class Red implements Color{

	@Override
	public void name() {
		System.out.println("是紅色的");
	}

}

public class Blue implements Color{

	@Override
	public void name() {
		System.out.println("是藍色的");
		
	}

}


複製程式碼

然後建立我們的抽象工廠類:

public abstract class Factory {
	public abstract void getCar();
	public abstract void getColor();
	

}
複製程式碼

編寫相關實現:

//紅色法拉利
public class RedPorscheFactory extends Factory {

	@Override
	public Car getCar() {
		// TODO Auto-generated method stub
		return new PorscheCar();
	}

	@Override
	public Color getColor() {
		// TODO Auto-generated method stub
		return new Red();
	}


}

//藍色布加迪
public class BlueBugattiFactory extends Factory {

	@Override
	public Car getCar() {
		// TODO Auto-generated method stub
		return new BugattiCar();
	}

	@Override
	public Color getColor() {
		// TODO Auto-generated method stub
		return new Blue();
	}

}



複製程式碼

最後為了體現超級工廠這個概念,我們新增一個超級工廠類,當然部分場景下是需要的,本例屬於可有可無的範圍。

public class BigFactory {
	
	public static Factory getFactory(String name){
		if("bugatti".endsWith(name)){
			return new BlueBugattiFactory();
		}else if("porsche".endsWith(name)){
			return new RedPorscheFactory();
		}
		return null;
		
	}

}

複製程式碼

測試:

public class Test {
	
	public static void main(String[] args) {
		Factory factory = BigFactory.getFactory("bugatti");
		Car car  = factory.getCar();
		Color color = factory.getColor();
		car.description();
		color.name();
	}

}

複製程式碼

輸出:

布加迪跑車
是藍色的
複製程式碼

由此可見,抽象工廠模式維護的是一套物件,那麼什麼時候會用到抽象工廠模式呢?

王者榮耀換面板的時候。

大家想,王者榮耀英雄換面板的時候,是不是一換一整套,這不就像當我們的產品需要向多個不同操作平臺適配的時候,而編寫相應的一套實現。比如面向liunx的叫linuxFactory,面向win的叫winFactory等等。

這個時候,有的讀者可能會想到,是不是有點像模板設計模式,不盡然,雖然兩者在職責上有重疊的部分,都是根據不同情況相應地提供不同實現,但是實現方式卻不一樣,工廠模式不關心是那個類具體實現了Car介面,也不關心是哪個實體類代表了法拉利,獲取這個類的途徑是通過工廠獲取,使用者只需要知道對應的工廠是什麼,而完全不需要care相關細節。

所以說呢,設計模式學到最後往往就可以把握到萬千設計模式中那不變的一部分,因為工廠方法模式實在是沒有什麼可說的,所以筆記由原來計劃的三篇縮減到了兩篇,通過這兩篇筆記呢,我知道這些筆記可能雖然沒有什麼人看,但是看的那幾個人應該以及初步掌握了工廠模式的精髓了,並且能在之後的開發中能有所應用。

github下載: github.com/hanshuaikan…

最後,我是韓數,歡迎關注我,我們下篇筆記再見。