1. 程式人生 > 資訊 >英特爾 11 代酷睿 i7-11800H 首次現身:高階遊戲本將搭載

英特爾 11 代酷睿 i7-11800H 首次現身:高階遊戲本將搭載

靜態工廠
在最早的《DesignPattern》這本書中 靜態工廠是沒有的 工廠系列就兩個模式 工廠方法和抽象工廠,但是也有人說靜態工廠是工廠模式

什麼是工廠?
1.任何可以產生(new)物件的方法或類,都可以稱之為工廠
2.看到1個方法 它的返回值return是1個物件 就可以稱之為1個工廠

所以單例也是一種工廠,單例模式的 getInstance 就是拿到1個物件 所以有人把單例模式 稱為靜態工廠

為什麼要工廠? 我們已經可以new產生物件了,為什麼還要工廠?
工廠可以靈活控制生產過程,可以加許可權、修飾decorate、日誌log等

我們先寫1個類 Car

public class Car {
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

然後我們再建立1個Main類 new出來1個Car

public class Main {
    public static void main(String[] args) {
        Car c = new Car();
        c.go();
    }
}
執行main方法

現在開的是Car車 我明天想開Plane飛機怎麼辦? 可以定製交通工具(實現類 )嗎?
我們當然可以再建立1個Plane飛機類,然後main方法去建立1個飛機

public class Plane {
    public void go(){
        System.out.println("Plane fly xixixixixixixi....");
    }
}
public class Main {
    public static void main(String[] args) {
//        Car c = new Car();
//        c.go();
        Plane p = new Plane();
        p.go();
    }
}

如果我以後想開火車Train,船Boat等等?難道還是像這樣 1個1個擴充套件嗎?程式碼太多了,既要新建1個類,還要修改main方法裡的內容,我想少點,怎麼辦?
我們可以建立1個介面Moveable ,其他的所有交通工具去實現這個介面

public interface Moveable {
    void go();
}
public class Plane implements Moveable{
    public void go(){
        System.out.println("Plane fly xixixixixixixi....");
    }
}
public class Car implements Moveable{
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

這樣main方法可以利用多型,只用改new後面的類就行了,不管呼叫

public class Main {
    public static void main(String[] args) {
        Moveable m = new Plane();
        m.go();
    }
}

程式碼只用修改1個地方,不用像第1種方法,要刪除修改至少2段

需求又來了,我想任意定製旅途過程 怎麼辦?
實際中的應用 我new 1個交通工具後 我要求你必須控制權限 那麼我的程式碼要修改在Plane類裡 必須要來回的變;我可以把 產生物件的這個過程 不用new 我交給1個工廠方法
1.簡單工廠VehicleFatory
建立1個VehicleFactory類 裡面有幾個方法 比如返回Car物件的 createCar()方法 在這個方法裡面 我們可以對它進行日誌處理 許可權處理等;而且VehicleFactory類除了 產生Car外 還可以產生Plane等

public class VehicleFactory {
    public Car createCar(){
        return new Car();
    }
    public Plane createPlane(){
        return new Plane();
    }
}

但是這種方法不太好 因為它雖然很簡單 但是可擴充套件性不太好 當我們新新增1種交通工具 火車train的時候 裡面就要新新增新的createTrain方法 而且裡面的 許可權處理的操作也是寫死的

針對每個產品做1個工廠
對於Car來說 我加1個CarFactory類

public class CarFactory {
    public Car createCar(){
        System.out.println("a car created!");
        return new Car();
    }
}

如果我們想用CarFactory的話 main方法要這樣寫

public class Main {
    public static void main(String[] args) {
        Moveable m = new CarFactory().createCar();
        m.go();
    }
}
簡單工廠

想來個Plane的話 就寫個PlaneFactory().createPlane() 想來個broom的話 就寫個BroomFactory().createBroom()
但是問題來了 當我們要新增一種新的交通工具的時候 我們首先得把它的工廠做出來PlaneFactory,broomFactory 接下來 我還要把程式碼改一下 更麻煩
總結一下:任意定製交通工具,我們可以 繼承Moveable;任意定製生產過程,我們可以Moveable XXXFactory.create()

2.抽象工廠
因為叫抽象工廠,所以是任意定製產品一族(不只1種系列產品),叫abstractFactory 更加抽象這個問題。
比如:現在是這樣的 ,作為1個司機 我開著一輛車 車還在跑,然後這個司機,他手裡還持有1個武器AK47 就叫AK47類,他還可以吃一點麵包Bread 有個麵包類
AK47類可以開槍,Brand類可以列印品牌

public class AK47 {
    public void shoot(){
        System.out.println("tutututututu.....");
    }
}

public class Brand {
    public void printName(){
        System.out.println("wdm");
    }
}

那麼這樣我就模擬了 很多類產品 Car,AK47,Bread ,其實這個是 產品簇的概念 我們有沒有一種方式 可以靈活的指定 來擴充套件新的產品簇,比如現在我來一個人是魔法師 他騎的是掃帚Broom 吃的是蘑菇Mushroom 它的魔法棒MagicStick可以發電 這樣當新的產品加進來的時候 程式碼不用改太多呢?
可以的 我們可以new 1個AbstractFactory. 這個抽象工廠 可以生產 1系列產品 他可以生產食物,武器,交通工具

public abstract class Food {
    abstract void printName();
}

public abstract class Weapon {
    abstract void shoot();
}

public abstract class Vehicle {
    abstract void go();
}

我們假設 這個抽象工廠會產生 3類產品;第1類是Food,第2類是Vehicle,第3類是Weapon,他們都可以返回對應的物件,可以生成抽象的產品

public abstract class AbstractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}

然後我們讓所有的不同類別的產品 去繼承
現代人的工具簇就是 Weapon對應AK47,Food對應Bread,Vehicle對應Car

//現代人的工具包
public class Car extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

public class Brand extends Food{
    public void printName(){
        System.out.println("wdm");
    }
}

public class AK47 extends Weapon{
    public void shoot(){
        System.out.println("tutututututu.....");
    }
}

我們做1個現代工廠ModernFactory,幫我們去生產這些東西,而不必自己去new

public class ModernFactory extends AbstractFactory {
    @Override
    Food createFood() {
        return new Brand();
    }
    @Override
    Vehicle createVehicle() {
        return new Car();
    }
    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}

魔法師的工具簇就是 Weapon對應MagStick,Food對應MushRoom,Vehicle對應Broom

//魔法師的工具包
public class Broom extends Vehicle {
    public void go(){
        System.out.println("Broom flying shushushus....");
    }
}

public class MushRoom extends Food {
    public void printName(){
        System.out.println("毒蘑菇");
    }
}

public class MagicStick extends Weapon{
    public void shoot(){
        System.out.println("dian dian dian dian....");
    }
}

魔法師就是魔法工廠MagicFactory,幫我們去生產這些東西

public class MagicFactory extends AbstractFactory{
    @Override
    Food createFood() {
        return new MushRoom();
    }
    @Override
    Vehicle createVehicle() {
        return new Broom();
    }
    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}

現在,我們main方法裡面程式碼就簡單了
之間我們需要1個1個new

Car c =new Car();
        c.go();
        AK47 w=new AK47();
        w.shoot();
        Bread b=new Bread();
        b.printName();

現在不需要了 直接呼叫現代工廠裡的方法就行

AbstractFactory f = new ModernFactory();
Vehicle c = f.createVehicle();
Weapon w = f.createWeapon();
Food  b = f.createFood();

而且修改程式碼恨少,你想改成 魔法世界工廠 你就把new 後面改一下 下面的都不用改 new MagicFactory(),同理,火星世界 就改成火星一簇 寫個MarsFactory 去實現裡面的火星武器,食物,機器

注意:這個工廠裡用的都是繼承,不是介面的實現,因為工廠裡的產生的食品一般是現實中存在的,但是它不是具體的某個食物,所以用抽象類比較合適,而介面更加側重於這個東西的屬性,moveable表示它這個東西可以動,comparable表示這個東西可以比較,所以從語義上用抽象類更加合適,形容詞用介面,名詞用抽象類

比較 工廠方法 和抽象工廠
工廠方法:在產品擴充套件時,比較方便
有Car 有Food 有AK47 以後比如說 還有帽子等等 非常方便

普通工廠

抽象工廠:然後 在產品簇上擴充套件比較方便 但是在產品上擴充套件不好擴充套件

抽象工廠

所以這個是兩個維度上的擴充套件,1個是產品一簇維度上 偏於擴充套件; 另一個是產品單一維度上 好擴充套件 都有自己的侷限性

總結一下:
簡單工廠vs靜態工廠vs工廠方法vs抽象工廠
簡單工廠:我們隨便1個方法 只要createCar什麼東西 返回的是1個物件 那麼它就是簡單工廠
靜態工廠:靜態的方法Static產生 比如單例的getInstance 就是1個靜態工廠
工廠方法FactoryMethod:產品維度上擴充套件 很方便
抽象工廠:產品一簇進行擴充套件

我們經常可以用抽象工廠來完成一鍵風格替換,比如1個人物,我可以換它的聲音,面板,動作等