磊哥學設計模式(二)工廠模式
阿新 • • 發佈:2018-11-09
工廠模式
什麼是工廠模式
工廠方法模式(FACTORY METHOD)是一種常用的物件建立型設計模式,此模式的核心精神是封裝類中不變的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、複用和方便後期維護拓展的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品
為什麼要用工廠模式
- 為了解耦,把物件的建立和使用的過程分開。就是Class A 想呼叫 Class B ,那麼A只是呼叫B的方法,而不用例項化Class B。
- 降低程式碼重複量,提高程式的可擴充套件性。也就是說,建立物件的程式碼,都放到工廠裡面。
程式碼演示
下面就來演示下,使用工廠模式。
首先,先舉個例子,比如一個遊戲,有兩種攻擊方式,魔法攻擊和物理攻擊,那麼我們很容易就寫出程式碼來:
普通程式碼
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();
}
}
看,擴充套件起來非常的方便。