zoukankan      html  css  js  c++  java
  • 《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() + "
    ");
            // 使用芝加哥原料工厂创建原料
            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());
        }
    }
    
  • 相关阅读:
    蓝桥杯 十六进制转八进制
    蓝桥杯 字母图形
    2017.12.13T19_B2_5mianshiti
    2017.11.21T19_B2_6.2讲义
    2017.12.13T19_B2_6zuoye
    2017.12.1T19_B2_5zuoye
    2017.12.1T19_B2_4zuoye
    2017.12.1T19_B2_4——2
    2017.12.1T19_B2_4.3kehouzuoye
    2017.12.1T19_B2_4.2
  • 原文地址:https://www.cnblogs.com/jingqueyimu/p/13382157.html
Copyright © 2011-2022 走看看