《Head First 设计模式》:抽象工厂模式

正文

一、定义

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

要点:

  • 抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产品的具体产品是什么。这样一来,客户就从具体的产品中被解耦。
  • 抽象工厂的任务是定义一个负责创建一组产品的接口。这个接口内的每个方法都负责创建一个产品,同时利用实现抽象工厂的子类来提供具体的做法。
  • 抽象工厂的方法经常以工厂方法的方式实现。

二、实现步骤

1、创建产品抽象类

(1)产品A抽象类

/**
 * 产品A抽象类
 */
public abstract class ProductA {
    
    String name;
    
    public String getName() {
        return name;
    }
}

(2)产品B抽象类

/**
 * 产品B抽象类
 */
public abstract class ProductB {
    
    String name;
    
    public String getName() {
        return name;
    }
}

2、创建具体的产品,并继承产品抽象类

(1)产品A1

/**
 * 产品A1
 */
public class ConcreteProductA1 extends ProductA {
    
    public ConcreteProductA1() {
        name = "ConcreteProductA1";
    }
}

(2)产品A2

/**
 * 产品A2
 */
public class ConcreteProductA2 extends ProductA {
    
    public ConcreteProductA2() {
        name = "ConcreteProductA2";
    }
}

(3)产品B1

/**
 * 产品B1
 */
public class ConcreteProductB1 extends ProductB {
    
    public ConcreteProductB1() {
        name = "ConcreteProductB1";
    }
}

(4)产品B2

/**
 * 产品B2
 */
public class ConcreteProductB2 extends ProductB {
    
    public ConcreteProductB2() {
        name = "ConcreteProductB2";
    }
}

3、创建工厂接口,并定义创建产品的方法

也可以使用工厂抽象类,然后在创建具体工厂时继承工厂抽象类。

/**
 * 抽象工厂接口
 */
public interface AbstractFactory {
    
    /**
     * 创建产品A
     */
    public ProductA createProductA();
    
    /**
     * 创建产品B
     */
    public ProductB createProductB();
}

4、创建具体的工厂,并实现工厂接口

(1)工厂1

/**
 * 工厂1
 */
public class ConcreteFactory1 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

(2)工厂2

/**
 * 工厂2
 */
public class ConcreteFactory2 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

5、使用工厂创建产品

public class Test {
    
    public static void main(String[] args) {
        // 工厂1
        AbstractFactory factory1 = new ConcreteFactory1();
        // 工厂2
        AbstractFactory factory2 = new ConcreteFactory2();
        
        // 工厂1创建产品
        ProductA productA = factory1.createProductA();
        System.out.println("工厂1创建产品A:" + productA.getName());
        ProductB productB = factory1.createProductB();
        System.out.println("工厂1创建产品B:" + productB.getName());
        // 工厂2创建产品
        productA = factory2.createProductA();
        System.out.println("工厂2创建产品A:" + productA.getName());
        productB = factory2.createProductB();
        System.out.println("工厂2创建产品B:" + productB.getName());
    }
}

三、举个栗子

1、背景

假设你有一个披萨店,并且拥有许多加盟店。为了确保每家加盟店都能使用高质量的原料,你打算建造生产原料的工厂,并将原料运送到各家加盟店。

由于加盟店坐落在不同的区域,每个区域的原料是不一样的。因此,必须能够针对不同的区域提供相应的原料。

2、实现

为每个区域建造一个工厂,每个工厂负责创建相应区域的原料。

(1)创建所有原料抽象类

/**
 * 面团抽象类
 */
public abstract class Dough {
    
    String name;
    
    public String getName() {
        return name;
    }
}
/**
 * 酱料抽象类
 */
public abstract class Sauce {
    
    String name;
    
    public String getName() {
        return name;
    }
}
/**
 * 芝士抽象类
 */
public abstract class Cheese {
    
    String name;
    
    public String getName() {
        return name;
    }
}

(2)创建不同区域的所有原料

/**
 * 薄皮面团
 */
public class ThinCrustDough extends Dough {
    
    public ThinCrustDough() {
        name = "Thin Crust Dough";
    }
}
/**
 * 厚皮面团
 */
public class ThickCrustDough extends Dough {

    public ThickCrustDough() {
        name = "Thick Crust Dough";
    }
}
/**
 * 大蒜番茄酱
 */
public class MarinaraSauce extends Sauce {

    public MarinaraSauce() {
        name = "Marinara Sauce";
    }
}
/**
 * 番茄酱
 */
public class PlumTomatoSauce extends Sauce {

    public PlumTomatoSauce() {
        name = "Plum Tomato Sauce";
    }
}
/**
 * 帕马森雷加诺干酪
 */
public class ReggianoCheese extends Cheese{
    
    public ReggianoCheese() {
        name = "Reggiano Cheese";
    }
}
/**
 * 马苏里拉奶酪
 */
public class MozzarellaCheese extends Cheese{

    public MozzarellaCheese() {
        name = "Mozzarella Cheese";
    }
}

(3)创建原料工厂接口

/**
 * 披萨原料工厂接口
 */
public interface PizzaIngredientFactory {
    
    /**
     * 创建面团
     */
    public Dough createDough();
    
    /**
     * 创建酱料
     */
    public Sauce createSauce();
    
    /**
     * 创建芝士
     */
    public Cheese createCheese();
    
    // 创建其他原料
}

(4)创建不同区域的原料工厂

/**
 * 纽约原料工厂
 */
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 ThickCrustDough();
    }

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

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

(5)使用不同区域的原料工厂创建原料

public class Test {
    
    public static void main(String[] args) {
        // 纽约原料工厂
        PizzaIngredientFactory nyFactory = new NYPizzaIngredientFactory();
        // 芝加哥原料工厂
        PizzaIngredientFactory chicagoFactory = new ChicagoPizzaIngredientFactory();
        
        // 使用纽约原料工厂创建原料
        Dough dough = nyFactory.createDough();
        Sauce sauce = nyFactory.createSauce();
        Cheese cheese = nyFactory.createCheese();
        System.out.println("New York Pizza Ingredient Factory Create:");
        System.out.println(" " + dough.getName());
        System.out.println(" " + sauce.getName());
        System.out.println(" " + cheese.getName() + "\n");
        // 使用芝加哥原料工厂创建原料
        dough = chicagoFactory.createDough();
        sauce = chicagoFactory.createSauce();
        cheese = chicagoFactory.createCheese();
        System.out.println("Chicago Pizza Ingredient Factory Create:");
        System.out.println(" " + dough.getName());
        System.out.println(" " + sauce.getName());
        System.out.println(" " + cheese.getName());
    }
}
posted @ 2020-07-26 21:33  惊却一目  阅读(99)  评论(0编辑  收藏