首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java库存系统

Java库存系统
EN

Code Review用户
提问于 2015-09-27 19:52:52
回答 2查看 8.3K关注 0票数 24

我经常申请工作只是为了测试我的技能。我最近申请了一个,不得不提交一个Java问题,但被拒绝了。请有人简要回顾一下我的申请,告诉我代码中最严重的错误是什么?我有兴趣提高自己,但我很难弄清楚我需要改进什么。

以下是问题所在:

假设您正在开发一个名为IMS的新仓库库存管理系统。IMS将负责实体、单一地点仓库内的库存跟踪工作。IMS将跟踪产品在仓库内的指定物理位置和每个产品的库存级别。IMS将被部署到繁忙的仓库,支持许多采摘者和重新进货者与单个终端和客户一起工作。库存水平的更新将被实时处理,以防止挑选者试图挑选缺货的产品。假设每个产品将存储在仓库中的一个和唯一一个指定位置。库存调整可能是加性的(再库存)或减法(挑选)。无需在位置和级别之外跟踪其他产品信息。问题在Java中,实现了IMS系统的拾取和补充例程。IMS接口将是实现的第一个组件;所有相关的域对象都必须已经分发给依赖它的其他团队。

GitHub

以下是重要的部分:

IMS.java (提供给我们,以创建一个库存)

代码语言:javascript
复制
public interface IMS {
  PickingResult pickProduct(String productId, int amountToPick);
  RestockingResult restockProduct(String productId, int amountToRestock);
}

Inventory.java (implements及其方法)

代码语言:javascript
复制
import java.util.Hashtable;
import java.util.Set;

public class Inventory implements IMS {

    private Hashtable<String, Product> products = new Hashtable<String, Product>();
    private Hashtable<String, Location> locations = new Hashtable<String, Location>();

    public void addLocation(Location location) {
        locations.put(location.getName(), location);
    }

    public void addProduct(Product product, Location location, int amount) {
        products.put(product.getName(), product);
        location.restockProduct(product.getName(), amount);
    }

    /*
     * returns location that has the product when you pass a product ID to it
     */
    public Location getLocationByProductID(String productId) throws Exception {
        Set<String> keys = locations.keySet();
        Location result = null;
        for (String key : keys) {
            Location current = locations.get(key);

            if (current.hasProduct(productId)) {
                if (result == null) {
                    result = current;
                } else {
                    // oh uh, we found the product in two locations, warning the
                    // user
                    throw new Exception("product found in two locations");
                }
            }
        }

        return result;
    }

    public void displayInventory() {
        Set<String> keys = locations.keySet();
        for (String key : keys) {
            Location current = locations.get(key);

            System.out.println(current.getName());
            current.displayInventory();
        }
        System.out.println("");
    }

    @Override
    public PickingResult pickProduct(String productId, int amountToPick) {
        Location loc = null;
        Product product = products.get(productId);

        // transaction data
        boolean transactionSuccess = false;
        String transactionMessage = "";

        try {
            loc = getLocationByProductID(productId);

            if (loc == null) {
                throw new Exception("Product " + productId + " wasn't found in any location");
            }

            int amount = loc.getAmountOfProduct(productId);
            if (amount < amountToPick) {
                throw new Exception("We do not have enough products for this transaction (quantity available: " + amount
                        + "), please restock the product " + productId + "!");
            }

            loc.pickProduct(productId, amountToPick);

            transactionSuccess = true;
            transactionMessage = "We have successfully picked " + amountToPick + " items of " + productId;
        } catch (Exception e) {
            transactionMessage = e.getMessage();
        }

        return new PickingResult(transactionSuccess, transactionMessage, loc, product, amountToPick);
    }

