1. 程式人生 > >磊哥學設計模式(二)工廠模式

磊哥學設計模式(二)工廠模式

工廠模式

什麼是工廠模式

工廠方法模式(FACTORY METHOD)是一種常用的物件建立型設計模式,此模式的核心精神是封裝類中不變的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、複用和方便後期維護拓展的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品

為什麼要用工廠模式

  1. 為了解耦,把物件的建立和使用的過程分開。就是Class A 想呼叫 Class B ,那麼A只是呼叫B的方法,而不用例項化Class B。
  2. 降低程式碼重複量,提高程式的可擴充套件性。也就是說,建立物件的程式碼,都放到工廠裡面。

程式碼演示

下面就來演示下,使用工廠模式。
首先,先舉個例子,比如一個遊戲,有兩種攻擊方式,魔法攻擊和物理攻擊,那麼我們很容易就寫出程式碼來:

普通程式碼

public class OldAttack {
	void magic(){
		System.out.println("magic attack!");
	}
	
	void Physical(){
		System.out.println("Physical attack!");
	}
}

然後在主函式呼叫:

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OldAttack a = new OldAttack();
		a.magic();
	}

}

很簡單,對不對,好現在問題來了,需要A,B,C,D四個物件來執行攻擊,也很容易,馬上就可以寫出下面的程式碼:

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OldAttack a = new OldAttack();
		a.magic();
		
		OldAttack b = new OldAttack();
		b.magic();
		
		OldAttack c = new OldAttack();
		c.magic();
		
		OldAttack d = new OldAttack();
		d.magic();
	}

}

好,現在需求又改了,需要有初始的引數,那麼就要改變如下:

public class OldAttack {
	void magic(){
		System.out.println("magic attack!");
	}
	
	void Physical(){
		System.out.println("Physical attack!");
	}
	OldAttack(int a,int b,int c,int d){
		
	}
}

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OldAttack a = new OldAttack(1,2,3,4);
		a.magic();
		
		OldAttack b = new OldAttack(1,2,3,4);
		b.magic();
		
		OldAttack c = new OldAttack(1,2,3,4);
		c.magic();
		
		OldAttack d = new OldAttack(1,2,3,4);
		d.magic();
	}

}

工廠模式程式碼

改變就要如上,逐個更改,每一個物件的初始化都要加上引數,現在程式碼比較簡單,改起來還算容易,但是要是有更多的程式碼呢,對於一個工程來說,更改需求很正常,程式碼量大也很正常。但是改起來真的很麻煩,所以我們就想換一種方式來寫:

public interface Attack {
	public void attack();
}

public class Magic implements Attack {

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		System.out.println("Magic attack!");
	}

	Magic(int a,int b ,int c,int d){
		
	}
	
}
public class Physical implements Attack {

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		 System.out.println("Physical attack!"); 
	}

	Physical(int a,int b,int c,int d){
		
	}
}
public interface Provider {
	public Attack toAttack();
}

public class MagicFactory implements Provider {

	@Override
	public Attack toAttack() {
		// TODO Auto-generated method stub
		return new Magic(1,2,3,4);
	}

}
public class PhysicalFactory implements Provider {

	@Override
	public Attack toAttack() {
		// TODO Auto-generated method stub
		return new Physical(1,2,3,4);
	}

}
public class FactoryTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Provider p = new MagicFactory();
		Attack a = p.toAttack();
		a.attack();
		
	}

}

如上程式碼就是,要改的時候只需要改實現類和工廠類,就可以,不影響主函式的使用,而且要擴充套件的時候,比如加一個特殊攻擊,只需要再做個工廠類和實現類。
如下:

public class Special implements Attack {

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		System.out.println("Special attack!");
	}

	Special(int a,int b,int c,int d){
		
	}
}

public class SpecialFactory implements Provider {

	@Override
	public Attack toAttack() {
		// TODO Auto-generated method stub
		return new Special(1,2,3,4);
	}

}
public class FactoryTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Provider p = new MagicFactory();
		Attack a = p.toAttack();
		a.attack();
		Provider p2 = new SpecialFactory();
		Attack a2 = p2.toAttack();
		a2.attack();
	}

}

看,擴充套件起來非常的方便。