1. 工廠模式
1.1 概述
工廠模式(Factory Pattern)是一種創(chuàng)建型設(shè)計模式,提供了一種將對象創(chuàng)建的過程與對象的使用分離的機(jī)制。它通過將實例化對象的邏輯封裝到一個工廠類中,從而減少客戶端和具體類的耦合。這使得代碼更加靈活和易于維護(hù),尤其是當(dāng)我們需要創(chuàng)建不同種類的對象時。
在 Java 中,萬物皆對象,這些對象都需要創(chuàng)建,如果創(chuàng)建的時候直接 new 該對象,就會對該對象耦合嚴(yán)重,假如我們要更換對象,所有 new 對象的地方都需要修改一遍,這顯然違背了軟件設(shè)計的開閉原則。如果我們使用工廠來生產(chǎn)對象,我們就只和工廠打交道就可以了,徹底和對象解耦,如果要更換對象,直接在工廠里更換該對象即可,達(dá)到了與對象解耦的目的。所以說,工廠模式最大的優(yōu)點就是:解耦。
工廠模式主要分為以下幾種類型:
- 簡單工廠模式(Simple Factory)
- 工廠方法模式(Factory Method)
- 抽象工廠模式(Abstract Factory)
1.2 場景:操作不同類型的動物
我們假設(shè)有一個場景,程序需要對不同種類的動物進(jìn)行操作,動物可以發(fā)出不同的聲音。
1.2.1 不用工廠模式
1.2.1.1 分析
在這個例子中,客戶端代碼直接依賴于具體的動物類 ( Dog, Cat, Bird),這意味著如果我們添加新的動物類型或者更改現(xiàn)有的創(chuàng)建邏輯,必須修改客戶端代碼。這種實現(xiàn)方式耦合度較高,不符合開閉原則。
類圖:

// 動物接口
interface Animal {
void makeSound();
}
// 具體動物類:狗
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Woof");
}
}
// 具體動物類:貓
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Meow");
}
}
// 具體動物類:鳥
class Bird implements Animal {
@Override
public void makeSound() {
System.out.println("Tweet");
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
// 客戶端直接實例化
Animal animal1 = new Dog();
// 輸出:Woof
animal1.makeSound();
Animal animal2 = new Cat();
// 輸出:Meow
animal2.makeSound();
Animal animal3 = new Bird();
// 輸出:Tweet
animal3.makeSound();
}
}
1.2.1.1 優(yōu)缺點
- 優(yōu)點:
- 簡單直接:客戶端直接實例化對象,代碼較為簡單,適用于對象數(shù)量少、變動少的情況。
- 缺點:
- 高耦合性:客戶端依賴具體類,任何對象的變化(如新增類、修改類)都需要修改客戶端代碼,違反開閉原則。
- 擴(kuò)展性差:當(dāng)新增或修改對象時,需要改動已有代碼,且對不同條件的判斷邏輯可能會擴(kuò)散到多個地方。
1.2.2 簡單工廠模式
簡單工廠模式使用一個單獨的類根據(jù)參數(shù)創(chuàng)建不同類型的對象。它是一種具體的工廠,不屬于設(shè)計模式中的 23 種經(jīng)典設(shè)計模式,但經(jīng)常被用作學(xué)習(xí)的起點。
1.2.2.1 結(jié)構(gòu)
簡單工廠包含如下角色:
- 抽象產(chǎn)品 :定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能。
- 具體產(chǎn)品 :實現(xiàn)或者繼承抽象產(chǎn)品的子類
- 具體工廠 :提供了創(chuàng)建產(chǎn)品的方法,調(diào)用者通過該方法來獲取產(chǎn)品。
1.2.2.2 分析
- 在簡單工廠模式中,
AnimalFactory類封裝了對象的創(chuàng)建邏輯,客戶端只需要傳遞參數(shù)來指定創(chuàng)建的動物類型,而無需知道具體的類。 - 雖然解決了直接依賴具體類的問題,但如果我們想添加新的動物類型,仍需要修改
AnimalFactory類的邏輯,這違反了開閉原則。
類圖:

