设计模式—工厂方法模式

工厂方法模式

文章目录

    • 工厂方法模式
      • 工厂方法模式是什么
      • 理解工厂方法模式
      • 代码实例
      • 运行截图
      • 工厂方法的优点
      • 工厂方法的不足


工厂方法模式是什么

  • 工厂方法模式属于创建型模式,也叫抽象构造模式, 工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

理解工厂方法模式

  • 这种模式是在原先的层级上多加了一层 实现的效果就是,不由原先的工厂类来实例对象工厂父类来定义创建产品的公共接口, 而各工厂子类对象通过集成来实现这个创建接口, 在这个实现里面去完成究竟应该实例化哪一个具体产品,这样就可以在不影响原先种类的情况下引入新的产品。

代码实例

  • 在这个代码实例中,我们将模拟订购pizza的场景,这次我们加入风味元素,如有北京风味的芝士披萨、伦敦风味的牛肉披萨等。
  1. 我们先定义各种产品类,他们有一个抽象父类,如Pizza类,具体产品类都继承自他
  2. 然后创建一个抽象工厂类,在这个抽象工厂种定义一个抽象的创建方法,后续让子类去实现
  3. 创建多种具体实现创建接口的实现类,在实现类中来决定具体创建哪一个pizza类
  4. 创建订购类,在这个类中实现各种方法的调用

/**
 * 这种模式是在原先的层级上多加了一层
 * 实现的效果就是,不由原先的工厂类来实例对象
 * 工厂父类来定义创建产品的公共接口,
 * 而各工厂子类对象通过集成来实现这个创建接口,
 * 在这个实现里面去完成究竟应该实例化哪一个具体产品
 * 这样就可以在不影响原先种类的情况下引入新的产品
 */

import java.util.Scanner;

public class 工厂方法 {
    public static void main(String[] args) {
        new Order().buy();
    }
}

//定义一个购买订单
class Order {
    public void buy() {
        Scanner in = new Scanner(System.in);
        while (true) {
            System.out.print("您需要什么地方的pizza:");
            String address = in.nextLine();
            PizzaFactory factory = null;
            if ("bj".equals(address)) {
                factory = new BjPizzaFactory();
            } else if ("ld".equals(address)) {
                factory = new LDPizzaFactory();
            }else {
                System.out.println("没有这个地方的口味哦");
                continue;
            }
            System.out.print("您需要什么口味的pizza:");
            String type = in.nextLine();

            Pizza pizza = factory.createPizza(type);
            System.out.println("订单需要为:" + pizza.pizzaName + "  " + pizza);
            if (pizza != null) {
                pizza.material();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }
        }
    }
}

//定义一个pizza创建工厂类
abstract class PizzaFactory {
    abstract public Pizza createPizza(String pizzaType);
}

class BjPizzaFactory extends PizzaFactory {

    @Override
    public Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new BjCheesePizza("芝士");
        } else if (type.equals("beef")) {
            return new BjBeefPizza("牛肉");
        } else {
            System.out.println("没有此类型的pizza");
            return null;
        }
    }
}

class LDPizzaFactory extends PizzaFactory {

    @Override
    public Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new LDCheesePizza("芝士");
        } else if (type.equals("beef")) {
            return new LDBeefPizza("牛肉");
        } else {
            System.out.println("没有此类型的pizza");
            return null;
        }
    }
}

abstract class Pizza {
    String pizzaName;

    Pizza(String pizzaName) {
        this.pizzaName = pizzaName + "披萨";
    }

    //准备材料
    abstract public void material();

    void bake() {
        System.out.println("正在烤 " + this.pizzaName);
    }

    void cut() {
        System.out.println("正在切 " + this.pizzaName);
    }

    void box() {
        System.out.println("正在打包 " + this.pizzaName);
    }
}

//利用多个披萨类来继承
class BjCheesePizza extends Pizza {


    BjCheesePizza(String pizzaName) {
        super(pizzaName);
    }

    @Override
    public void material() {
        System.out.println("正在准备北京芝士披萨的材料");
    }
}

class BjBeefPizza extends Pizza {

    BjBeefPizza(String pizzaName) {
        super(pizzaName);
    }

    @Override
    public void material() {
        System.out.println("正在准备北京牛肉披萨的材料");
    }
}

class LDCheesePizza extends Pizza {

    LDCheesePizza(String pizzaName) {
        super(pizzaName);
    }

    @Override
    public void material() {
        System.out.println("正在准备伦敦芝士披萨的材料");
    }
}

class LDBeefPizza extends Pizza {

    LDBeefPizza(String pizzaName) {
        super(pizzaName);
    }

    @Override
    public void material() {
        System.out.println("正在准备伦敦牛肉披萨的材料");
    }
}

运行截图

设计模式—工厂方法模式_第1张图片
设计模式—工厂方法模式_第2张图片

工厂方法的优点

  1. 不关心创建细节: 用户只需要关心产品所对应的工厂,不需要关心它内部是如何创建
  2. 符合开闭原则: 加入新的产品,只需要增加新的工厂类就可以,符合开闭原则,提高了可扩展性

工厂方法的不足

  1. 增加了代码的复杂性: 因为需要增加具体工厂类,所以类的个数容易过多,增加了系统的复杂度(除了编写新的产品类之外,还要编写该产品类的对应工厂类)。
  2. 增加难度: 增加了系统的抽象性和理解难度(工厂方法本身利用了抽象,该模式中会引入抽象层,如果需要动态创建产品类,还需要引入反射技术)。

设计模式的使用 , 要根据实际的业务场景 , 模型综合平衡考量 , 不能过分遵守设计原则 和 设计模式

你可能感兴趣的:(设计模式,设计模式,工厂方法模式,java)