设计模式—工厂方法模式

工厂方法模式


工厂方法模式是什么

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

理解工厂方法模式

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

代码实例

  • 在这个代码实例中,我们将模拟订购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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LvhaoIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值