Hello, New to the Ranch!
Before I continue two things:
I asked this question of StackOverflow, but the answers were mixed, and I think I'm partly to blame because of the example problem I have.
https://stackoverflow.com/questions/46893229/violation-of-isp
https://stackoverflow.com/questions/46841630/using-the-strategy-pattern-to-avoid-downcasting
https://softwareengineering.stackexchange.com/questions/359542/is-it-ever-okay-to-violate-the-lsp/359548?noredirect=1#comment779531_359548
Although my problems has a gaming context
(A text adventure game),
don't take it too seriously, it could have just as easily be vehicles with different subclass for each type. Gaming was the quickest context I could come up with, but I'm starting to regret that. I have a feeling my problem is I'm trying to do too many things at once without a real justification. You'll see
I'm currently reading about SOLID principals and also exploring Design
Patterns.
This is where I learned LSP:
https://www.tomdalling.com/blog/software-design/solid-class-design-the-liskov-substitution-principle/
From my understanding, you'd want to avoid using the keyword instanceof or getClass(), only in certain cases for example in the equals method. I don't really understand why you'd want to avoid instanceof or getClass().
I'll present my problem(s) and the solution I used to fix it and then ask for guidance.
Problem: Some subclasses have
methods unique to that subclass. Which means at some point I would have to downcast.
My attempt at solving the problem: Some of the advice I've been given either violates a SOLID principal or just doesn't make sense. For example, someone suggested that Sword be made aware of Reload just don't do anything which to is a violation or LSP/ISP.
I prohibited inheritance with the final keyword and used the Strategy Pattern to implement the behavior. Example:
I understand, it's a lot of work for very little. The criticism I've received is that it violates ISP(
A comment suggested that Weapon was an ISP violation machine), but I don't think so, because Sword is no longer and shouldn't be aware the Reload method/class. The client is not forced to implement methods it isn't going to use. If for some reason the game allows sword to fire something, for example, fireball, then the client can go ahead and make Sword implement reload, but that's at the client's discretion. Another solution is to have my Weapon class have a prepare method, for Sword it would remove it from inventory, Gun it would be loaded and aimed, I get that, but again, I might end up in a situation where I have a subclass specific method(for example, Sword could have wipeBloodofBlade() or Gun could have adjustLaserSight), and to me anyway the Strategy Pattern seemed to solve my problems.
How so:
I can maintain a List<Weapons> collection without the need for downcasting, the weapons will be loading with the necessary actions.Any weapon that isn't Reloadable, won't have the concrete class Reload. This mean no throwing or leaving the method blank, which is a violation of LSP as stated in the Tom Dalling article above
Questions:
1. Why avoid the use of instanceof or getClass?
2. Is the Strategy Pattern, they way I implemented it, a good solution? If not, why?
3. How would you suggest I fix my code without violating SOLID?
This is not homework. I know it sounds foolish to say, but this problem comes from years of reading and researching, but never being able to come up with a valid solution. My attempt at solving the problem was the Strategy Pattern. Given the amount of code, it probably isn't the best, this is why I'm asking.