1. 程式人生 > >Java中的工廠模式

Java中的工廠模式

ride 依賴倒轉原則 spa 接口隔離 負責 展開 具體實現 sta 開放

設計模式遵循原則

  • 開閉原則:對擴展開放,對修改關閉
  • 裏氏代換原則:只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被覆用。而衍生類也能夠在基類的基礎上增加新的行為
  • 依賴倒轉原則:開閉原則的基礎,對接口編程,依賴於抽象而不依賴於具體
  • 接口隔離原則:使用多個隔離的接口來降低耦合度
  • 迪米特法原則:最少知道原則。一個實體應該盡量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立
  • 合成復用原則:盡量使用合成/聚合的方式,而不是使用繼承。繼承實際上破環了類的封裝性,超類的方法可能會被子類修改。

工廠模式

簡單工廠模式

技術分享圖片

簡單工廠模式當中,一個工廠負責生產所有的產品。如上圖所示,無論是戴爾鼠標還是惠普鼠標,都在一家鼠標工廠中生產。工廠通過用戶的需要生產不同的鼠標,即用戶傳入生產鼠標的參數,工廠返回生產出的鼠標實體。

具體實現如下:

//鼠標基類
class Mouse{
    public void sayHi(){};
}
//鼠標擴展類
class DellMouse extends Mouse{
    @Override
    public void sayHi() {
        System.out.println("產品:戴爾鼠標");
    }
}
class HpMouse extends Mouse{
    @Override
    public void sayHi() {
        System.out.println("產品:惠普鼠標");
    }
}
//鼠標工廠
class MouseFactory{ //生產鼠標的方法,所有的鼠標都通過該方法生成 public static Mouse createMouse(int i) { switch (i) { case 0: return new DellMouse(); case 1: return new HpMouse(); default: return null; } } } public class NormFactory { public static void main(String[] args) { Mouse hpm
= MouseFactory.createMouse(1); Mouse dellm = MouseFactory.createMouse(0); hpm.sayHi(); dellm.sayHi(); } }

打印結果如下:

產品:惠普鼠標
產品:戴爾鼠標

上述模式下,所有的鼠標都在同一個MouseFactory工廠下生產,有一個統一的create靜態方法。在使用工廠時,不需要對工廠進行實例化,只需要調用該靜態方法便可得到相應的產品。

但如果用戶需要添加新一類的產品,例如有一項華碩鼠標,工廠要生產該產品則需要改create函數,這有悖於設計原則的開閉原則。

工廠模式

技術分享圖片

在該模式下,不同品牌的產品交由不同的工廠來生產,有一個統一的工廠接口,生產該產品的工廠都要實現該接口。

生產哪種產品不再由參數決定,而是在創建工廠時讓工廠來決定,例如惠普的工廠只會生產惠普的鼠標,而戴爾的工廠只會生產戴爾的鼠標。

具體實現如下:

class Mouse{
    public void sayHi(){};
}

class DellMouse extends Mouse{
    @Override
    public void sayHi() {
        System.out.println("產品:戴爾鼠標");
    }
}
class HpMouse extends Mouse{
    @Override
    public void sayHi() {
        System.out.println("產品:惠普鼠標");
    }
}
//生產工廠接口
interface MouseFactory{
    public Mouse createMouse();
}
//不同的鼠標交由不同的工廠生產
class HpMouseFactory implements MouseFactory{
    @Override
    public Mouse createMouse() {
        return new HpMouse();
    }
}
class DellMouseFactory implements MouseFactory{
    @Override
    public Mouse createMouse() {
        return new DellMouse();
    }
}
public class NormFactory {
    public static void main(String[] args) {
        MouseFactory hpFact = new HpMouseFactory();
        MouseFactory dellFact = new DellMouseFactory();
        Mouse hpm = hpFact.createMouse();
        Mouse dellm = dellFact.createMouse();
        hpm.sayHi();
        dellm.sayHi();
    }
}

打印結果如下:

產品:惠普鼠標
產品:戴爾鼠標

該模式下代碼的可擴展性大大提高,當需要添加一種商品時,只需要添加生產該商品的工廠,並讓其實現生產工廠接口即可。

但在該模式下,商品的生產變得更為復雜,我們要得到一件商品,必須先得到一座生產該商品的工廠,再調用該工廠的生產方法才能得到該商品。

抽象工廠模式

技術分享圖片

該模式下的工廠生產的產品不唯一,同一品牌的工廠有著各種不同的產品,相當於是工廠模式的一個加強版。

具體實現如下:

class Mouse{
    public void sayHi(){};
}

class DellMouse extends Mouse {
    @Override
    public void sayHi() {
        System.out.println("產品:戴爾鼠標");
    }
}
class HpMouse extends Mouse {
    @Override
    public void sayHi() {
        System.out.println("產品:惠普鼠標");
    }
}

class KeyBoard {
    public void kick(){};
}
class HpKeyBoard extends KeyBoard {
    @Override
    public void kick() {
        System.out.println("產品:惠普鍵盤");
    }
}
class DellKeyBoard extends KeyBoard {
    @Override
    public void kick() {
        System.out.println("產品:戴爾鍵盤");
    }
}
//總的工廠接口
interface PcFactory {
    public Mouse createMouse() ;
    public KeyBoard createKeyBoard() ;
}
class HpFactory implements PcFactory {
    @Override
    public Mouse createMouse() {
        return new HpMouse();
    }

    @Override
    public KeyBoard createKeyBoard() {
        return new HpKeyBoard();
    }
}
class DellFactory implements PcFactory {
    @Override
    public Mouse createMouse() {
        return new DellMouse();
    }
    @Override
    public KeyBoard createKeyBoard() {
        return new DellKeyBoard();
    }
}

//當需要增加一個華碩工廠時:
class AsusMouse extends Mouse {
    @Override
    public void sayHi() {
        System.out.println("產品:華碩鼠標");
    }
}
class AsusKeyBoard extends KeyBoard {
    @Override
    public void kick() {
        System.out.println("產品:華碩鍵盤");
    }
}
class AsusFactory implements PcFactory {
    @Override
    public Mouse createMouse() {
        return new AsusMouse();
    }
    @Override
    public KeyBoard createKeyBoard() {
        return new AsusKeyBoard();
    }
}

public class NormFactory {
    public static void main(String[] args) {
        PcFactory hpFact = new HpFactory();
        Mouse hpm = hpFact.createMouse();
        KeyBoard hpkbd = hpFact.createKeyBoard();
        
        PcFactory dellFact = new DellFactory();
        Mouse dellm = dellFact.createMouse();
        KeyBoard dellkbd = dellFact.createKeyBoard();
        
        hpm.sayHi();
        dellm.sayHi();
        
        hpkbd.kick();
        dellkbd.kick();
    }
}

打印結果如下:

產品:惠普鼠標
產品:戴爾鼠標
產品:惠普鍵盤
產品:戴爾鍵盤

但該模式如果要添加產品時,需要修改PcFactory、DellFactory、HpFactory等所有實現了PcFactroy接口的工廠類,這是十分不好的。

Java中的工廠模式