【问题标题】:Java Generic / Enum in Factory工厂中的 Java 通用/枚举
【发布时间】:2021-05-14 13:05:56
【问题描述】:

我正在学习Java,想了解如何实现这种产品工厂的想法? (或其他方式的代码结构)

public interface  VirtualBD <E extends Enum<E>>  {  
    void addInStorage(Class<E> type, Product product, int amount);
}

1问:如何使用泛型获取任意类型的Enum类作为参数

根类别

public abstract class Product { 
    ...
}
public enum AlchogolType {
    Beer, Vodka;
}
public enum nonAlchogolType {
    FreshJuise, Lemonade;
}

子类别

public abstract class Alchogol extends Product {
    ...
}
public abstract class nonAlchogol extends Product {
    ...
}
public class Beer extends Alchogol {
    ...
}

还有,这里有一个问题:

public class AlchogolTables implements VirtualBD{

    HashMap<Alchogol, Integer> beer = new HashMap<Alchogol, Integer>();
    HashMap<Alchogol, Integer> vodka = new HashMap<Alchogol, Integer>();

    @Override
    public void addInStorage(AlchogolType type, Product product, int amount) {
        switch (type) {
        case Beer:
            beer.put((Alchogol) product,amount);
            break;

        case Vodka:
            vodka.put((Alchogol) product,amount);
            break;
            
        default:
            break;
        }
        
    }

}

在我的想法中 - 我想对不同的产品使用 addInStorage 方法,例如:

public class OtherBeveragesTables implements VirtualBD{

    HashMap<nonAlchogol, Integer> orangeFresh = new HashMap<nonAlchogol, Integer>();
    HashMap<nonAlchogol, Integer> soda = new HashMap<nonAlchogol, Integer>();

@Override
    public void addInStorage(nonAlchogolType type, Product product, int amount) {
        switch (type) {
        case FreshJuise:
            orangeFresh.put((nonAlchogol) product,amount);
            break;

        case Lemonade:
            soda.put((nonAlchogol) product,amount);
            break;
            
        default:
            break;
        }
        
    }

}
  1. 如何使用 Enum AlchogolType/nonAlchogolType 作为参数?
  2. 我怀疑代码组织的正确性是否适合这样的任务:为许多具有类别、一些差异和相似之处的产品编写工厂。
  3. 是 CAST:beer.put((Alchogol) product,amount); 正常方式吗?

【问题讨论】:

    标签: java generics enums factory


    【解决方案1】:

    问题 1

    “我如何使用 Enum AlchogolType/nonAlchogolType 作为参数?”

    在阅读您的问题时,我假设您正在寻找一种方法,了解如何在同一方法中将 AlchogolType 和 NonAlchogolType 作为参数传递。不幸的是,这是不可能的,因为方法要求特定类型。与类不同,枚举不能覆盖其他类/枚举。这意味着方法中给出的参数类型不能是其他任何东西。

    假设有EnumOne(苹果、香蕉、菠萝)和EnumTwo(奥迪、BWM、福特)。如果一个方法请求EnumOne 类型的参数,则无法传递EnumOne 枚举中未定义的任何其他内容。尝试从 EnumTwo 传递值时,您会遇到编译器错误。

    如果您想解决此问题,可以尝试将值放在一个枚举类中。仅当您的代码仍然可以保持可维护性和高效性时才这样做。

    问题 2

    “我怀疑代码组织的正确性,例如:为许多具有类别、一些差异和相似之处的产品编写工厂。”

    即使您在代码中使用抽象将逻辑与模型分开,您仍然使用单独的类(在您的情况下为 VirtualDB 类),这会阻止您的程序在面向对象编程中使用抽象的好处。

    在你的模型类中使用抽象(在你的例子中是 Beer),很好。我建议保持这种状态,不要进一步将抽象与您的工厂类结合使用。

    我相信您只需要 1 个包含所有产品的工厂类。您可以为每种类型的饮料制作一个 HashMap,但这使得您在制作一种新类型的饮料时总是必须更新您的工厂类。您可以做的是使用作为键 Product 和作为值 Integer 的单个 HashMap,然后将饮料类型的枚举保存在 Product 类中。原因是饮料的类型是产品的属性。现在判断饮料类型的唯一方法是知道它保存在哪个 HashMap 中。考虑到稍后在您的代码中您可能可以访问 Product 实例,而无法访问工厂中的 HashMap,这似乎效率低下。在 Product 实例本身中保存饮料类型时,您可以创建一个返回饮料类型的方法,仅此而已。

    问题 3

    “是 CAST: beer.put((Alchogol) product,amount); 正常方式吗?”

    这是否可以,实际上取决于您事先做了什么。这一切都与“狗是动物,但动物并不总是狗”的故事有关。

    假设您有一个抽象类Animal 和两个类DogCat,它们都继承自Animal 类。如果您有一个 Animal 继承类的实例,您想将其转换为 Dog,并且您之前没有检查此实例是否真的是一只狗,那么您要求抛出错误。实例可以Dog 类的实例,但它也可以是Cat 类的实例。如果您尝试将其转换为错误的继承类型,您将获得java.lang.ClassCastException

    要解决可能引发此错误的可能情况,请务必事先检查您尝试强制转换的变量是否属于特定的继承类型。你应该看看instanceof 关键字。

    仅供参考,如果您没有事先检查变量,现代 IDE 在大多数情况下会在您尝试强制转换变量时向您发出警告。


    我的主要语言不是英语。我尽力解释它。如果您确实有 cmets 或任何您想告诉我的内容,请随时编辑我的评论或在其下方发表评论。

    【讨论】:

    • 谢谢你的回答(英语也不是我的语言;-))但我理解你 :-) 在问题 3 中我理解 CastException 问题。我只是想知道,可能存在其他方法来组织不同对象类型的代码结构。
    • 你能告诉我如何定义代码的组织以使抽象工作吗?我只是不知道如何组织这些任务的代码。你说:“这会阻止你的程序使用抽象的好处”,但我看不到它,这是主要问题:-(
    猜你喜欢
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多