1. 程式人生 > >設計模式真香筆記-工廠模式

設計模式真香筆記-工廠模式

工廠模式分類

  • 簡單工廠
  • 工廠方法模式
  • 抽象工廠模式

工廠模式的作用

工廠模式:是為了將物件的建立和呼叫者分開,實現解耦,也就是將繁瑣的物件的建立由工廠來實現。

簡單工廠(並不是設計模式,而是一種習慣)

簡單工廠也叫靜態工廠,通過簡單工廠類的靜態方法傳入不同的引數來返回不同的所需要的物件。
缺點:

  1. 雖然工廠不需要建立例項來呼叫方法,但是不同通過繼承來改變建立方法的行為。
  2. 新增加的物件 需要修改工廠類的程式碼來實現。
    程式碼實現
  • 披薩的抽象類
public abstract class Pizza
{ /** * 看吃的什麼披薩 */ protected abstract void eat(); }
  • 披薩的實現類
public class BaoleziPizza extends Pizza {

    @Override
    public void eat() {
        System.out.println("保樂茲披薩有點難吃呀!");
    }
}
  • 披薩的實現類
public class HualaishiPizza extends Pizza {

    @Override
    public
void eat() { System.out.println("華萊士披薩還行吧!"); } }
  • 簡單工廠類
public class SimplePizzaFactory {
    public static Pizza createPizza(String type){
        Pizza pizza=null;
        if (type.equals("baolezi")) {
            pizza = new BaoleziPizza();
        }else if(type.equals("hualaishi"
)){ pizza = new HualaishiPizza(); }else { return null; } return pizza; } }
  • 簡單工廠的測試類
public class SimplePizzaTest {
    public static void main(String[] args) {
        Pizza pizza = SimplePizzaFactory.createPizza("baolezi");
        pizza.eat();
        pizza = SimplePizzaFactory.createPizza("hualaishi");
        pizza.eat();
    }


}

在這裡插入圖片描述

工廠方法模式

工廠方法模式:定義一個建立物件的藉口,由子類決定要例項化哪一個類,工廠方法把例項化推遲到子類。
優缺點:工廠方法模式更加符合開閉原則,但是每次擴充套件會增加新的類
設計原則
依賴倒轉原則:要依賴抽象,不要依賴具體類。
依賴倒轉原則的指導方針(儘量達到,而不是必須遵守)

  • 變數不可以持有具體類的引用 (如果使用new,就是持有具體類的引用,改用工廠來避免)
  • 不要讓派生類來自於具體類 (讓派生類來自於抽象類或者介面)
  • 不要覆蓋基類中已實現的方法(基類中的已經實現的方法,應該由所有的子類共享)
    UML類圖
    在這裡插入圖片描述
    程式碼實現
  • Pizza抽象類
public abstract class Pizaa {
    String name;

    ArrayList list=new ArrayList();
    void prepare() {
        System.out.println("---準備做:"+name+"披薩");
        for(Object adds:list){
            System.out.println("---新增"+adds.toString());
        }
    }
    void bake() {
        System.out.println("---烤20分鐘");
    }
    void cut() {
        System.out.println("---披薩切塊");
    }

    void box() {
        System.out.println("---打包裝盒");
    }

    public String getName() {
        return name;
    }
}
  • 具體Pziaa
public class BaoleziMalaPizza extends  Pizaa {
    public BaoleziMalaPizza(){
        name = "BaoleziMalaPizza";
        list.add("Bmala醬");
    }

}
  • 具體pizza
public class BaoleziZhishiPizza extends  Pizaa {
    public BaoleziZhishiPizza(){
        name = "BaoleziZhishiPizza";
        list.add("Bzhishi醬");
    }

}
  • 具體pizza
public class HualaishiMalaPizza extends  Pizaa {
    public HualaishiMalaPizza(){
        name = "HualaishiMalaPizza";
        list.add("Hmala醬");
    }

}
  • 具體pizza
public class HualaishiZhishiPizza extends  Pizaa {
    public HualaishiZhishiPizza(){
        name = "HualaishiMalaPizza";
        list.add("Hzhishi醬");
    }

}
  • pizza工廠抽象類,有工廠方法需要子類去實現
