So I'm writing a game and I've come across a conundrum where I believe Reflection might be a better solution. But knowing that Reflection is discouraged and my other solution doesn't look that pretty, I thought I'd ask here and see what's actually a better idea in this scenario.
Essentially I've got an abstract card class, and will have several implementations of it. I have a case where I'm given a card name and need to construct an object of it, just given the name.
I know I could use either:
a) Reflection and use forName and invoke. It'll be very short code, scale well, and easy enough to write. That said, it's Reflection, and I'm all for avoiding it when I don't particularly need it.
b) Use a Factory design pattern and then have a giant conditional check, calling the appropriate class based on the name I supply. It's not difficult to write but requires constant maintenance and will take a while to write, plus it won't scale well. That said, it's a non-Reflection solution.
So what is the ideal solution? Do I just use Reflection because it keeps my code nice and short?
Skills and attitudes for reflective practice The literature commonly refers to the following as being the skills required of reflective practice: self awareness, description, critical analysis, synthesis and evaluation (Atkins & Murphy, 1994).
It builds stronger connections between learning experiences: Reflective learning is a way of allowing learners to step back from their learning experience, helping them to develop critical thinking skills and, improve on future performance by analysing what they have learned and how far they have come.
As you can see, self-reflection can be a great way to improve your overall life. By taking some time out of your day to reflect on past events, you will have a better sense of self. This sense of self will allow for things like better relationships and improved decision-making in your everyday life.
If you reflect on the things you did right, on your successes, that allows you to celebrate every little success. It allows you to realize how much you've done right, the good things you've done in your life. Without reflection, it's too easy to forget these things, and focus instead on our failures.
Here's an alternative (not sure if it's the "ideal solution" like you've mentioned, but I think it's worth considering): enumerated types. It will still be a huge list, but maybe a bit cleaner? And you have to define them all somewhere.
An example of what I mean:
enum CardType {
CARD_ONE(new Card(arg0, arg1, arg2, ..., argN)),
CARD_TWO(new Card(arg0, arg1, arg2, ..., argN)),
...
CARD_N(new Card(arg0, arg1, arg2, ..., argN));
private final Card card;
private CardType(Card card) {
this.card = card;
}
public Card getCard() {
return card;
}
}
Then when you need to get one by name, just do:
public Card getCardByName(String cardName) {
return CardType.valueOf(cardName).getCard();
}
This assumes the cards are singletons, but you could just as easily make the getCard
method do some sort of factory logic to create a new one.
I would suggest to use a factory pattern and use a prebuilt factory like Spring that you can use to define bean instances with there rather then implement your own factory. It will scale easier as you can just define more bean types in either XML or annotated Java code. Just make sure you use non-singleton beans and every time you ask your spring factory for a bean of a name it will call the constructor properly. It will even allow you to do dependency injection at the same time for free.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With