一篇文章帶你入門java工廠模式

Java設計模式-工廠模式

什麼是工廠模式?

工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬於創建型模式,它提供瞭一種創建對象的最佳方式。

在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。

簡單編寫一個類:

1、簡單工廠模式

本程序非常簡單就是通過接口的子類為接口對象實例化,但是本操作存在什麼樣的問題呢?

之前一直在強調,主方法或者是主類是一個客戶端,客戶端的操作應該越簡單越好。但是在現在的程序之中,有一個最大的問題:客戶端之中,一個接口和一個固定的子類綁在一起瞭。

在本程序之中,最大的問題在於耦合上,發現在主方法之中一個接口和一個子類緊密耦合在一起,這種方法比較直接,可以簡單的理解為:A→B,但是這種緊密的方式不方便於維護,所以後來使用瞭A→B→C,中間經歷瞭一個過渡,這樣一來B去改變,C去改變,但是A不需要改變,就好比JAVA的JVM一樣:程序→JVM→操作系統。

2、普通工廠模式 UML圖:

源代碼:

ProjectFactory.java

public interface ProjectFactory {
	Project getname();
}

BlueFactory.java(ConcreteFactory1)

public class BlueFactory implements ProjectFactory{
	@Override
	public Project getname() {
		// TODO Auto-generated method stub
		return new Bluepen();
	}
}

RedFactory.java(ConcreteFactory2)

public class RedFactory implements ProjectFactory{
	@Override
	public Project getname() {
		// TODO Auto-generated method stub
		return new redPen();
	}
}

Project.java(產品類)

public interface Project {
	void name();
}

Bluepen.java(ConcreteProject1)

public class Bluepen implements Project{
	@Override
	public void name() {
		// TODO Auto-generated method stub
		System.out.println("這是一個藍色的筆");
	}
}

RedFactory.java(ConcreteProject2)

public class RedFactory implements ProjectFactory{
	@Override
	public Project getname() {
		// TODO Auto-generated method stub
		return new redPen();
	}
}

測試類

public class Client {
	public static void main(String[] args) {
		Project pen = new RedFactory().getname();
		pen.name();
		Project pen1 = new BlueFactory().getname();
		pen1.name();
	}
}

運行結果:

image-20210805205221818

這個時候發現客戶端不在和一個具體的子類耦合在一起瞭,就算以後增加瞭新的子類,那麼也隻需要修改Factory類即可。

小結:

  • 以後如果是自己編寫的接口如果想要取得接口的 實例化對象,第一反應寫工廠類
  • 簡單工廠和工廠方法模式的不同在於前者生成產生產品的行為封裝在一個方法中,根據參數的類型進行實例化,同時不存在抽象接口。而後者則增加瞭抽象工廠,通過實現不同的工廠方法來創建不同的產品,一個方法通常對應一個產品,這種方式相較於前者擴展性更高,在需求增加時完全符合開閉原則和依賴倒置原則

使用場景:

消費者不關心它所要創建對象的類(產品類)的時候。

消費者知道它所要創建對象的類(產品類),但不關心如何創建的時候。

例如:hibernate裡通過sessionFactory創建session、通過代理方式生成ws客戶端時,通過工廠構建報文中格式化數據的對象。

3、抽象工廠模式

定義:為創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類。

抽象工廠模式與工廠方法模式的區別

​ 抽象工廠模式是工廠方法模式的升級版本,他用來創建一組相關或者相互依賴的對象。他與工廠方法模式的區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對的多個產品等級結構。在編程中,通常一個產品結構,表現為一個接口或者抽象類,也就是說,工廠方法模式提供的所有產品都是衍生自同一個接口或抽象類,而抽象工廠模式所提供的產品則是衍生自不同的接口或抽象類。

​ 在抽象工廠模式中,有一個產品族的概念:所謂的產品族,是指位於不同產品等級結構中功能相關聯的產品組成的傢族。抽象工廠模式所提供的一系列產品就組成一個產品族;而工廠方法提供的一系列產品稱為一個等級結構。.

如果工廠的產品全部屬於同一個等級結構,則屬於工廠方法模式;如果工廠的產品來自多個等級結構,則屬於抽象工廠模式。

UML圖:

image-20210805210243478

源代碼:

Factory.java(抽象工廠)

public interface Factory {
	PhoneProject projectPhone();
	LaptopProject projectLaptop();
}

HuaWeiFactory.java(華為具體工廠)

