You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

args传入的产品对象应在Main循环创建还是Controller层创建?

架构选择建议

直接选args传入UI层、再转交给Controller,在Controller流程里调用工厂方法创建产品实例的方案,别在Main方法里直接循环调createByName写业务逻辑,核心原因和落地注意点如下:

  • 别把Main方法当业务筐。Main的唯一职责是做程序启动的最基础初始化,比如拉起UI、初始化核心依赖,不要往里面塞任何业务逻辑——你现在要做专属优惠,后续大概率要加折扣计算、满减、商品计数这些逻辑,全堆在Main里,后面改优惠规则、加新商品的时候找代码都麻烦。
  • 分层要守好职责边界。命令行参数本质是CLI(命令行)这个UI层的输入源,UI层就干两件事:接收原始输入、做最基础的格式校验(比如判断args是不是空、有没有多余的特殊符号),校验完直接把原始参数传给Controller就行,别在UI层做商品对象转换。不然你以后要是想把输入源换成Swing图形界面、HTTP接口,总不能把对象创建的代码复制粘贴三遍吧?
  • Controller本来就是干流程协调的活。在这里接收UI传过来的商品名列表,循环调用工厂方法创建Product实例,再把实例丢给购物车Service去做加购、优惠计算、结算,整个链路的逻辑是顺的:

    CLI UI:接收args → 基础非空/格式校验 → 传原始参数给Controller
    Controller:捕获业务异常(比如你switch里抛的未知商品异常)、协调工厂和Service完成购物车流程
    业务Service:纯写购物车逻辑、优惠规则计算,不关心输入是哪来的、商品是怎么创建的
    产品工厂:单独存你现在写的createByName逻辑,专职负责根据名称创建商品实例

你现在写的switch创建逻辑本身没毛病,别把它塞在Controller或者Main里就行,单独抽一个ProductFactory类放这段代码,后续加新商品只需要改工厂类,不用动Controller和UI的代码,符合开闭原则,作业交上去结构分会高不少。

给你个最简的分层代码结构参考:

// 程序启动入口
public class Main {
    public static void main(String[] args) {
        // 只做初始化,不写业务逻辑
        ShopController controller = new ShopController();
        new CliUI().run(args, controller);
    }
}

// 命令行UI层
public class CliUI {
    public void run(String[] args, ShopController controller) {
        // 仅做最基础的输入校验
        if (args.length == 0) {
            System.out.println("请输入要购买的商品名称,多个商品用空格分隔");
            return;
        }
        try {
            double totalPrice = controller.checkout(args);
            System.out.printf("优惠后应付金额:¥%.2f%n", totalPrice);
        } catch (IllegalArgumentException e) {
            // 统一处理业务返回的错误,给用户提示
            System.out.println("结算失败:" + e.getMessage());
        }
    }
}

// 控制层,协调业务流程
public class ShopController {
    private final ProductFactory productFactory = new ProductFactory();
    private final CartService cartService = new CartService();

    public double checkout(String[] productNames) {
        Cart cart = new Cart();
        for (String name : productNames) {
            // 在这里调用工厂创建商品实例
            Product product = productFactory.createByName(name.trim());
            cart.addProduct(product);
        }
        // 调用业务层计算优惠和总价
        return cartService.calculateFinalPrice(cart);
    }
}

// 单独抽的产品工厂类,放你原来的switch逻辑
public class ProductFactory {
    public Product createByName(String productName) {
        switch (productName) {
            case "Soup": return new Soup();
            case "Bread": return new Bread();
            case "Milk" : return new Milk();
            case "Apple" : return new Apple();
            default: throw new IllegalArgumentException("不存在的商品:" + productName);
        }
    }
}

如果你的作业总共就几十行代码,写完就扔不会再改,直接在Main里写也能跑,但既然要求是企业开发级别的优质方案,按上面的分层结构写,职责清晰后续好扩展,比把逻辑全堆在Main里靠谱得多。


内容的提问来源于stack exchange,提问作者Joao Barros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:18:21