1. 程式人生 > >Headfirst java設計模式-工廠模式

Headfirst java設計模式-工廠模式

抽象工廠模式:提供一個介面,用於建立相關或依賴物件的家族,而不許要明確指定具體類。
工廠方法模式:定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法讓類的例項化推遲到子類。

程式碼實現:
1.簡單工廠(嚴格上非工廠模式)
(1)建立一個pizza抽象類

public abstract class Pizza {

    public abstract void prepare();

    public abstract void bake();

    public abstract void cut();

    public abstract void
box(); }

(2)繼承pizza抽象類,實現兩個類

public class ClamPizza extends Pizza{

    @Override
    public void prepare() {
        // TODO Auto-generated method stub
        System.out.println("prepare clam pizza.");
    }

    @Override
    public void bake() {
        // TODO Auto-generated method stub
        System.out.println("bake clam pizza."
); } @Override public void cut() { // TODO Auto-generated method stub System.out.println("cut clam pizza."); } @Override public void box() { // TODO Auto-generated method stub System.out.println("box clam pizza."); } } public class CheesePizza
extends Pizza{
@Override public void prepare() { // TODO Auto-generated method stub System.out.println("prepare cheese pizza."); } @Override public void bake() { // TODO Auto-generated method stub System.out.println("bake cheese pizza."); } @Override public void cut() { // TODO Auto-generated method stub System.out.println("cut cheese pizza."); } @Override public void box() { // TODO Auto-generated method stub System.out.println("box cheese pizza."); } }

(3)簡單工廠實現

/**
 * 簡單工廠模式(一般來說不算工廠模式)
 *
 */
public class SimplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;

        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        }

        return pizza;
    }
}

2.工廠方法模式
(1)建立一個PizzaStore抽象類
具體的createPizza操作由子類去實現。

public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }

    abstract Pizza createPizza(String type);
}

(2)建立pizza類,並實現兩種不同風味的Pizza

import java.util.ArrayList;

public class Pizza {
    String name;
    String dough;
    String sauce;

    ArrayList toppings = new ArrayList();

    void prepare() {
        System.out.println("Preparing " + name);
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce...");
        for(int i = 0; i < toppings.size(); i++) {
            System.out.println(" " + toppings.get(i));
        }
    }

    void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

    void cut() {
        System.out.println("Cutting the pizza into the diagonal slices.");
    }

    void box() {
        System.out.println("Place the pizza in the offical pizza box.");
    }

    public String getName() {
        return name;
    }

}

public class NYStyleCheesePizza extends Pizza {
    public NYStyleCheesePizza() {
        name = "NY style sauce and cheese pizza";
        dough = "Thin crust dough";
        sauce = "Marinara sauce";

        toppings.add("Greated Reggiano pizza");
    }
}

public class ChicagoStyleCheesePizza extends Pizza {

    public ChicagoStyleCheesePizza() {
        name = "Chicago style cheese pizza.";
        dough = "Extra trick crust dough";
        sauce = "plum tomato sauce";

        toppings.add("Shredded Mozzarella Cheese.");
    }

    void cut() {
        System.out.println("Cutting the pizza into square slices.");
    }
}

(3)繼承PizzaStore類,實現兩種不同的PizzaStore

public class ChicagoStylePizzaStore extends PizzaStore {

    @Override
    Pizza createPizza(String type) {
        // TODO Auto-generated method stub
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new ChicagoStyleCheesePizza();
        }

        return pizza;
    }



}

public class NYStylePizzaStore extends PizzaStore {

    @Override
    Pizza createPizza(String type) {
        // TODO Auto-generated method stub
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new NYStyleCheesePizza();
        }

        return pizza;
    }

}

(4)測試程式碼

public class PizzaTestDriver {
    public static void main(String[] args) {
        PizzaStore nyStore = new NYStylePizzaStore();
        PizzaStore chicagoStore = new ChicagoStylePizzaStore();

        Pizza pizza = nyStore.orderPizza("cheese");
        System.out.println("Ethan ordered a " + pizza.getName() + "\n");

        pizza = chicagoStore.orderPizza("cheese");
        System.out.println("Joel ordered a " + pizza.getName() + "\n");
    }
}

測試結果:
Preparing NY style sauce and cheese pizza
Tossing dough…
Adding sauce…
Greated Reggiano pizza
Bake for 25 minutes at 350
Cutting the pizza into the diagonal slices.
Place the pizza in the offical pizza box.
Ethan ordered a NY style sauce and cheese pizza

Preparing Chicago style cheese pizza.
Tossing dough…
Adding sauce…
Shredded Mozzarella Cheese.
Bake for 25 minutes at 350
Cutting the pizza into square slices.
Place the pizza in the offical pizza box.
Joel ordered a Chicago style cheese pizza.

3.抽象工廠模式
(1)建立一個原料工廠介面和抽象pizza類

public interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Cheese createCheese();
    public Clams createClams();
}

public abstract class Pizza {
    String name;
    Dough dough;
    Sauce sauce;
    Veggies[] veggies;
    Pepperoni pepperoni;
    Cheese cheese;
    Clams clam;

    public abstract void prepare();

    void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

    void cut() {
        System.out.println("Cut the pizza into diagonal slices");
    }

    void box() {
        System.out.println("Place the pizza into offical PizzaStore box");
    }

    void setName(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    public String toString() {
        return name + ((dough != null)?" Dough:"+dough.getClass().getName():"")
                + ((sauce != null)?" Sauce:" + sauce.getClass().getName():"")
                + ((cheese != null)?" Cheese:" + cheese.getClass().getName():"")
                + ((clam != null)?" Clam:" + clam.getClass().getName():"");
    }

}

(2)繼承PizzaIngredientFactory介面實現具體的原料工廠,繼承抽象pizza類實現具體的pizza類

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {

    @Override
    public Dough createDough() {
        // TODO Auto-generated method stub
        return new ThinCrustDough();
    }

    @Override
    public Sauce createSauce() {
        // TODO Auto-generated method stub
        return new MarinaraSauce();
    }

    @Override
    public Veggies[] createVeggies() {
        // TODO Auto-generated method stub
        Veggies[] veggies = {new Garlic(), new Onion(), new Mushroom(), new RedPepper()};
        return veggies;
    }

    @Override
    public Pepperoni createPepperoni() {
        // TODO Auto-generated method stub
        return new SlicedPepperoni();
    }

    @Override
    public Clams createClams() {
        // TODO Auto-generated method stub
        return new FreshClams();
    }

    @Override
    public Cheese createCheese() {
        // TODO Auto-generated method stub
        return new ReggianoCheese();
    }

}

public class CheesePizza extends Pizza{
    PizzaIngredientFactory factory;

    public CheesePizza(PizzaIngredientFactory factory) {
        this.factory = factory;
    }

    @Override
    public void prepare() {
        // TODO Auto-generated method stub
        System.out.println("Preparing " + name);
        dough = factory.createDough();
        sauce = factory.createSauce();
        cheese = factory.createCheese();
    }
}

public class ClamPizza extends Pizza{
    PizzaIngredientFactory factory;

    public ClamPizza(PizzaIngredientFactory factory) {
        this.factory = factory;
    }

    @Override
    public void prepare() {
        // TODO Auto-generated method stub
        System.out.println("Prepare " + name);
        dough = factory.createDough();
        sauce = factory.createSauce();
        cheese = factory.createCheese();
        clam = factory.createClams();
    }
}

public class ReggianoCheese implements Cheese{

}

(3)建立相應的Pizza原料介面並實現相應的原料類

public interface Cheese {

}

public interface Clams {

}

public interface Dough {

}

public interface Sauce {

}

public interface Veggies {

}

public interface Pepperoni {

}

public class FreshClams implements Clams{

}

public class Garlic implements Veggies{

}

public class MarinaraSauce implements Sauce{

}

public class Mushroom implements Veggies{

}

public class Onion implements Veggies{

}

public class RedPepper implements Veggies{

}

public class SlicedPepperoni implements Pepperoni{

}

public class ThinCrustDough implements Dough {

}

(4)建立一個pizzaStore,並實現具體的NYPizzaStore

public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }

    abstract Pizza createPizza(String type);
}

public class NYPizzaStore extends PizzaStore{

    @Override
    Pizza createPizza(String type) {
        // TODO Auto-generated method stub
        Pizza pizza = null;
        PizzaIngredientFactory factory = new NYPizzaIngredientFactory();

        if (type.equals("cheese")) {
            pizza = new CheesePizza(factory);
            pizza.setName("New York style cheese pizza");
        } else if (type.equals("clam")) {
            pizza = new ClamPizza(factory);
            pizza.setName("New York style clam pizza");
        }

        return pizza;
    }

}

(5)測試程式碼

public class PizzaTestDriver {
    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaStore();
        //PizzaStore chicagoStore = new ChicagoStylePizzaStore();

        Pizza pizza = nyStore.orderPizza("cheese");
        System.out.println("Ethan ordered a " + pizza.toString() + "\n");

        pizza = nyStore.orderPizza("clam");
        System.out.println("Joel ordered a " + pizza.toString() + "\n");
    }
}