// 簡單工廠類
class AnimalFactory {
public Animal createAnimal(String type) {
if ("Dog".equalsIgnoreCase(type)) {
return new Dog();
} else if ("Cat".equalsIgnoreCase(type)) {
return new Cat();
} else if ("Bird".equalsIgnoreCase(type)) {
return new Bird();
} else {
throw new IllegalArgumentException("Unknown animal type");
}
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
AnimalFactory factory = new AnimalFactory();
Animal animal1 = factory.createAnimal("Dog");
// 輸出:Woof
animal1.makeSound();
Animal animal2 = factory.createAnimal("Cat");
// 輸出:Meow
animal2.makeSound();
Animal animal3 = factory.createAnimal("Bird");
// 輸出:Tweet
animal3.makeSound();
}
}
1.2.1.3 優(yōu)缺點
- 優(yōu)點:
- 創(chuàng)建邏輯集中:將對象的創(chuàng)建集中在一個工廠類中,客戶端只需知道要創(chuàng)建的對象類型(傳遞字符串或參數(shù)),降低了對具體類的依賴。
- 簡化客戶端代碼:客戶端不再負(fù)責(zé)具體對象的創(chuàng)建,只需調(diào)用工廠方法。
- 缺點:
-
違反開閉原則:如果需要添加新的類型,需要修改工廠類的創(chuàng)建邏輯(
if-else或switch-case語句)。 - 復(fù)雜性增加:隨著對象類型增多,工廠類的創(chuàng)建邏輯可能變得復(fù)雜,不利于維護(hù)。
1.2.1.4 擴(kuò)展:靜態(tài)工廠
在開發(fā)中也有一部分人將工廠類中的創(chuàng)建對象的功能定義為靜態(tài)的,這個就是靜態(tài)工廠模式,它也不是 23 種設(shè)計模式中的。
類圖:

// 靜態(tài)工廠類
class AnimalFactory {
public static Animal createAnimal(String type) {
if ("Dog".equalsIgnoreCase(type)) {
return new Dog();
} else if ("Cat".equalsIgnoreCase(type)) {
return new Cat();
} else if ("Bird".equalsIgnoreCase(type)) {
return new Bird();
} else {
throw new IllegalArgumentException("Unknown animal type");
}
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
Animal animal1 = AnimalFactory.createAnimal("Dog");
// 輸出:Woof
animal1.makeSound();
Animal animal2 = AnimalFactory.createAnimal("Cat");
// 輸出:Meow
animal2.makeSound();
Animal animal3 = AnimalFactory.createAnimal("Bird");
// 輸出:Tweet
animal3.makeSound();
}
}
1.2.3 工廠方法模式
工廠方法模式定義了一個創(chuàng)建對象的接口,但讓子類決定實例化哪個類。工廠方法模式將對象的創(chuàng)建推遲到子類。
1.2.3.1 結(jié)構(gòu)
工廠方法模式的主要角色:
- 抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口,調(diào)用者通過它訪問具體工廠的工廠方法來創(chuàng)建產(chǎn)品。抽象工廠既可以是接口也可以是抽象類,具體使用哪種形式取決于具體的設(shè)計需求和場景。
- 具體工廠(ConcreteFactory):主要是實現(xiàn)抽象工廠中的抽象方法,完成具體產(chǎn)品的創(chuàng)建。
- 抽象產(chǎn)品(Product):定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能。
- 具體產(chǎn)品(ConcreteProduct):實現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間一一對應(yīng)。
1.2.3.2 分析
- 在工廠方法模式中,每個具體的動物都有一個對應(yīng)的工廠類,工廠類負(fù)責(zé)創(chuàng)建對應(yīng)的動物實例。
- 這種模式遵循了開閉原則,添加新的動物類型只需新建一個工廠類和對應(yīng)的動物類,而無需修改現(xiàn)有代碼。
類圖:

