天天看點

設計模式之工廠方法模式【Factory Method Pattern】

工廠方法的解題思路是采用無為而治的方式,即自己不知道具體如何實作,把它延遲到子類實作。

1、定義

定義一個用于建立對象的接口,讓子類決定執行個體化哪個具體類。

2、使用場景

在任何需要生成複雜對象的地方,都可以使用工廠方法模式。

3、UML圖

設計模式之工廠方法模式【Factory Method Pattern】
  1. Product:抽象産品。
  2. ConcreteProduct:具體産品
  3. Factory:建立器,抽象工廠,申明建立Product的工廠方法。
  4. ConcreteFactory:具體工廠,實作具體的業務邏輯。

4、示例代碼

public abstract class Product {

}
public class ConcreteProduct extends Product {

}

public abstract class Factory {

    public abstract Product createProduct();

    //有時在一些方法中需要調用工廠方法來擷取 Product 對象
    public void someOperation() {
        Product product = createProduct();
    }
}

public class ConcreteFactory extends Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProduct();
    }
}
           

對于createProduct()方法,需要哪個産品就生産哪個産品,但有時也可以使用反射的方式更簡潔地生産具體的産品對象。

反射實作:

public abstract class Factory {
    public abstract <T extends Product> T createProduct(Class<T> cls);
}

public class ConcreteFactory extends Factory {

    @Override
    public <T extends Product> T createProduct(Class<T> cls) {
        Product p = null;
        try {
            p = (Product) Class.forName(cls.getName()).newInstance();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return (T) p;
    }
}
           

5、簡單工廠/靜态工廠

抽象出抽象工廠類 Factory 來,通常的情況是有多個不同的具體工廠實作。以上隻是實作了一個具體工廠concreteFactory,但通常一般還可能定義ConcreteFactoryA,ConcreteFactoryB …等,以産生不同的産品。這種我們稱為多工廠方法模式。

如果我們确定我們的工廠類隻有一個的時候,可以将其簡化掉,将對應的工廠方法改為靜态方法,那這種情況就變成了簡單工廠/靜态工廠了,它是工廠方法的一個弱化版本。

public class Factory {

    public static Product createProduct() {
        return new ConcreteProduct();
    }
}
           

6、Java源碼中的實作

java中的 List , Set 就應用了工廠方法模式來擷取 Iterator。它們都實作了 Iterable 接口,來生産具體的 Iterator。

1、定義生産 Iterator 的接口

public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();

    //...
} 
           

2、 ArrayList 生産具體的 Iterator 的實作

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    //ArrayList 生産具體的 Iterator 的實作   
    public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        //...
    }

    //...
}
           

3、HashSet生産具體的 Iterator 的實作

public class HashSet<E> extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    public Iterator<E> iterator() {
            return map.keySet().iterator();
    }
}
           

繼續閱讀