第四天:工廠方法模式、抽象工廠模式

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)點就是:解耦。

工廠模式主要分為以下幾種類型:

  1. 簡單工廠模式(Simple Factory)
  2. 工廠方法模式(Factory Method)
  3. 抽象工廠模式(Abstract Factory)

1.2 場景:操作不同類型的動物

我們假設(shè)有一個場景,程序需要對不同種類的動物進(jìn)行操作,動物可以發(fā)出不同的聲音。

1.2.1 不用工廠模式

1.2.1.1 分析

在這個例子中,客戶端代碼直接依賴于具體的動物類 ( Dog, Cat, Bird),這意味著如果我們添加新的動物類型或者更改現(xiàn)有的創(chuàng)建邏輯,必須修改客戶端代碼。這種實現(xiàn)方式耦合度較高,不符合開閉原則。

類圖:

image.png
// 動物接口
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)缺點

  1. 優(yōu)點:
  • 簡單直接:客戶端直接實例化對象,代碼較為簡單,適用于對象數(shù)量少、變動少的情況。
  1. 缺點:
  • 高耦合性:客戶端依賴具體類,任何對象的變化(如新增類、修改類)都需要修改客戶端代碼,違反開閉原則。
  • 擴(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 類的邏輯,這違反了開閉原則。

類圖:

image.png
// 簡單工廠類
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)缺點

  1. 優(yōu)點:
  • 創(chuàng)建邏輯集中:將對象的創(chuàng)建集中在一個工廠類中,客戶端只需知道要創(chuàng)建的對象類型(傳遞字符串或參數(shù)),降低了對具體類的依賴。
  • 簡化客戶端代碼:客戶端不再負(fù)責(zé)具體對象的創(chuàng)建,只需調(diào)用工廠方法。
  1. 缺點:
  • 違反開閉原則:如果需要添加新的類型,需要修改工廠類的創(chuàng)建邏輯(if-elseswitch-case 語句)。
  • 復(fù)雜性增加:隨著對象類型增多,工廠類的創(chuàng)建邏輯可能變得復(fù)雜,不利于維護(hù)。

1.2.1.4 擴(kuò)展:靜態(tài)工廠

在開發(fā)中也有一部分人將工廠類中的創(chuàng)建對象的功能定義為靜態(tài)的,這個就是靜態(tài)工廠模式,它也不是 23 種設(shè)計模式中的。

類圖:

image.png
// 靜態(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)有代碼。

類圖:

image.png
// 抽象工廠類
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)缺點

  1. 優(yōu)點:
  • 符合開閉原則:工廠方法模式通過新增具體工廠類來擴(kuò)展產(chǎn)品類型,而不修改已有代碼,符合開閉原則。
  • 解耦合:客戶端不再依賴于具體類,而是依賴于抽象工廠接口,提升了代碼的可擴(kuò)展性和靈活性。
  • 職責(zé)分離:每個工廠負(fù)責(zé)創(chuàng)建一種產(chǎn)品,工廠類和產(chǎn)品類的職責(zé)更加明確,便于維護(hù)。
  1. 缺點:
  • 增加類的數(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)建動物和食物的接口。不同的具體工廠(DogFactoryCatFactory、BirdFactory)負(fù)責(zé)創(chuàng)建不同的動物及其食物。
  • 這種模式適合在需要創(chuàng)建相關(guān)產(chǎn)品族時使用,比如同一類的動物和它們的食物。在不修改已有工廠的情況下,可以擴(kuò)展新的動物和食物種類。

類圖:

image.png
// 食物接口
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)缺點

  1. 優(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)品族,而不修改已有代碼,符合開閉原則。
  1. 缺點:
  • 復(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 不同點

  1. 產(chǎn)品的數(shù)量

    • 工廠方法模式:一個工廠類只創(chuàng)建一個產(chǎn)品
    • 抽象工廠模式:一個工廠類可以創(chuàng)建多個相關(guān)的產(chǎn)品(即產(chǎn)品族)。
  2. 復(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 步驟分析

  1. 配置文件:將需要創(chuàng)建的類(具體產(chǎn)品)的信息存儲在配置文件中,工廠可以根據(jù)該配置文件動態(tài)加載類。
  2. 簡單工廠模式:根據(jù)讀取到的配置文件的內(nèi)容,工廠通過反射等機(jī)制動態(tài)創(chuàng)建具體的產(chǎn)品對象。
  3. 解除耦合:客戶端不再直接依賴具體的產(chǎn)品類,而是依賴工廠類。通過工廠類讀取配置文件,靈活地創(chuàng)建不同的產(chǎn)品。

1.4.2 例子

類圖:

image.png

配置文件 (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)鍵點

  1. 配置文件:配置文件 config.properties 存儲了具體類的類名信息,這樣可以方便更改具體的實現(xiàn)。比如,修改配置文件中的 DogCat,就會創(chuàng)建 Cat 類的對象,而不需要修改客戶端代碼。

  2. 反射機(jī)制:工廠通過反射動態(tài)加載配置文件中的類名,并創(chuàng)建對應(yīng)的實例。

  3. 解耦合:客戶端不再依賴于具體的 DogCat 類,而是依賴于工廠,工廠通過配置文件靈活創(chuàng)建實例。即便以后新增其他 Animal 實現(xiàn)類,客戶端也無需修改,只需調(diào)整配置文件。

1.4.4 優(yōu)缺點

  1. 優(yōu)點:
  • 低耦合:客戶端不直接依賴具體產(chǎn)品,具體產(chǎn)品類可以靈活替換。
  • 擴(kuò)展性強(qiáng):通過修改配置文件即可動態(tài)替換不同的產(chǎn)品類,而不影響代碼。
  • 維護(hù)性好:新增產(chǎn)品時,只需新增實現(xiàn)類和配置,而不需要修改客戶端代碼。
  1. 缺點:
  • 反射開銷:使用反射機(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)建和使用分離。

類圖:

image.png

1.5.1 Iterator 和 Collection

Iterator 是 Java 集合框架中的一個接口,允許客戶端在不知道集合內(nèi)部實現(xiàn)的情況下進(jìn)行遍歷。Collection 是所有集合類的頂層接口,如 List、SetQueue 等都實現(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()。
  • ListSet 分別實現(xiàn)了 Collection 接口,提供了具體的 iterator() 實現(xiàn)。它們返回的是各自特定的迭代器。

1.5.4 工廠模式的體現(xiàn)

  • Collection 接口中的 iterator() 方法就像是一個工廠方法,返回 Iterator 對象。
  • 每個具體的集合類(如 ListSet)都提供了自己的 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)

  1. 優(yōu)點:
  • 解耦:客戶端無需知道集合的具體實現(xiàn),只需要通過 Iterator 接口來進(jìn)行遍歷。無論是 List、Set 還是其他集合類型,都提供統(tǒng)一的遍歷方式。
  • 擴(kuò)展性強(qiáng):如果添加新的集合類型,只需要提供自己的 iterator() 實現(xiàn)即可,客戶端不需要做任何修改。
  1. 缺點:
  • 工廠模式可能會導(dǎo)致類的數(shù)量增加,因為每種具體集合類型都需要提供自己的迭代器實現(xiàn)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容