簡單工廠

ChengNengNeng發表於2020-10-12

首先說明,簡單工廠並不屬於23中設計模式。
學習設計模式前,首先了解簡單工廠,是程式碼設計中經常用到的。

現在有個案例如下程式碼:

// Video的抽象類
public abstract class Video {
    public abstract void produce();
}

//Video的兩個實現類

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("錄製java視訊");
    }
}

public class PythonVideo extends Video{
    @Override
    public void produce() {
        System.out.println("錄製python視訊");
    }
}

//客戶端

public class Test {
    public static void main(String[] args) {
        Video video = new JavaVideo();
        video.produce();
        Video video2 = new PythonVideo();
        video.produce();
    }
}

執行結果

錄製java視訊
錄製python視訊

問題說明:
當前程式碼客戶端對具體實現類的依賴太強。

我們用簡單工廠將其優化

//新增工廠類VideoFactory
public class VideoFactory {
    public Video getVideo(String type) {
        if ("java".equalsIgnoreCase(type)) {
            return new JavaVideo();
        } else if ("python".equalsIgnoreCase(type)) {
            return new PythonVideo();
        }
        return null;
    }
}
//修改客戶端
public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo("java");
        video.produce();
    }
}

這樣就可以了,我們只需要在客戶端向工廠類傳入型別引數,就可以得到想要的物件。
但是,我們會發現,當出現一個新的Video類時,我們需要修改工廠類的方法,違背了開閉原則(對修改關閉,對擴充套件開放)。
需要進行優化,這裡我們通過反射的法方法來優化工廠方法。程式碼如下

//修改工廠類的getVideo方法
public class VideoFactory {
    public Video getVideo(Class c) {
        Video video = null;
        try {
            video = (Video)Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return video;
    }
}
//修改客戶端
public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo(JavaVideo.class);
        video.produce();
    }
}

這樣修改之後,我們只需要在客戶端傳入我們想要的型別class,就可以獲取到對應型別的物件,達到多型別擴充套件的目的。

相關文章