介紹
抽象工廠模式Abstract Factory,提供了一個創建一系列相關或互相依賴對象的接口,而無需指定它們具體的類;
結構圖
Demo
假設我們在打cs的時候需要買槍,而子彈是不通用的,但我們不知道什麼武器的對應什麼子彈,
理想情況下是在不同的商店直接買到對應的武器和子彈
接口
//武器接口
public interface IGun {
void shot(IBullet bullet);
}
//子彈接口
public interface IBullet {
String getBulletName();
}
//武器工廠
public interface IWeaponFactory {
IGun createGun();
IBullet createBullet();
}
AK47
//武器與子彈相耦合
public class AK47 implements IGun {
@Override
public void shot(IBullet bullet) {
Log.d("meee","使用AK47發射"+bullet.getBulletName());
}
}
//武器與子彈相耦合
public class AK47Bullet implements IBullet {
@Override
public String getBulletName() {
return "AK47子彈";
}
}
//AK47的工廠類
public class AK47Factory implements IWeaponFactory {
@Override
public IGun createGun() {
return new AK47();
}
@Override
public IBullet createBullet() {
return new AK47Bullet();
}
}
M4A1
//M4A1也是一樣的
public class M4A1 implements IGun {
@Override
public void shot(IBullet bullet) {
Log.d("meee","使用M4A1發射"+bullet.getBulletName());
}
}
public class M4A1Bullet implements IBullet {
@Override
public String getBulletName() {
return "M4A1子彈";
}
}
public class M4A1Factory implements IWeaponFactory {
@Override
public IGun createGun() {
return new M4A1();
}
@Override
public IBullet createBullet() {
return new M4A1Bullet();
}
}
客戶端
//只需要更換工廠即可同時更換武器和子彈,不需要知道子彈和武器的對應關係
// AK47Factory factory = new AK47Factory();
M4A1Factory factory = new M4A1Factory();
IBullet bullet = factory.createBullet();
IGun gun = factory.createGun();
gun.shot(bullet);
抽象工廠模式的優缺點
優點:
1.便於交換產品的系列,工廠只需要在一個應用中出現一次,這就使得改變一個應用的具體工廠非常容易,只需要改變工廠即可使用不同的產品配置.
2.讓具體的創建過程和客戶端分離,客戶端是通過他們的接口來操縱實例,產品的具體名稱也被具體工廠的實現分離,不會出現在客戶端代碼中;
缺點:
仍然在使用時需要多次創建特定的工廠對象,更改時也需要多次更改
使用簡單工廠對抽象工廠進行改進
//把判斷的職責交給封裝類
public class Factory {
public static final int AK47_FACTORY = 0x01;
public static final int M4A1_FACTORY = 0x02;
public static IWeaponFactory create(int factoryType) {
switch (factoryType) {
case AK47_FACTORY:
return new AK47Factory();
case M4A1_FACTORY:
return new M4A1Factory();
default:
throw new RuntimeException("找不到啊..");
}
}
}
//只需要更改傳入的參數即可實現武器和子彈的更換
IWeaponFactory factory = Factory.create(Factory.M4A1_FACTORY);
IBullet bullet = factory.createBullet();
IGun gun = factory.createGun();
gun.shot(bullet);
更爲簡潔的簡單工廠,剔除IFactory 具體Factory類
//把生產槍和子彈的職責都上放到簡單工廠中,通過一個變量來控制
public class SimpleFactory {
public static final int AK47_FACTORY = 0x01;
public static final int M4A1_FACTORY = 0x02;
private static int mflag;
public static void init(int flag) {
mflag = flag;
}
public static IGun createGun() {
switch (mflag) {
case AK47_FACTORY:
return new AK47();
case M4A1_FACTORY:
return new M4A1();
default:
return null;
}
}
public static IBullet createBullet() {
switch (mflag) {
case AK47_FACTORY:
return new AK47Bullet();
case M4A1_FACTORY:
return new M4A1Bullet();
default:
return null;
}
}
}
//只需要更改配置即可更換槍的種類
SimpleFactory.init(SimpleFactory.M4A1_FACTORY);
IBullet bullet = SimpleFactory.createBullet();
IGun gun = SimpleFactory.createGun();
gun.shot(bullet);