// 抽象工廠類
abstract class AnimalFactory {
public abstract Animal createAnimal();
}
// 具體工廠類:狗工廠類
class DogFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
// 具體工廠類:貓工廠類
class CatFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Cat();
}
}
// 具體工廠類:鳥工廠類
class BirdFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Bird();
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
AnimalFactory factory1 = new DogFactory();
Animal animal1 = factory1.createAnimal();
// 輸出:Woof
animal1.makeSound();
AnimalFactory factory2 = new CatFactory();
Animal animal2 = factory2.createAnimal();
// 輸出:Meow
animal2.makeSound();
AnimalFactory factory3 = new BirdFactory();
Animal animal3 = factory3.createAnimal();
// 輸出:Tweet
animal3.makeSound();
}
}
1.2.3.3 優(yōu)缺點
- 優(yōu)點:
- 符合開閉原則:工廠方法模式通過新增具體工廠類來擴(kuò)展產(chǎn)品類型,而不修改已有代碼,符合開閉原則。
- 解耦合:客戶端不再依賴于具體類,而是依賴于抽象工廠接口,提升了代碼的可擴(kuò)展性和靈活性。
- 職責(zé)分離:每個工廠負(fù)責(zé)創(chuàng)建一種產(chǎn)品,工廠類和產(chǎn)品類的職責(zé)更加明確,便于維護(hù)。
- 缺點:
- 增加類的數(shù)量:每增加一種產(chǎn)品類型,都需要新建對應(yīng)的工廠類,這會使類的數(shù)量增多,增加代碼的復(fù)雜性。
- 適用場景有限:適合有多個類型的產(chǎn)品且產(chǎn)品類型較穩(wěn)定的場景。如果產(chǎn)品類型非常多,工廠方法模式可能顯得冗余。
1.2.4 抽象工廠模式
抽象工廠模式提供了一個接口,用于創(chuàng)建一系列相關(guān)或相互依賴的對象,而無需指定它們的具體類。它通常用于需要創(chuàng)建多個相關(guān)產(chǎn)品的場景。
1.2.4.1 結(jié)構(gòu)
抽象工廠模式的主要角色如下:
- 抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口,它包含多個創(chuàng)建產(chǎn)品的方法,可以創(chuàng)建多個不同等級的產(chǎn)品。抽象工廠既可以是接口也可以是抽象類,具體使用哪種形式取決于具體的設(shè)計需求和場景。
- 具體工廠(Concrete Factory):主要是實現(xiàn)抽象工廠中的多個抽象方法,完成具體產(chǎn)品的創(chuàng)建。
- 抽象產(chǎn)品(Product):定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能,抽象工廠模式有多個抽象產(chǎn)品。
- 具體產(chǎn)品(ConcreteProduct):實現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它 同具體工廠之間是多對一的關(guān)系。
1.2.4.2 分析
- 在抽象工廠模式中,
AnimalFactory提供了創(chuàng)建動物和食物的接口。不同的具體工廠(DogFactory、CatFactory、BirdFactory)負(fù)責(zé)創(chuàng)建不同的動物及其食物。 - 這種模式適合在需要創(chuàng)建相關(guān)產(chǎn)品族時使用,比如同一類的動物和它們的食物。在不修改已有工廠的情況下,可以擴(kuò)展新的動物和食物種類。
類圖:

