淺談Java設計模式之工廠模式

工廠模式是JAVA中最經常使用的設計模式之一,這種設計模式屬於建立性模式,是一種建立對象的最佳方式。在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用同一個接口來指向新建立的對象例如:你在買一輛車時並不須要這輛車的具體實現,只要從工廠裏直接提貨就好。
java

咱們來舉一個簡單的栗子體會一下工廠模式的含義,在這個栗子中咱們建立一個形狀接口及其實現類,還有一個工廠類。設計模式

第一步:建立接口Shape.javaide

public interface Shape {
    void draw();
}

第二步:建立Shape.java的實現類spa

Circle.java設計

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}

Rectangle.java對象

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}

Square.java接口

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}

第三步:建立一個工廠ShapeFactory1.javaci

public class ShapeFactory1 {

    private final String CIRCLE = "CIRCLE";
    private final String RECTANGLE = "RECTANGLE";
    private final String SQUARE = "SQUARE";

    /**
     * 使用getShape()獲取形狀類型對象
     * @param shapeType
     * @return
     */
    public Shape getShape(String shapeType){
        if(StringUtils.isEmpty(shapeType)){
            return null;
        }
        if(shapeType.equalsIgnoreCase(CIRCLE)){
            return new Circle();
        }else if(shapeType.equalsIgnoreCase(RECTANGLE)){
            return new Rectangle();
        }else if(shapeType.equalsIgnoreCase(SQUARE)){
            return new Square();
        }

        return null;
    }
}

第四步:使用該工廠來建立對象get

public class FactoryPatternDemo1 {
    public static void main(String[] args) {
        ShapeFactory1 factory1 = new ShapeFactory1();

        //獲取circle對象
        Shape shape1 = factory1.getShape("circle");
        shape1.draw();

        //獲取Rectangle對象
        Shape shape2 = factory1.getShape("Rectangle");
        shape2.draw();

        //獲取Square對象
        Shape shape3 = factory1.getShape("Square");
        shape3.draw();
    }
}

第五步:驗證輸出
產品

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

由此總結工廠模式的優缺點:

優勢:

一、一個調用者只要知道其名字就能夠,不須要知道其建立過程;

二、拓展性高:增長產品時只須要拓展一個工廠類就行了。

缺點:

每次增長一個產品就要新增一個具體類和實現工廠,使得系統中類的個數成倍增長,必定程度上增長了系統的複雜度。

因此,咱們在建立複雜對象時適合使用工廠模式,建立簡單對象時使用new關鍵字來建立

-----------------------------------------------我是一條分割線-----------------------------------------------

上面的代碼中存在一個很大的問題:每增長一個實現類就要修改ShapeFactory1.java的代碼,這樣是及其不正確的作法,爲了解決這個問題,咱們使用反射機制來改進。

升級版本一:

工廠類:

public class ShapeFactory2 {

    public static Object getClass(Class<?extends Shape> clazz){
        Object obj = null;
        try {
            obj = Class.forName(clazz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

使用工廠:

public class FactoryPatternDemo2 {
    public static void main(String[] args) {
        Circle circle = (Circle) ShapeFactory2.getClass(Circle.class);
        circle.draw();

        Rectangle rectangle = (Rectangle) ShapeFactory2.getClass(Rectangle.class);
        rectangle.draw();

        Square square = (Square) ShapeFactory2.getClass(Square.class);
        square.draw();

    }
}

這個版本雖然改進了頻繁修改代碼的缺點,但仍是存在一個問題:調用後不能直接拿到想要的對象還要進行類型強轉。此次咱們使用泛型來解決。

升級版本二:

public class ShapeFactory3 {
    public static <T> T getClass(Class<? extends T> clazz) {
        T obj = null;

        try {
            obj = (T) Class.forName(clazz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return obj;
    }
}

使用工廠:

public class FactoryPatternDemo3 {
    public static void main(String[] args) {

        Circle circle = ShapeFactory3.getClass(Circle.class);
        circle.draw();

        Rectangle rect = ShapeFactory3.getClass(Rectangle.class);
        rect.draw();

        Shape square = ShapeFactory3.getClass(Square.class);
        square.draw();
    }
}
相關文章
相關標籤/搜索