public abstract class PizzaStore {
        public Pizaa orderPizza(String type) {
            Pizaa pizaa;
            pizaa=createPizza(type);
            pizaa.prepare();
            pizaa.bake();
            pizaa.cut();
            pizaa.box();
            return pizaa;
        }

    protected abstract Pizaa createPizza(String type);//這就是 工廠方法由子類實現
}
  • 子類工廠
public class BaoleziPizzaStore extends PizzaStore {

    @Override
    protected Pizaa createPizza(String type) {
        if (type.equals("mala")) {

            return new BaoleziMalaPizza();
        }else if(type.equals("zhishi")){
            return new BaoleziZhishiPizza();
        }else {
            return null;
        }
    }
}
  • 另一個子類工廠
public class HualaishiPizzaStore extends PizzaStore {

    @Override
    protected Pizaa createPizza(String type) {
        if (type.equals("mala")) {

            return new HualaishiMalaPizza();
        }else if(type.equals("zhishi")){
            return new HualaishiZhishiPizza();
        }else {
            return null;
        }
    }
}
  • 工廠模式測試類
public class PizzaTest {
    public static void main(String[] args) {
        PizzaStore hualaishipizza = new HualaishiPizzaStore();
        PizzaStore baoleziPizza = new BaoleziPizzaStore();
        Pizaa pizaa = hualaishipizza.orderPizza("mala");
        System.out.println("---完成"+pizaa.getName()+"的製作"+"\n");

        pizaa = baoleziPizza.orderPizza("mala");
        System.out.println("---完成"+pizaa.getName()+"的製作");
    }
}
  • 輸出結果
    在這裡插入圖片描述

抽象工廠模式

抽象工廠模式:提供一個介面,用於建立相關或依賴物件的家族,而不是需要明確指定具體類的。
優缺點:能增加產品工廠,而不能增加產品

程式碼實現:

  • 披薩產品介面及其實現
public interface Pizza {//披薩介面
    void eat();
}
class  ExpensivePizza implements  Pizza{

    @Override
    public void eat() {
        System.out.println("貴的披薩巨好吃!");
    }
}

class CheapPizza implements Pizza {
    @Override
    public void eat() {
        System.out.println("便宜的披薩");
    }
}

  • 醬料產品介面及其實現
public interface Souce {//醬料介面
        void addSouce();
}

class ExpensiveSouce implements Souce {

    @Override
    public void addSouce() {
        System.out.println("貴的醬料");
    }
}
class CheapSouce implements Souce {

    @Override
    public void addSouce() {
        System.out.println("便宜的醬料");
    }
}
  • 披薩抽象工廠
public  interface AbstractPizzaFactory {//抽象工廠
   Pizza createPizza();
   Souce createSouce();
}
  • 具體高階工廠
public class ExpensiveFactory implements  AbstractPizzaFactory {//具體工廠

    @Override
    public Pizza createPizza() {
        return new ExpensivePizza();
    }

    @Override
    public Souce createSouce() {
        return new ExpensiveSouce();
    }
}
  • 具體低階工廠
public class CheapFactory implements AbstractPizzaFactory {//具體工廠

    @Override
    public Pizza createPizza() {
        return new CheapPizza();
    }

    @Override
    public Souce createSouce() {
        return new CheapSouce();
    }
}
  • 測試類
public class AbstractPizzaTest {
    public static void main(String[] args) {
        AbstractPizzaFactory expensiveFactory = new ExpensiveFactory();
        Pizza pizza = expensiveFactory.createPizza();
        pizza.eat();
    }
}

測試結果
在這裡插入圖片描述

總結

  • 簡單工廠是一方法,可以將客戶程式解耦具體類
  • 工廠方法使用繼承把物件的建立委託給子類
  • 工廠模式減少應用程式和具體類之間的依賴促進鬆耦合
  • 依賴倒轉原則,依賴具體型別,而要儘量依賴抽象
  • 針對抽象程式設計,而不是針對具體類程式設計