    @Override
    public RestockingResult restockProduct(String productId, int amountToRestock) {
        Location loc = null;
        Product product = products.get(productId);

        // transaction data
        boolean transactionSuccess = false;
        String transactionMessage = "";

        try {
            loc = getLocationByProductID(productId);

            if (loc == null) {
                throw new Exception("Location wasn't found");
            }

            loc.restockProduct(productId, amountToRestock);

            transactionSuccess = true;
            transactionMessage = "We have successfully restocked " + amountToRestock + " items of " + productId;
        } catch (Exception e) {
            transactionMessage = e.getMessage();
        }

        return new RestockingResult(transactionSuccess, transactionMessage, loc, product, amountToRestock);
    }

}

Location.java

代码语言:javascript
复制
import java.util.Hashtable;
import java.util.Set;

public class Location {

    private String name;
    private Hashtable<String, Integer> amountByProductID = new Hashtable<String, Integer>();

    public Location(String name) {
        this.name = name;
    }

    public void restockProduct(String name, Integer amount) {
        Integer previousAmount = getAmountOfProduct(name);

        amountByProductID.put(name, previousAmount + amount);
    }

    /*
     * returns false if we don't have enough product
     */
    public boolean pickProduct(String name, Integer amount) {
        Integer previousAmount = getAmountOfProduct(name);

        if (previousAmount < amount) {
            // not enough items
            return false;
        }

        amountByProductID.put(name, previousAmount - amount);

        return true;
    }

    public boolean hasProduct(String productId) {
        return amountByProductID.get(productId) != null;
    }

    public Integer getAmountOfProduct(String productId) {
        Integer amount = amountByProductID.get(productId);

        return amount != null ? amount : 0;
    }

    public String getName() {
        return this.name;
    }

    public void displayInventory() {
        Set<String> keys = amountByProductID.keySet();
        for (String productId : keys) {
            Integer amount = amountByProductID.get(productId);

            System.out.println("  " + productId + ": " + amount.toString());
        }
    }
}

(我重命名了几个变量,这样就不会被其他候选人搜索)。

EN

回答 2

Code Review用户

发布于 2015-09-28 02:31:50

对于Hashtable,h.j.k非常礼貌。反对Hashtable的Java2于1998年问世。那是17年前的事了实际代码的第一行以Hashtable开头。如果我是一名招聘经理,我就会立刻停止阅读。它运行得非常快,使用17年前被废弃的类真的很糟糕。

我没有完全阅读您的代码,但我认为您应该避免异常。如果请求没有答案,我只会将其写入返回值,而不是抛出异常。它可能会发生,不可能的请求将在一个库存管理系统,我不希望整个系统停止,因为一个不可能的要求。异常应该保留给真正的异常事件,我不认为错误请求是库存系统中的异常事件。对标准返回值使用异常也会带来性能成本。其他人可能会争辩说,使用例外是在这里进行的正确方式。甚至有可能他们要求您使用异常来符合他们的API。

票数 11
EN

Code Review用户

发布于 2015-09-28 06:27:50

虽然提到了位置,但它并不存在于给定的接口中,因此,我不确定在没有明确定义的需求的情况下是否会使用它。也就是说,即使您完美地实现了位置,客户端程序也无法在给定的接口中设置位置。(可以在PickingResult和RestockingResult中返回一个位置,但是任何这样的位置都是任意的--您最好为每个位置返回“某个地方”或“在仓库中”)。

IMS接口中还有一些提示;它返回PickingResult和RestockingResult这一事实非常清楚地表明,不需要抛出异常。

当选择/重新进货成功时,PickingResult和RestockingResult值应该是什么?当他们失败时?他们什么时候会失败?

PickingResult和RestockingResult应该是具体的叶类,还是作为接口/抽象类更好?(例如,类似Scala的抽象选项,带有一些()和None子类的具体子类。)

其中一个要求是“这个接口的实现和对共享数据的访问必须是线程安全的。”是否有您的代码不是线程安全的地方?(提示:是的,有几个。)

提示:看看https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html

您需要确切地了解如何使用它(特别是重试),它不会解决所有并发问题,但它将解决大多数并发问题。(哪一个问题不能解决,你能做些什么来解决这个问题?)

票数 10
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/105857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档