// 食物接口
interface Food {
void eat();
}
// 具體食物類:狗糧
class DogFood implements Food {
@Override
public void eat() {
System.out.println("Dog is eating dog food.");
}
}
// 具體食物類:貓糧
class CatFood implements Food {
@Override
public void eat() {
System.out.println("Cat is eating cat food.");
}
}
// 具體食物類:鳥糧
class BirdFood implements Food {
@Override
public void eat() {
System.out.println("Bird is eating bird seeds.");
}
}
// 抽象工廠類
interface AnimalFactory {
Animal createAnimal();
Food createFood();
}
// 具體工廠類:狗工廠類
class DogFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
@Override
public Food createFood() {
return new DogFood();
}
}
// 具體工廠類:貓工廠類
class CatFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
@Override
public Food createFood() {
return new CatFood();
}
}
// 具體工廠類:鳥工廠類
class BirdFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Bird();
}
@Override
public Food createFood() {
return new BirdFood();
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
AnimalFactory factory1 = new DogFactory();
Animal animal1 = factory1.createAnimal();
Food food1 = factory1.createFood();
// 輸出:Woof
animal1.makeSound();
// 輸出:Dog is eating dog food.
food1.eat();
AnimalFactory factory2 = new CatFactory();
Animal animal2 = factory2.createAnimal();
Food food2 = factory2.createFood();
// 輸出:Meow
animal2.makeSound();
// 輸出:Cat is eating cat food.
food2.eat();
AnimalFactory factory3 = new BirdFactory();
Animal animal3 = factory3.createAnimal();
Food food3 = factory3.createFood();
// 輸出:Tweet
animal3.makeSound();
// 輸出:Bird is eating bird seeds.
food3.eat();
}
}
1.2.4.3 優(yōu)缺點
- 優(yōu)點:
- 產(chǎn)品族管理:能夠創(chuàng)建相關(guān)聯(lián)的一系列產(chǎn)品(即產(chǎn)品族),適合創(chuàng)建一組相互依賴的對象,如某一類產(chǎn)品和它的配件。
- 解耦產(chǎn)品族與客戶端:客戶端不關(guān)心產(chǎn)品的具體實現(xiàn),而是通過抽象工廠統(tǒng)一獲取產(chǎn)品,降低了代碼的耦合度。
- 符合開閉原則:可以通過擴(kuò)展工廠來增加新的產(chǎn)品族,而不修改已有代碼,符合開閉原則。
- 缺點:
- 復(fù)雜度高:抽象工廠模式的結(jié)構(gòu)復(fù)雜,增加了類和接口的數(shù)量,導(dǎo)致系統(tǒng)變得臃腫,尤其是在不需要創(chuàng)建產(chǎn)品族的情況下。
- 擴(kuò)展產(chǎn)品等級結(jié)構(gòu)困難:雖然易于擴(kuò)展產(chǎn)品族(增加一組新產(chǎn)品),但如果需要為已有的產(chǎn)品族增加新的產(chǎn)品等級結(jié)構(gòu)(如在已有的產(chǎn)品類中再增加一個功能),需要修改所有的工廠接口和具體工廠類。
1.2.5 抽象工廠模式和工廠方法模式的區(qū)別與聯(lián)系
抽象工廠模式 是 工廠方法模式 的擴(kuò)展。抽象工廠模式解決了 多個相關(guān)產(chǎn)品 一起創(chuàng)建的需求,而工廠方法模式只處理單一產(chǎn)品的創(chuàng)建
1.2.5.1 聯(lián)系
工廠方法模式:主要用于創(chuàng)建 單個產(chǎn)品。每個具體的工廠類負(fù)責(zé)創(chuàng)建一種具體的產(chǎn)品,工廠方法模式的重點是為某個類型的產(chǎn)品提供創(chuàng)建方法,客戶端通過調(diào)用工廠接口來創(chuàng)建產(chǎn)品對象。
抽象工廠模式:不僅僅創(chuàng)建單個產(chǎn)品,而是用于創(chuàng)建一系列相關(guān)的產(chǎn)品族。抽象工廠為不同的產(chǎn)品族提供接口,允許客戶端使用不同的具體工廠來創(chuàng)建整個產(chǎn)品族中的所有產(chǎn)品,而不需要修改客戶端代碼。
1.2.5.2 不同點
-
產(chǎn)品的數(shù)量:
- 工廠方法模式:一個工廠類只創(chuàng)建一個產(chǎn)品。
- 抽象工廠模式:一個工廠類可以創(chuàng)建多個相關(guān)的產(chǎn)品(即產(chǎn)品族)。
-
復(fù)雜度:
- 工廠方法模式相對較簡單,關(guān)注于單一產(chǎn)品的創(chuàng)建。
- 抽象工廠模式更加復(fù)雜,適用于有多個產(chǎn)品需要同時創(chuàng)建,且這些產(chǎn)品通常是有內(nèi)在關(guān)聯(lián)的情況。
1.3 總結(jié)
- 不用工廠模式:簡單但耦合度高,擴(kuò)展性差。
- 簡單工廠模式:將對象的創(chuàng)建邏輯集中管理,但擴(kuò)展性差,違反開閉原則。
- 工廠方法模式:符合開閉原則,增加擴(kuò)展性,適合單個產(chǎn)品的創(chuàng)建,但類數(shù)量增多。
- 抽象工廠模式:適合創(chuàng)建一組相關(guān)產(chǎn)品,能管理產(chǎn)品族,擴(kuò)展性強(qiáng),但實現(xiàn)復(fù)雜,增加了系統(tǒng)的難度。
1.4 通過 簡單工廠模式+配置文件 解除耦合
通過簡單工廠模式和配置文件的結(jié)合,可以有效解除客戶端和具體產(chǎn)品類之間的耦合。這種方式通過在配置文件中配置具體產(chǎn)品類的名稱或類型,簡單工廠讀取配置文件動態(tài)創(chuàng)建對象,從而讓客戶端不需要直接依賴具體類。這樣如果以后要替換或新增產(chǎn)品,客戶端代碼無需修改,只需要更新配置文件和相應(yīng)的工廠邏輯。
1.4.1 步驟分析
- 配置文件:將需要創(chuàng)建的類(具體產(chǎn)品)的信息存儲在配置文件中,工廠可以根據(jù)該配置文件動態(tài)加載類。
- 簡單工廠模式:根據(jù)讀取到的配置文件的內(nèi)容,工廠通過反射等機(jī)制動態(tài)創(chuàng)建具體的產(chǎn)品對象。
- 解除耦合:客戶端不再直接依賴具體的產(chǎn)品類,而是依賴工廠類。通過工廠類讀取配置文件,靈活地創(chuàng)建不同的產(chǎn)品。
1.4.2 例子
類圖:

