简体   繁体   中英

Java Generic / Enum in Factory

I have studying Java, and wanna understand how to realize idea of such factory of products? (or other way structure of code)

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

1 Question: how to use generic to get any type of Enum class as parameter

Root Categorie

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

SubCategories

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

And, here is a problem begin's:

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;
        }
        
    }

}

in my idea - i want to use addInStorage method for different products, like:

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. how can i use Enum AlchogolType/nonAlchogolType as parametr?
  2. I doubt the correctness of the organization of the code for such a task as: writing a factory for many products with categories, some differences and similarities.
  3. Is a CAST: beer.put((Alchogol) product,amount); normal way?

Question 1

"how can i use Enum AlchogolType/nonAlchogolType as parametr?"

When reading your question, I assume that you are looking for a way on how you can pass both AlchogolType and NonAlchogolType as parameter in the same method. Unfortunately this is not possible, since a method asks for a specific type. Unlike classes, enums cannot override from other classes/enums. This means that the parameter type given in the method cannot be anything else than that.

Let's say there is EnumOne (APPLE, BANANA, PINEAPPLE) and EnumTwo (AUDI, BWM, FORD). If a method asks for a parameter of type EnumOne there is no way of passing anything else that is not defined in the EnumOne enum. You will get compiler errors when trying to pass values from, let's say, EnumTwo .

If you would like to have a work-around for this, you can try and put the values in one enum class. Only do this if your code can still remain maintainable and efficient.

Question 2

"I doubt the correctness of the organization of the code for such a task as: writing a factory for many products with categories, some differences and similarities."

Even though you are using abstraction to divide logic from your models in your code, you are still using separate classes (VirtualDB classes in your case) that prevent your program from using the benefits of abstraction in Object-oriented-programming.

Using abstractions in your model classes (Beer in your case), is good. I would recommend keeping it like that and not go further with applying abstraction in combination with your factory classes.

I believe you only need 1 factory class that holds all of your products. You can make a HashMap for every type of drink, but that makes it so you always have to update your factory class when you make a new type of drink. What you can do is make a single HashMap with as key Product and as value Integer and then save your enum of the type of drink in the Product class. The reason is because the type of drink is a property of a product. Now the only way to tell the type of drink is by knowing in what HashMap it is saved in. That seems inefficient considering later in your code you might have access to a Product instance, without having access to the HashMap in your factory. When saving the type of drink in the Product instance itself, you can make a method that returns the type of drink and that's it.

Question 3

"Is a CAST: beer.put((Alchogol) product,amount); normal way?"

Whether this is ok or not really depends on what you did beforehand. This all has to do with the "A dog is an animal, but an animal is not always a dog" story.

Let's say you have an abstract class Animal and two classes Dog and Cat that both inherit from the Animal class. If you have an instance of an Animal inherited class that you want to cast to Dog and you did not check before if this instance is actually a dog, you are asking for errors to be thrown. The instance could be an instance of a Dog class, but it could also be an instance of a Cat class. If you try to cast it and you are casting it to the wrong inherited type, you will get a java.lang.ClassCastException .

To solve the probable situation where this error could be thrown, always check beforehand if the variable you are trying to cast is of a specific inherited type. You should have a look at theinstanceof keyword.

FYI, modern IDEs will most of the time give you a warning when you try to cast a variable if you did not check it beforehand.


My main language is not English. I tried to explain it the best I could. If you do have comments or anything that you would like to let me know, feel free to edit my comment or put a comment under it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM