設計模式——Factory工廠模式

設計模式——Factory工廠模式

工廠模式

       實例化對象,用工廠方法代替new操作。定義一個創建對象的接口指向其實現的子類,讓父類決定實例的生成方式,讓子類決定實現的細節。這樣有利於擴展。

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

作爲一種創建類模式,在任何需要生成複雜對象的地方,都可以使用工廠方法模式。有一點需要注意的地方就是複雜對象適合使用工廠模式,而簡單對象,特別是只需要通過 new 就可以完成創建的對象,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統的複雜度。

應用實例: 1、JDBC中調用對數據庫操作的API,而不必關係底層實現的是MySQL還是Oracle,只需要傳入對應的類名。

優點: 1、一個調用者想創建一個對象,只要知道其名稱就可以了。 2、擴展性高,如果想增加一個產品,只要擴展一個工廠類就可以。 3、屏蔽產品的具體實現,調用者只關心產品的接口。

缺點:每次增加一個產品時,都需要增加一個具體類和對象實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事。

 

Shape.java

定義一個接口,規範對象使用行爲。

public interface Shape {
   
void draw();
}

兩個實現類

實現相同的接口,細節實現不同的功能。

public class Square implements Shape {
   
@Override
   
public void draw() {
        System.
out.println("我是方形");
   
}
}

 

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("我是圓形");
    }
}

ShapeFactory.java

實現了三個方法分別對應不同的獲取對象的方式,推薦使用第二和第三個方法,使用了反射機制,這樣新增功能,比如三角形時,不用修改工廠類,而使用第一種方法需要修改。

public class ShapeFactory {

    //使用 getShape 方法獲取形狀類型的對象
    public static Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if ("Circle".equals(shapeType)) {
            return new Circle();
        } else if ("Square".equals(shapeType)) {
            return new Square();
        }
        return null;
    }

    //根據類名獲取
    public static Shape getShapeByClassName(String className){
        Shape shape=null;
        try {
            shape = (Shape) Class.forName(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return shape;
    }

    //根據Class類型 獲取
    public static <T> T getShape(Class<? extends T> clazz) {
        T obj = null;
        try {
            obj = (T) Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

Test.java

測試,輸出爲:

我是圓形

我是方形

我是圓形

public class Test {
    public static void main(String[] args){
        Shape shape1 = ShapeFactory.getShape("Circle");
        shape1.draw();
        Shape shape2 = ShapeFactory.getShapeByClassName("factory.shapepack.Square");
        shape2.draw();
        Shape shape3 = ShapeFactory.getShape(Circle.class);
        shape3.draw();
    }
}

 

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創建其他工廠。該超級工廠又稱爲其他工廠的工廠

在抽象工廠模式中,接口是負責創建一個相關對象的工廠,不需要顯式指定它們的類。每個生成的工廠都能按照工廠模式提供對象。

能夠提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。在一個工廠裏聚合多個同類產品。這裏理解上有一定困難,打個比方:

工作了,爲了參加一些聚會,肯定有兩套或多套衣服吧,比如說有商務裝(成套,一系列具體產品)、時尚裝(成套,一系列具體產品),即一系列具體產品。假設一種情況,某一個衣櫃(具體工廠)只能存放某一種這樣的衣服(成套,一系列具體產品),每次拿這種成套的衣服時也自然要從這個衣櫃中取出了。用 OO 的思想去理解,所有的衣櫃(具體工廠)都是衣櫃類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產品),褲子(某一具體產品),這些具體的上衣其實也都是上衣(抽象產品),具體的褲子也都是褲子(另一個抽象產品)。

 

示例代碼,新增一個Color接口和Red和Blue兩個實現類以及ColorFactory工廠類,類似於上面的Shape實現方式。

新增一個AbstractFactory抽象工廠類

public abstract class AbstractFactory {
    protected abstract Color getColor(String color);
    protected abstract Shape getShape(String shape) ;
}

ColorFactory和ShapeFactory繼承該抽象工廠類,如ColorFactory:

public class ColorFactory extends AbstractFactory {
    //簡單起見這裏不使用反射機制
    public Color getColor (String colorType){
        if (colorType == null) {
            return null;
        }
        if ("Red".equals(colorType)) {
            return new Red();
        } else if ("Blue".equals(colorType)) {
            return new Blue();
        }
        return null;
    }

    @Override
    //getShape不具體實現,讓ShapeFactory去實現
    protected Shape getShape(String shape) {
        return null;
    }
}

新增一個工廠生成器類來獲取對應的具體的工廠

FactoryProducer

public class FactoryProducer {
    public static AbstractFactory getFactory(String choice){
        //這裏簡單起見不使用反射機制
        if("Shape".equals(choice)){
            return new ShapeFactory();
        } else if("Color".equals(choice)){
            return new ColorFactory();
        }
        return null;
    }
}

 

測試輸出:

我是方形

填充紅色

AbstractFactory shapeFactory = FactoryProducer.getFactory("Shape");
shapeFactory.getShape("Square").draw();
AbstractFactory colorFactory = FactoryProducer.getFactory("Color");
colorFactory.getColor("Red").fill();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章