配置文件 (config.properties):配置文件中指定了產(chǎn)品類的全限定類名,便于工廠動態(tài)讀取和創(chuàng)建實例。
Dog=patterns.factory.Implementation.after.configfactory.Dog
Cat=patterns.factory.Implementation.after.configfactory.Cat
Bird=patterns.factory.Implementation.after.configfactory.Bird
// 簡單工廠類+配置文件
class AnimalFactory {
// 加載配置文件,獲取配置文件中配置的全類名,并創(chuàng)建該類的對象進(jìn)行存儲
private static HashMap<String, Animal> map = new HashMap<>();
// 加載配置文件, 只需要加載一次
static {
// 根據(jù)配置文件創(chuàng)建產(chǎn)品對象
Properties properties = new Properties();
InputStream in = AnimalFactory.class.getClassLoader().getResourceAsStream("config.properties");
try {
properties.load(in);
// 從配置文件對象中獲取全類名并創(chuàng)建對象
Set<Object> keys = properties.keySet();
for (Object key : keys) {
String className = properties.getProperty((String) key);
// 通過反射技術(shù)創(chuàng)建對象
Class<?> clazz = Class.forName(className);
Animal animal = (Animal) clazz.getDeclaredConstructor().newInstance();
// 將名稱和對象存儲到容器中
map.put(((String) key).toLowerCase(), animal);
}
if (in != null) {
in.close();
}
} catch (IOException | ReflectiveOperationException e) {
e.printStackTrace();
}
}
public static Animal createAnimal(String type) {
return map.get(type.toLowerCase());
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
// 客戶端通過工廠獲取具體產(chǎn)品,而不關(guān)心具體產(chǎn)品的實現(xiàn)
Animal animal1 = AnimalFactory.createAnimal("Dog");
// 輸出:Woof
animal1.makeSound();
Animal animal2 = AnimalFactory.createAnimal("Cat");
// 輸出:Meow
animal2.makeSound();
Animal animal3 = AnimalFactory.createAnimal("Bird");
// 輸出:Tweet
animal3.makeSound();
}
}
1.4.3 關(guān)鍵點
配置文件:配置文件
config.properties存儲了具體類的類名信息,這樣可以方便更改具體的實現(xiàn)。比如,修改配置文件中的Dog為Cat,就會創(chuàng)建Cat類的對象,而不需要修改客戶端代碼。反射機(jī)制:工廠通過反射動態(tài)加載配置文件中的類名,并創(chuàng)建對應(yīng)的實例。
解耦合:客戶端不再依賴于具體的
Dog或Cat類,而是依賴于工廠,工廠通過配置文件靈活創(chuàng)建實例。即便以后新增其他Animal實現(xiàn)類,客戶端也無需修改,只需調(diào)整配置文件。
1.4.4 優(yōu)缺點
- 優(yōu)點:
- 低耦合:客戶端不直接依賴具體產(chǎn)品,具體產(chǎn)品類可以靈活替換。
- 擴(kuò)展性強(qiáng):通過修改配置文件即可動態(tài)替換不同的產(chǎn)品類,而不影響代碼。
- 維護(hù)性好:新增產(chǎn)品時,只需新增實現(xiàn)類和配置,而不需要修改客戶端代碼。
- 缺點:
- 反射開銷:使用反射機(jī)制會帶來一定的性能開銷,且在編譯期無法檢測類的有效性,容易在運行時出現(xiàn)錯誤。
- 配置管理:需要額外的配置文件管理。
1.5 JDK源碼解析-Collection.iterator方法
Collection.iterator() 方法的設(shè)計實際上可以看作是工廠模式的一個應(yīng)用。雖然工廠模式在經(jīng)典的形式中通常用于創(chuàng)建獨立的對象,但在 Java 的集合框架中,iterator() 方法提供了類似工廠模式的功能:它通過接口返回一個 Iterator 對象,而不用暴露 Iterator 的具體實現(xiàn),符合工廠模式的核心思想,即將對象的創(chuàng)建和使用分離。
類圖:

