Loading

5.抽象工厂模式

1.什么是抽象工厂模式?

提供一个接口,用于创建相关对象或依赖对象的家族,而不需要明确指定具体类。 通过依赖注入来降低耦合。
在这里插入图片描述

2.结合工厂模式的披萨实例来理解抽象工厂模式

2.1 具体设计

尽管上一节的工厂模式设计已经好像看着可以,但是,我们好像也能明显的发觉到对于具体的PizzaStore的编写,我们好像违反了一个原则: 不要依赖具体,要依赖抽象。

例如我们看一下NYPizzaStore,它里面好像依赖了具体的Pizza对象,现在看来它就依赖了两个,但是如果长期以这样的方式来做的话,不难发现我们会进入一个依赖噩梦。

package factoryPattern.third.store;
import factoryPattern.third.PizzaStore;
import factoryPattern.third.pizza.NYPizza1;
import factoryPattern.third.pizza.NYPizza2;
import factoryPattern.third.pizza.Pizza;

public class NYPizzaStore extends PizzaStore {
    @Override
    protected Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("NY1")){
            pizza = new NYPizza1();
        }else if(type.equals("NY2")){
            pizza = new NYPizza2();
        }
        return pizza;
    }
}

如何解决这个问题? 本届的抽象工厂模式也许会给你一些启发。

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

那么我们该如何让PizzaStore从依赖噩梦中解脱呢?员工A在原有的基础上,进行思考后,设计出下面的结构:
在这里插入图片描述

首先,他将Pizza抽象化了,并且新建立一个PizzaFactory接口用来将具体的PizzaStory和具体的Pizza实例解耦。
从图中我们可以看到,面向用户的具体的NYPizzaStore是通过依赖抽象的方式来满足需求的。

2.2 具体实现

Pizza.java

package AbstractFactoryPattern.base;
import java.util.Arrays;

public abstract class Pizza {
    public String name;
 
    public abstract void prepare();

    protected void bake(){
        System.out.println("准备烘烤 25 分钟...");
    }

    protected void cut(){
        System.out.println("烘烤完成,进行切割");
    }

    protected void box(){
        System.out.println("切割完毕,进行装盒");
    }

    public String getName() {
        return name;
    }

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

PizzaFactory.java

package AbstractFactoryPattern.base;

public interface PizzaFactory {
    Pizza createPizza(String type);
}


PizzaStore.java
package AbstractFactoryPattern.base;
public abstract class PizzaStore {

    public Pizza orderPizza(String type){
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    /**
     * 工厂方法
     * @param type 披萨类型
     * @return pizza实例
     */
    protected abstract Pizza createPizza(String type);
}

CheesePizza.java

package AbstractFactoryPattern.pizza;
import AbstractFactoryPattern.base.Pizza;

/**
 * Cheese披萨定义类
 * 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
 */
public class CheesePizza extends Pizza {

    public CheesePizza(){
    }

    @Override
    public void prepare() {
        System.out.println("Preparing "+name);
    }

    @Override
    protected void bake(){
        System.out.println("Cheese烘烤方式:。。。,,,。。。");
    }
}

ClamPizza.java

package AbstractFactoryPattern.pizza;

import AbstractFactoryPattern.base.Pizza;

public class ClamPizza extends Pizza {
    public ClamPizza(){ }

    @Override
    public void prepare() {
        System.out.println("Preparing "+name);
    }
    @Override
    protected void bake(){
        System.out.println("ClamPizza烘烤方式------");
    }
}

NYPizzaFactory.java

package AbstractFactoryPattern.factory;
import AbstractFactoryPattern.base.Pizza;
import AbstractFactoryPattern.base.PizzaFactory;
import AbstractFactoryPattern.pizza.CheesePizza;
import AbstractFactoryPattern.pizza.ClamPizza;

/**
 * Pizza工厂
 */
public class NYPizzaFactory implements PizzaFactory {
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("cheese")){
            pizza = new CheesePizza();
            pizza.setName("New York Style Cheese Pizza");
        }else if(type.equals("clam")){
            pizza = new ClamPizza();
            pizza.setName("New York Style Clam Pizza");
        }
        return pizza;
    }
}

NYPizzaStore.java

package AbstractFactoryPattern.pizzaStore;

import AbstractFactoryPattern.base.Pizza;
import AbstractFactoryPattern.base.PizzaFactory;
import AbstractFactoryPattern.base.PizzaStore;
import AbstractFactoryPattern.factory.NYPizzaFactory;


/**
 * NY披萨工厂
 */
public class NYPizzaStore extends PizzaStore {

    PizzaFactory pizzaFactory;

    public NYPizzaStore(){
        this.pizzaFactory = new NYPizzaFactory();
    }

    public NYPizzaStore(PizzaFactory pizzaFactory){
        this.pizzaFactory = pizzaFactory;
    }
    @Override
    protected Pizza createPizza(String type) {
        return pizzaFactory.createPizza(type);
    }
}

OK,构建完毕,下面进行测试一下:

package AbstractFactoryPattern;

import AbstractFactoryPattern.base.PizzaStore;
import AbstractFactoryPattern.pizzaStore.NYPizzaStore;

/**
 * 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。 这种方式依赖注入
 */
public class MainTest {
    public static void main(String[] args) {
        PizzaStore nyPizzaStore = new NYPizzaStore();
        nyPizzaStore.orderPizza("cheese");
    }
}

在这里插入图片描述
完成!! 如果你成功重现出了上面的例子并理解了这种方式,可以将它和上一节的例子进行对比。

代码仓库地址如下:
https://gitee.com/yan-jiadou/design-mode/tree/master/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/src/main/java/AbstractFactoryPattern

posted @ 2022-06-02 08:41  文牧之  阅读(19)  评论(0)    收藏  举报  来源