本文原創掘金:L_Sivan
工廠模式定義
- 定義一個建立物件的介面,由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到子類
- 作用:沒使用工廠的話,我們要創造物件使用new,工廠方法就是幫我們負責建立需要的物件。
- 工廠模式是建立類模式。
實現
先看一下沒用到工廠類的場景,我們需要AProduct和BProduct
//產品類介面
public interface IProduct {
public void say();
}
// A產品類
public class AProduct implements IProduct {
@Override
public void say() {
System.out.println("我是A產品");
}
}
//B產品類
public class BProduct implements IProduct {
@Override
public void say() {
System.out.println("我是B產品");
}
}
//場景類
public class Client {
public static void main(String[] args) {
IProduct aProduct = new AProduct();
aProduct.say();
IProduct bProduct = new BProduct();
bProduct.say();
}
}
結果:
我是A產品
我是B產品
複製程式碼
完美執行,但是這個有什麼問題呢?試想一下,假設以後改需求,需要在生產產品的時候傳入生產批次,怎麼傳?建構函式或者setter都可以,但是都有一個問題,就是我們在改了產品類的時候,還得改正在使用它的地方,這個耦合其實可以解的,用的就是工廠方法。
// 抽象工廠類
public abstract class AbstractFactory {
public abstract <T extends IProduct> T getProduct(Class<T> clazz) ;
}
// 具體工廠類
public class ConcreteFactory extends AbstractFactory{
@Override
public <T extends IProduct> T getProduct(Class<T> clazz) {
T product = null;
try {
product = (T) Class.forName(clazz.getName()).newInstance();
} catch (Exception e) {
}
return product;
}
}
// 產品類不變
// 場景類
public class Client {
public static void main(String[] args) {
ConcreteFactory factory = new ConcreteFactory();
AProduct aproduct = factory.getProduct(AProduct.class);
aproduct.say();
BProduct bProduct = factory.getProduct(BProduct.class);
bProduct.say();
}
}
結果:
我是A產品
我是B產品
複製程式碼
- 分析下上面的程式碼,定義了一個抽象工廠類,工廠裡面有一個方法,接收引數是繼承產品類介面的類的類屬性,確保工廠生產出來必定是繼承自IProduct的物件。為什麼要用泛型?因為你會發現,不用泛型的話,接收的引數不知道該怎麼定義,直接用IProduct的class屬性的話,在使用ConcreteFactory傳參的時候是不能傳實現IProduct介面的類的class屬性的。
- 然後結果不變,但是可以發現,依賴關係改變了,沒改動程式碼之前,呼叫者(場景類)依賴於產品類,只要產品類有改動,都有可能對呼叫者造成影響。而使用工廠模式後,呼叫者對產品類的依賴變成了對工廠類的依賴,無論產品類如何變化,呼叫者都不需要關心,只需要工廠類能夠正確返回物件即可,實現瞭解耦。
以上就是工廠模式。