public class HuaWeiFactory implements Factory{
	@Override
	public PhoneProject projectPhone() {
		// TODO Auto-generated method stub
		return new HuaWeiPhone();
	}
	@Override
	public LaptopProject projectLaptop() {
		// TODO Auto-generated method stub
		return new HuaWeiLaptop();
	}
}

XiaomiFactory.java(小米具體工廠)

public class XiaomiFactory implements Factory{
	@Override
	public PhoneProject projectPhone() {
		// TODO Auto-generated method stub
		return new XiaomiPhone();
	}
	@Override
	public LaptopProject projectLaptop() {
		// TODO Auto-generated method stub
		return new XiaomiLaptop();
	}
}

LaptopProject.java(筆記本產品)

public interface LaptopProject {
	void getId();
	void printInfo();
}

HuaWeiLaptop.java(華為筆記本)

public class HuaWeiLaptop implements LaptopProject{
	@Override
	public void getId() {
		// TODO Auto-generated method stub
		System.out.println("編號"+123);
	}
	@Override
	public void printInfo() {
		// TODO Auto-generated method stub
		System.out.println("生產瞭華為電腦");
	}
}

XiaomiLaptop.java(小米筆記本)

public class XiaomiLaptop implements LaptopProject{
	@Override
	public void getId() {
		// TODO Auto-generated method stub
		System.out.println("編號"+213);
	}
	@Override
	public void printInfo() {
		// TODO Auto-generated method stub
		System.out.println("生產小米電腦");
	}
}

PhoneProject.java(手機產品)

public interface PhoneProject {
	void getId();
	void printInfo();
}

HuaWeiPhone.java(華為手機)

public class HuaWeiPhone implements PhoneProject{
	@Override
	public void getId() {
		// TODO Auto-generated method stub
		System.out.println("編號:"+123412);
	}
	@Override
	public void printInfo() {
		// TODO Auto-generated method stub
		System.out.println("生產華為手機");
	}
}

XiaomiPhone.java(小米手機)

public class XiaomiPhone implements PhoneProject{
	@Override
	public void getId() {
		// TODO Auto-generated method stub
		System.out.println("編號:"+123412);
	}
	@Override
	public void printInfo() {
		// TODO Auto-generated method stub
		System.out.println("生產瞭小米手機!!");
	}
}

測試類:

public class Client {
	public static void main(String[] args) {
		PhoneProject huawei = new HuaWeiFactory().projectPhone();
		huawei.printInfo();
		huawei.getId();
		PhoneProject xiaomi = new XiaomiFactory().projectPhone();
		xiaomi.printInfo();
		LaptopProject huawei1 = new HuaWeiFactory().projectLaptop();
		huawei1.printInfo();
	}
}

運行結果:

image-20210805211054410

總結:

抽象工廠模式是工廠方法模式的升級版,後者面向單個產品,而前者面向的的是一個產品族。根據官方定義:為創建一組相關/互相依賴的對象提供一個接口而無需指定它們的具體類。
比如一個汽車工廠要生成騎車,而每種汽車都有車門、車輪胎等一系列產品,這意味著每增加一款汽車就需要增加一個新的工廠來提供新產品的實現。這時候就可以使用抽象工廠模式來進行設計。抽象工廠模式適用於一系列產品族。

優點: 抽象廠模式將產品族的依賴與約束關系放到抽象工廠中,便於管理。職責解耦,用戶不需要關心一堆自己不關心的細節,由抽象廠來負責組件的創建切換產品族容易,隻需要增加一個具體工廠實現,客戶端選擇另-個套餐就可以瞭 缺點: 抽象工廠模式類增加的速度很快,有一個產品族就需要增加一一個具體工廠實現,比較繁瑣產品族難以擴展產品。當產品族中增加一個產品時,抽象工廠接口中需要增加一個函數,對應的所有具體工廠實現都需要修改,修改放大嚴重。抽象廠並未完全屏蔽創建細節,給出的都是組件。對於這種情況可以結合工廠模式或簡單工廠模式-起使用。 使用場景:

大傢應該已經發現瞭,其實抽象工廠模式如果隻有一個組件的話,其實是退化到工廠方法模式,也就是沒有瞭產品族的概念,隻剩一一個產品瞭,因此簡單工廠,廠方法,抽象工廠這三者之間是有內在聯系的,區別隻產品的復雜度。抽象工廠的本質是選擇產品族,因此大傢可以根據這個特征來識別是否可以應用抽象廠。

本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: