设计模式系列【Java】一:工厂模式(简单工厂、工厂方法模式、抽象工厂模式)

设计模式系列一:工厂模式(简单工厂、工厂方法模式、抽象工厂模式)

本文是设计模式系列第一篇,主要介绍工厂模式,包括:简单工厂、工厂方法模式、抽象工厂模式,想更深入的学习可以参考:Head First 设计模式(中文版)。

动动发财小手,关注 + 点赞 + 收藏不迷路。

一. 简单工厂

1. 定义

简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。有些开发人员的确是把这个编程习惯误认为是 “工厂模式” (Factory Pattern)。

下面通过比萨工厂来举例,用比萨工厂来生产比萨。

public abstract class Pizza {

    private String PIZZA_PREFIX = "common pizza ";

    /**
     * 准备
     */
    public void prepare() {
        System.out.println(PIZZA_PREFIX + "prepare");
    }

    /**
     * 烘烤
     */
    public void bake() {
        System.out.println(PIZZA_PREFIX + "bake");
    }

    /**
     * 切
     */
    public void cut() {
        System.out.println(PIZZA_PREFIX + "cut");
    }

    /**
     * 装箱
     */
    public void box() {
        System.out.println(PIZZA_PREFIX + "box");
    }

}

/**
 * 芝士比萨
 *
 */
public class CheesePizza extends Pizza {

    private String PIZZA_PREFIX = "cheese pizza ";

    /**
     * 准备
     */
    public void prepare() {
        System.out.println(PIZZA_PREFIX + "prepare");
    }

    /**
     * 烘烤
     */
    public void bake() {
        System.out.println(PIZZA_PREFIX + "bake");
    }

    /**
     * 切
     */
    public void cut() {
        System.out.println(PIZZA_PREFIX + "cut");
    }

    /**
     * 装箱
     */
    public void box() {
        System.out.println(PIZZA_PREFIX + "box");
    }
}

public class SimplePizzaFactory {

    public Pizza createPizza(String type) {
        Pizza pizza = null;

        switch (type) {
            // 芝士比萨
            case "cheese":
                pizza = new CheesePizza();
                break;
            // 意大利辣香肠比萨
            case "pepperoni":
                pizza = new PepperoniPizza();
                break;
            // 蛤蜊比萨
            case "clam":
                pizza = new ClamPizza();
                break;
            // 蔬菜披萨
            case "veggie":
                pizza = new VeggiePizza();
                break;
            default:
                break;
        }
        return pizza;
    }

}

/**
 * 披萨商店
 *
 */
public class PizzaStore {

    private SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = factory.createPizza(type);

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

}

/**
 * 披萨商店
 *
 */
public class PizzaStore {

    private SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = factory.createPizza(type);

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

}

public class SimpleFacotryDemo {

    public static void main(String[] args) {
        PizzaStore pizzaStore = new PizzaStore(new SimplePizzaFactory());
        pizzaStore.orderPizza("cheese");
    }

}


输出如下:

cheese pizza prepare
cheese pizza bake
cheese pizza cut
cheese pizza box

二. 工厂方法模式

1. 定义

定义了一个创建对象的接口,但由于子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

简单工厂中的披萨店生意太好,需要开一个分店。假设现在有两个披萨店,一个纽约披萨店,一个芝加哥披萨店,使用工厂方法模式来生产披萨。


public abstract class Pizza {

    public String name;
    // 面团
    public String dough;
    // 酱
    public String sauce;
    // 佐料
    public ArrayList toppings = new ArrayList();

    /**
     * 准备
     */
    public void prepare() {
        System.out.println("Preparing " + name);
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce...");
        System.out.println("Adding toppings...");
        for (Object topping : toppings) {
            System.out.println("  " + topping);
        }
    }

    /**
     * 烘烤
     */
    public void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

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

    /**
     * 装箱
     */
    public void box() {
        System.out.println("Place pizza in official PizzaStore 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("Grated Reggiano Cheese");
    }

}

/**
 * 芝加哥风味芝士比萨
 *
 */
public class ChicagoStyleCheesePizza extends Pizza {

    public ChicagoStyleCheesePizza() {
        name = "Chicago Style Deep Dish Cheese Pizza";
        dough = "Extra Thick Crust Dough";
        sauce = "Plum Tomato Sauce";

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

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

}

/**
 * 披萨商店
 *
 */
public abstract class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = createPizza(type);

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

        return pizza;
    }

    protected abstract Pizza createPizza(String type);

}


/**
 * 纽约披萨商店
 *
 */
public class NYPizzaPizzaStore extends PizzaStore {

    public Pizza createPizza(String item){
        switch (item){
            case "cheese":
                return new NYStyleCheesePizza();
            // 其他披萨...
            default:
                break;
        }
        return null;
    }

}

/**
 * 芝加哥披萨商店
 *
 * @Date: 2022/04/05 17:38
 */
public class ChicagoPizzaPizzaStore extends PizzaStore {
    
    public Pizza createPizza(String item){
        switch (item){
            case "cheese":
                return new ChicagoStyleCheesePizza();
            // 其他披萨...
            default:
                break;
        }
        return null;
    }

}

/**
 * @Date: 2022/04/05 17:40
 */
public class FactoryMethodDemo {

    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaPizzaStore();
        PizzaStore chicogoStore = new ChicagoPizzaPizzaStore();

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

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

}

输出如下:

Preparing NY Style Sauce and Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings...
  Grated Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Tom ordered a NY Style Sauce and Cheese Pizza

Preparing Chicago Style Deep Dish Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings...
  Shredded Mozzarella Cheese
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Jack ordered a Chicago Style Deep Dish Cheese Pizza


三. 抽象工厂模式

1. 定义

提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

工厂方法模式中,PizzaStore依赖于所有的披萨对象,不满足依赖倒置原则,因此提出抽象工厂模式,通过建造原料工厂,重做披萨。

public interface Dough {

    String getName();

}

public class ThinCrustDough implements Dough {

    public String getName() {
        return "ThinCrustDough";
    }

}

public interface Sauce {

    String getName();

}

public class MarinaraSauce implements Sauce {

    public String getName() {
        return "MarinaraSauce";
    }

}

public class PlumTomatoSauce implements Sauce{

    public String getName() {
        return "PlumTomatoSauce";
    }

}

public interface Cheese {

    String getName();

}

public class MozzarellaCheese implements Cheese {

    public String getName() {
        return "MozzarellaCheese";
    }

}

public class ReggianoCheese implements Cheese {

    public String getName() {
        return "ReggianoCheese";
    }

}

public interface PizzaIngredientFactory {

    Dough createDough();
    Sauce createSauce();
    Cheese createCheese();

}

public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
    @Override
    public Dough createDough() {
        return new ThinCrustDough();
    }

    @Override
    public Sauce createSauce() {
        return new MarinaraSauce();
    }

    @Override
    public Cheese createCheese() {
        return new ReggianoCheese();
    }

}

public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory{

    @Override
    public Dough createDough() {
        return new ThinCrustDough();
    }

    @Override
    public Sauce createSauce() {
        return new PlumTomatoSauce();
    }

    @Override
    public Cheese createCheese() {
        return new MozzarellaCheese();
    }

}

public abstract class Pizza {

    public String name;
    // 面团
    public Dough dough;
    // 酱
    public Sauce sauce;
    // 芝士
    public Cheese cheese;

    /**
     * 准备
     */
    public abstract void prepare();

    /**
     * 烘烤
     */
    public void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

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

    /**
     * 装箱
     */
    public void box() {
        System.out.println("Place pizza in official PizzaStore box");
    }

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

    public String getName() {
        return name;
    }

}

public class CheesePizza extends Pizza {

    PizzaIngredientFactory ingredientFactory;

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

    public void prepare() {
        System.out.println("Preparing " + name);
        dough = ingredientFactory.createDough();
        System.out.println("dough: " + dough.getName());
        sauce = ingredientFactory.createSauce();
        System.out.println("sauce: " + sauce.getName());
        cheese = ingredientFactory.createCheese();
        System.out.println("cheese: " + cheese.getName());
    }

}

public abstract class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = createPizza(type);

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

        return pizza;
    }

    protected abstract Pizza createPizza(String type);

}

public class NYPizzaPizzaStore extends PizzaStore {

    public Pizza createPizza(String item){
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

        switch (item){
            case "cheese":
                pizza = new CheesePizza(ingredientFactory);
                pizza.setName("New York Style Clam Pizza");
                break;
            // 其他披萨...
            default:
                break;
        }
        return pizza;
    }

}

public class ChicagoPizzaPizzaStore extends PizzaStore {

    public Pizza createPizza(String item) {
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();

        switch (item) {
            case "cheese":
                pizza = new CheesePizza(ingredientFactory);
                pizza.setName("Chicago Style Cheese Pizza");
                break;
            // 其他披萨...
            default:
                break;
        }
        return pizza;
    }

}

/**
 * @Date: 2022/04/05 20:53
 */
public class AbstractFactoryDemo {

    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaPizzaStore();
        PizzaStore chicogoStore = new ChicagoPizzaPizzaStore();

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

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

}

输出如下:

Preparing New York Style Clam Pizza
dough: ThinCrustDough
sauce: MarinaraSauce
cheese: ReggianoCheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Tom ordered a New York Style Clam Pizza

Preparing Chicago Style Cheese Pizza
dough: ThinCrustDough
sauce: PlumTomatoSauce
cheese: MozzarellaCheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Jack ordered a Chicago Style Cheese Pizza

引用:
1.《Head First 设计模式(中文版)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值