1. 程式人生 > >設計模式|簡單工廠、工廠方法、抽象工廠

設計模式|簡單工廠、工廠方法、抽象工廠

簡單工廠

概念

  • 定義:

    由一個工廠物件決定創建出哪一種產品類的例項

  • 型別:

    建立型,但不屬於GOF23種設計模式

  • 使用場景

  • 優點

  • 缺點

案例一

動物的抽象類

public abstract class Animal {
    public abstract void eat();
}
public class Cat extends Animal {
    public void eat() {
        System.out.println("Cat is eating");
    }
}
public class Dog extends Animal
{ public void eat() { System.out.println("Dog is eating"); } }
public class Demo {
    @Test
    public void demo1(){
        Animal cat = new Cat();
        cat.eat();
        Animal dog = new Dog();
        dog.eat();
    }
}

在這裡插入圖片描述

缺點:應用層依賴具體的實現類

思路:讓應用層不依賴具體的實現類

重構

簡單工廠demo1

public class
AnimalFactory { public Animal getAnimal(String name){ Animal animal = null; if ("cat".equalsIgnoreCase(name)){ animal = new Cat(); }else if ("dog".equalsIgnoreCase(name)){ animal = new Dog(); } return animal; } }

測試

@Test
public void demo2(){
    AnimalFactory animalFactory = new AnimalFactory();
    Animal cat = animalFactory.getAnimal("cat");
    if (cat == null){
        return;
    }
    cat.eat();
}

缺點:當需要新增一個實現時,需要破壞animalFactory原有的程式碼,不符合開閉原則。

簡單工廠demo2

在AnimalFactory工廠類中,重寫getAnimal方法

public Animal getAnimal(Class<Cat> c){
    Animal animal = null;
    try {
        animal = (Animal) Class.forName(c.getName()).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return animal;
}

測試

@Test
public void demo3(){
    AnimalFactory animalFactory = new AnimalFactory();
    Animal cat = animalFactory.getAnimal(Cat.class);
    if (cat == null){
        return;
    }
    cat.eat();
}

在這裡插入圖片描述

測試成功

工廠方法

概念

  • 定義:定義一個建立物件的介面,但讓實現這個介面的類來決定例項化哪個類。工廠方法讓類的例項化推遲到子類中進行。
  • 型別:建立型
  • 使用場景
    • 建立物件需要大量重複的程式碼
    • 應用層不依賴與產品類例項如何被建立、實現等細節。
    • 一個類通過其子類來指定建立哪個物件
  • 優點
  • 使用者只需要關心所需要物件對應的工廠,無需關心建立的細節。
  • 加入新的功能是複合開閉原則,提高擴充套件性
  • 缺點
    • 類的個數容易過多,增加複雜度
    • 增加了系統的抽象性和理解難度

案例二

安裝工廠方法的定義,對上面的案例一進行重構

  • 將AnimalFactory定義成抽象類,定義一個建立物件的抽象方法。
public abstract class AnimalFactory {

    public abstract Animal getAnimal();

}

AnimalFactory只是定義一種規範,不定義具體的實現。完全交給子類來實現。

public class CatFactory extends AnimalFactory {
    public Animal getAnimal() {
        return new Cat();
    }
}
public class DogFactory extends AnimalFactory {
    public Animal getAnimal() {
        return new Dog();
    }
}

應用層呼叫

public class Demo {
    @Test
    public void demo4(){
        AnimalFactory catFactory = new CatFactory();
        Cat cat = (Cat) catFactory.getAnimal();
        cat.eat();
    }
}

在這裡插入圖片描述

這樣擴充套件性增加了。

應用

Collection中的iterator方法

java.util.Collection 介面中定義了一個抽象的 iterator() 方法,該方法就是一個工廠方法。

對於 iterator() 方法來說 Collection 就是一個根抽象工廠,下面還有 List 等介面作為抽象工廠,再往下有 ArrayList 等具體工廠。

java.util.Iterator 介面是根抽象產品,下面有 ListIterator 等抽象產品,還有 ArrayListIterator 等作為具體產品。

使用不同的具體工廠類中的 iterator 方法能得到不同的具體產品的例項。