Sveta Rosemond

Greenhorn
+ Follow
since Oct 02, 2018
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
1
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Sveta Rosemond

Junilu Lacar wrote:Related to "we're asking the object, do you contain this attribute?" there's also the Tell, Don't Ask Principle which says that rather than asking an object for information and then acting on that information (which in many cases breaks or violates the object's encapsulation), you should tell the object to do something, giving it any kind of information it needs to complete the task. That's a 180-degree turnaround in perspective.  



In the Clean Code example, he asks for information, if the flag is set to true, and acts on it by added it to a list.

The Wizard and Sword example, if an attribute is present then I act on it by either rejecting it or accepting it, if I were to place that logic inside the class, as you pointed out, I might be violating GRASP. so I Rule object is implemented.

In your opinion is encapsulation broken in either example?  
5 years ago

The way I see it is, you're checking the attribute of an object to determine how to proceed. In the Clean Code sample, you're correct, it's about naming, but the author included it in his book, so I doubt it isn't considered clean or bad code even if the naming of the variables and methods are correct. Also, how else would you gather a List of flagged cells if you can't check it's state in someway?  



Sorry, typo!
5 years ago

Junilu Lacar wrote:As I see it, the crux of this whole discussion is whether or not you should check types explicitly or not. Using instanceof programmatically checks an object's type. Checking for inclusion of an enum in a collection where the enum values represent types or attributes is also a way of programmatically checking what kind of thing something is. This case may be in a little bit of a gray area, depending on what exactly the enum values represent. Some (many?) would argue that this is not a good approach and that you should prefer to use the language's type system and polymorphism mechanisms instead of conditional statements.



The way I see it is, you're checking the attribute of an object to determine how to proceed. In the Clean Code sample, you're correct, it's about naming, but the author included it in his book, so I doubt it isn't considered clean or bad code even if the naming of the variables and methods are correct. Also, how else would you gather a List of flagged cells if you can check it's state in someway?  

My point is, in both examples, we're asking the object, do you contain this attribute? Do you contain a boolean variable that's true? If so, here is what to do.  Consider this other example:

I might have a Wizard subclass that contains Mana user as a character attribute. I can also have a Farmer subclass and he/she is also a Mana user, but cannot be classified as a Wizard. They might cast spells, for example, to make their garden grow, but they aren't Wizards in the game world, they will not accompany you on a quest, attack with fireballs or heal you. Now I agree that you should have a Rule class, but how that Rule class is implemented is what's interesting. Instanceof might tell me I have a Farmer subclass, but checking the attributes might tell me a lot more. Not every Farmer might be a Mana user, so implementing an interface might not be a good idea, it might also violate LSP.  
5 years ago
Would an attribute system be a possible solution as well? I'm not saying you code or any of the answers posted are wrong. I just want to look at the problem from a different perspective and find out the different ways to solve it.

Take for example this code snippet from Clean Code, Pg 19:


From this code snippet, we know a know that a cell contains a method that verifies if it's been flagged. In other words, we can ask the cell, are you flagged?

We then collect a List of flagged cells and return to the caller.

With that logic and example in mind, we can have a GameObjectAttributes type, and a  Weapon class that looks like:




A Wizard class might look like this:


Much like the Clean Code snippet, I'm asking the object, do you contain a specific attribute, and if not, add it to the weapons collection.

Question:

When using an enum to filter out objects and place them in a Collection, as shown in the Clean Code example, is it a code smell?

I'm not checking for a specific attribute and then calling a method to perform an action, I'm simply filtering, not more, nothing less.

This might get a little messy, because every subclass of Character might have similar checks, but we can place all of those checks in a Rule object.
5 years ago
What I'm failing to understand is, why can't the Rule class simple use instanceof and check the Character and Weapon types and decided what to do?  

To my anyways, it seems like a lot of code for something that seems to simple. I'm not saying you're wrong, you obviously know what you're doing, but as you pointed out, using the double dispatch with the visitor pattern might be hard to maintain as more character types and weapons get added.  
5 years ago

Junilu Lacar wrote:Code-wise, I'd imagine you'd have a Wizard or Rule that looks something like this:


This uses the language's type system and polymorphic features to route calls like this properly:



The issue is, you'll never deal with a Staff directly in this way. Staff will be stored in the Character inventory as a Weapon, so imagine that Wizard is a subclass of Character with a weapon inventory.

Example:



The problem is in the tryAdd() method, how can I communicate with the Rule class that I have a Sword or a Staff when I'm being given a generic Weapon?  Let's make it easier, don't worry about the Rule class for now, how would I determine in the tryAdd() method what weapon I have?
5 years ago
I'm sure many of you know Eric Lippert's Blog series: Wizards and Warriors. In it, he has two rules:

   A warrior can only use a sword.
   A wizard can only use a staff.

Over the series of blogs, he tries to show you how the C# type system fails to implement those rules and what to do about it instead. He suggest the creation of a Rule class, and let the Rule system determine what can happen in the game. You can agree or disagree, that's not the point of my question. I included it because it relates to my bigger question, how would you tell the Rule class or system that the object you're trying to carry is in fact a Sword without instanceof?

Before anyone accuses me of not trying, I did on three separate times.

My first attempt was to have each weapon contain an enum. This approach was considered bad,

Quote:

When your weapon types enum just mirrors the class hierarchy, then this is a blatant violation of the DRY principle - you encode the same information, the type of a weapon redundantly in two places - one place is the class name itself, one place the enum. That's definitely not just a code smell, that is bad code.




My second attempt was to introduce a private collection with attributes that any class attempting to use the Weapon can query using a method. This too was seen as complicating the issue.

Quote:

Without knowing more of your specific case, I would say yes, you are doing the same thing, you are just making it more complex.

The fundamental problem you are having, is that you are trying to decide how an object would react to some action from outside the object. This is fundamentally not how object-orientation works (or should work). You should ask the object directly to perform the action, and the object will hopefully tell you what the result is if any.



My third attempt, didn't even generate any answers.

This Game Dev link states something I agree with:

In terms of the comparison there isn't really getting around using an enum or something similar. Either the weapon or the thing adding the weapon needs to know if it can be added/equipped, and the only way to do that is to compare it to something known ahead of time and determine if it is true or false. Your options are rather limited in that area, if you don't compare against a weapon type then you'll have to compare against the item i'd or if it implements an interface or something else. These all equate to identifying what the thing is.



Problem:

Weapon is rightfully an abstract class.


Question:

Can someone show me how to implement the rule class and use it, so that when I need to check if a certain character can use a weapon, I can determine what weapon is being checked?

Or in others words...

Because Weapon is an abstract class, you can't determine exactly what weapon it is, so how do you communicate to the Rule class that the weapon you have is in fact a Sword and that a Wizard cannot use it.

Just because I'm a nice person, I'll put it another way...

The Rule class needs to enforce that a Wizard cannot use a Sword, but it will get passed a Weapon object which is an abstract class. How can the Weapon class communicate with the Rule class that it's a Sword?  

Sorry if this post comes off as rude, but I've been frustrated trying to figure this out, and the answers on SESE aren't helpful, they simple confirm something is a bad idea, but no solution on how to fix it.
5 years ago