設計模式(三)——工廠模式

liangxingwei發表於2017-12-14

本文原創掘金: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屬性的。
  • 然後結果不變,但是可以發現,依賴關係改變了,沒改動程式碼之前,呼叫者(場景類)依賴於產品類,只要產品類有改動,都有可能對呼叫者造成影響。而使用工廠模式後,呼叫者對產品類的依賴變成了對工廠類的依賴,無論產品類如何變化,呼叫者都不需要關心,只需要工廠類能夠正確返回物件即可,實現瞭解耦。

以上就是工廠模式。

相關文章