从输入流中读取并从数据中创建特定实例

时间:2017-11-18 23:32:56

标签: java oop io stream

我有一个BaseProduct接口和两个实现类,GroceryProduct和TechProduct。我创建了一个从输入字节流中读取产品的方法。考虑到两种产品都有相似的领域,我一直在寻找一种方法来使用这种方法创建某种类型的产品。

我提出的唯一解决方案是创建一个帮助方法来获取产品类的构造函数并相应地创建一个实例。

这是解决该问题的最佳方案吗?是否有另一种方法从输入流中读取产品并创建某种产品类型的实例?

{{1}}

1 个答案:

答案 0 :(得分:1)

不,不是。不要使用反射。只需使用多态:

@FunctionalInterface
interface ProductFactory<T extends BaseProduct> {
    T create(String brand, 
             String productName, 
             BigDecimal price, 
             int totalQuantity, 
             int defectiveQuantity, 
             List<Review> reviews);
}

然后传递一个这样的接口的实例,可以写成lamdbda:

public static <T> T input(ProductFactory<T> factory, InputStream in) throws IOException {
    DataInputStream dataInputStream = new DataInputStream(in);
    String brand = dataInputStream.readUTF();
    String productName = dataInputStream.readUTF();
    BigDecimal price = new BigDecimal(dataInputStream.readUTF());
    int totalQuantity = dataInputStream.readInt();
    int defectiveQuantity = dataInputStream.readInt();
    List<Review> reviews = new ArrayList<>();
    for (Review review : reviews) {
        String userName = dataInputStream.readUTF();
        int rating = dataInputStream.readInt();
    }
    return factory.create(brand, productName, price, totalQuantity, defectiveQuantity, review);
}

并像这样称呼它,例如:

ProductFactory<GroceryProduct> factory = 
    (String brand, String productName, BigDecimal price, int totalQuantity, int defectiveQuantity, List<Review> reviews) -> 
        new GroceryProduct(brand, 
                           productName, 
                           price, 
                           totalQuantity, 
                           defectiveQuantity, 
                           reviews);
input(factory, inputStream);

请注意,如果您定义了一个类(让我们说ProductInformation)来保存所有这些参数,并且您将该类的实例作为参数传递给您的产品构造函数,那将会更加清晰。然后,您可以用Function<ProductInformation, T>替换ProductFactory接口。但请注意,如果你这样做,你甚至不再需要这个功能了。你可以做到

ProductInformation info = input(inputStream);
GroceryProduct product = new GroceryProduct(info);