1.5.1 Iterator 和 Collection
Iterator 是 Java 集合框架中的一個接口,允許客戶端在不知道集合內(nèi)部實現(xiàn)的情況下進(jìn)行遍歷。Collection 是所有集合類的頂層接口,如 List、Set、Queue 等都實現(xiàn)了這個接口。而 iterator() 方法則是 Collection 接口中的一個方法,它返回該集合元素的迭代器(Iterator),用于遍歷集合。
1.5.2 如何體現(xiàn)工廠模式
工廠模式的核心思想是:
- 提供一個接口,用于創(chuàng)建對象。
- 隱藏具體實現(xiàn),讓客戶端只關(guān)心接口,不關(guān)心具體實現(xiàn)。
iterator() 方法符合這種思路,它提供一個接口 Iterator 來遍歷集合,而客戶端并不需要關(guān)心具體集合類是如何實現(xiàn) Iterator 的。
-
Collection 是集合的頂層接口,定義了
iterator()方法。 -
Iterator 是迭代器的接口,定義了迭代器需要的方法,如
hasNext()、next()、remove()。 -
List 和 Set 分別實現(xiàn)了
Collection接口,提供了具體的iterator()實現(xiàn)。它們返回的是各自特定的迭代器。
1.5.4 工廠模式的體現(xiàn)
-
Collection接口中的iterator()方法就像是一個工廠方法,返回Iterator對象。 - 每個具體的集合類(如
List和Set)都提供了自己的iterator()實現(xiàn)。這相當(dāng)于工廠方法中的不同工廠類,返回不同的產(chǎn)品對象(不同的Iterator實現(xiàn))。 - 客戶端調(diào)用
iterator()后,得到的是Iterator接口,而不是具體的Iterator實現(xiàn)類。這種方式屏蔽了集合內(nèi)部的實現(xiàn)細(xì)節(jié),客戶端不需要關(guān)心集合的具體類型,只需要按照Iterator接口的規(guī)范來操作集合。
1.5.4.1 Collection 接口(簡化版)
public interface Collection<E> {
Iterator<E> iterator();
}
1.5.4.2 List 和 Set 類
public class Client {
public static void main(String[] args) {
// 使用ArrayList的迭代器
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
Iterator<String> listIterator = list.iterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
// 使用HashSet的迭代器
HashSet<String> set = new HashSet<>();
set.add("X");
set.add("Y");
set.add("Z");
Iterator<String> setIterator = set.iterator();
while (setIterator.hasNext()) {
System.out.println(setIterator.next());
}
}
}
1.5.5 工廠模式的優(yōu)缺點在 Collection.iterator() 中的體現(xiàn)
- 優(yōu)點:
-
解耦:客戶端無需知道集合的具體實現(xiàn),只需要通過
Iterator接口來進(jìn)行遍歷。無論是List、Set還是其他集合類型,都提供統(tǒng)一的遍歷方式。 -
擴(kuò)展性強(qiáng):如果添加新的集合類型,只需要提供自己的
iterator()實現(xiàn)即可,客戶端不需要做任何修改。
- 缺點:
- 工廠模式可能會導(dǎo)致類的數(shù)量增加,因為每種具體集合類型都需要提供自己的迭代器實現(xiàn)。