• Post Reply Bookmark Topic Watch Topic
  • New Topic

Encapsulation and Getters  RSS feed

 
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yesterday, I was involved in a thread discussion that went off topic and was talking about getters inside interfaces. The entire conversation made me question a lot of things and drove me crazy about the way I would write certain lines of code. Basically, getters in interfaces are considered bad design or code smell. My problem is, what happens when you need to access an attribute using a getter regardless of object type?

For example:






Assume that if I store these objects in an ArrayList, and I wanted to view all of them, I could loop though them and call the toString().

Let's say I wanted to do some sort of calculation based off the damage a weapon can cause? For example, in addition to displaying all the weapons, what if I provided another view that showed the top 3 weapons based on damage?

If I had a method that took the weapons regardless of type:



Without a getter, how would this be done?

Sidenote: Maybe game weapons aren't a good example for the problem that I'm having. If I were to simplify it, it would be this. What if I needed to access a specific attribute of an object, regardless of type? 
 
Bartender
Posts: 1664
37
Eclipse IDE Google Web Toolkit Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hank Emery wrote:Basically, getters in interfaces are considered bad design or code smell.

I think You misunderstood Junilu.
Here's his remark:
Junilu Lacar wrote:An interface that defines only getter and setter methods is smelly
 
salvin francis
Bartender
Posts: 1664
37
Eclipse IDE Google Web Toolkit Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Look at interface as a behavior. You are setting a standard for how an object behaves. Typically, you should be able to read an interface to a person who does not know java.

Imagine saying:
"My game has a character who can pick up, drop or buy weapons. He can use it to kill his enemies"

vs:
"My game has a character which has mutators for weapons"

In addition to this, You might want to look at Null Object pattern for behaviors which do not make sense for a particular class.

 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
salvin francis wrote:Look at interface as a behavior. You are setting a standard for how an object behaves. Typically, you should be able to read an interface to a person who does not know java.

Imagine saying:
"My game has a character who can pick up, drop or buy weapons. He can use it to kill his enemies"

vs:
"My game has a character which has mutators for weapons"

In addition to this, You might want to look at Null Object pattern for behaviors which do not make sense for a particular class.



So, in my above example, you agree that having a getter that returns the damage would make sense, if I wanted to sort, or do some sort of calculation? I should use the getter/setters in interfaces when it makes sense to have them? but not have it be the only reason why I'm using the interface, Correct? Would an abstract class be better if all I needed was getter/setters to be available?
 
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hank Emery wrote:. . . So, in my above example, you agree that having a getter that returns the damage would make sense, if I wanted to sort, or do some sort of calculation? . . .
Once you start writing that sort of thing, you start to destroy your own case. But it also gives you all sorts of design possibilities. So now my mind has gone off in flights of fancy
Are you going to want to add up all Swordsmen? Are you going to want to sort all Swordsmen? If you have an interface which has a getStrength() method in, that is not only going to affect its public interface, but it is also going to affect its implementation by encouraging you to give (him) a strength field, and determining the type of that field. Giving that method int type makes it impossible to change the field to a long or a double later on.
You can add other interfaces. For sorting, consider the Comparable<Swordsman> interface, comparing strengths. Consider an Addable interface with the getStrength method. Consider giving it Number as its return type, rather than a primitive, or even ? extends Number. Consider a better name than Addable. Consider putting all your warrior classes in one package, making the strength field package‑private and writing a WarriorList class in the same package. You can write a wrapper round a java.util.List implementation. Then its sort() method can access the strength field directly, but it won't be accessible outwith the package. These are simply ideas, but maybe a plain simple getStrength method in the interface isn't the best design.
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Hank Emery wrote:. . . So, in my above example, you agree that having a getter that returns the damage would make sense, if I wanted to sort, or do some sort of calculation? . . .
Once you start writing that sort of thing, you start to destroy your own case. But it also gives you all sorts of design possibilities. So now my mind has gone off in flights of fancy
Are you going to want to add up all Swordsmen? Are you going to want to sort all Swordsmen? If you have an interface which has a getStrength() method in, that is not only going to affect its public interface, but it is also going to affect its implementation by encouraging you to give (him) a strength field, and determining the type of that field. Giving that method int type makes it impossible to change the field to a long or a double later on.
You can add other interfaces. For sorting, consider the Comparable<Swordsman> interface, comparing strengths. Consider an Addable interface with the getStrength method. Consider giving it Number as its return type, rather than a primitive, or even ? extends Number. Consider a better name than Addable. Consider putting all your warrior classes in one package, making the strength field package‑private and writing a WarriorList class in the same package. You can write a wrapper round a java.util.List implementation. Then its sort() method can access the strength field directly, but it won't be accessible outwith the package. These are simply ideas, but maybe a plain simple getStrength method in the interface isn't the best design.


I'm not getting the answer that I want, because I'm not asking the proper question.  Let me try again, and hopefully I get an answer.

Lets say I have two classes that share the same attributes.  As stated in the previous forum and comment above:

An interface that defines only getter and setter methods is smelly


Now, if I'm required to have getters for these attributes, and using an interface would be bad practice, what then should I do? Would an abstract class be better?
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I should clarify that simply having the same attributes doesn't automatically mean abstract class . I'll add this, assume that both classes share the same methods, just different implementation, enough to justify there existence in two different classes. 
 
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@OP
I don't think that GameWeapon interface supposed to have a method attack(). You might think in your head correctly, but might naming it wrongly. I'd think a game character can attack using a weapon sword, while sword might do is some damage.

i.e.


But reading this thread, I don't really understand your problem, what you are trying to solve. Might could rephrase problem once again?
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is your main problem you are trying to solve, how to enforce some entity to have a behaviour ability to provide some information? (in your case getterOfSomething?)
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:Is your main problem you are trying to solve, how to enforce some entity to have a behaviour ability to provide some information? (in your case getterOfSomething?)


Bare with me my problem is with

ability to provide some information? (in your case getterOfSomething?)


As stated above, and in the other thread that having only getters in an interface is considered code smell/bad practice. I understand that.

However,

as my second example stated, let's say I have two classes that share the same attributes and methods(same method name and return type, just different implementation, enough difference to justify the existence both both classes). Obviously, this isn't ideal, because we have repeated code, such as the constructor, and setter/getters. Seeing as interfaces that contain only getters are considered bad practice, what should I use then, an abstract class?
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My problem was, I was using an interface as an alternative to abstract classes. My interface only contained getters, which as pointed out, is code smell.

Given that I want to provide a constructor, and getters that are same across both classes, an abstract classes but be sufficient, correct?
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alright.

So, let's discuss from the theory perspective. Abstract class means what it means. If you have something abstract, probably makes sense to keep it there.

So if I wanted to make an Employee, I'd create Employee class and put everything what is common among descendants (name.. and that kind of stuff) while in descendent classes you put specifics. In abstract class you can put some behaviour if they are common among all descendants. Descendants might even override some behaviour of abstract class, but that is a borderline, you might want Interface in such case. BUT, if you find yourself a need to override abstract class methods, probably better is to keep method abstract by not providing any implementation and leave that job for extending classes.

According to theory, interfaces supposed to define a behaviour, what object might do. Getters and Setters aren't really behaviours, they just either tell you a state or sets a state, so such things are better to keep in abstract class in my opinion.

An example (I might did some mistakes which prevent from compiling, haven't tried running, sorry in case of that) :


Is it something similar what you are talking about?
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is it something similar what you are talking about?


Yes! and with your example, you answered my question.

According to theory, interfaces supposed to define a behaviour, what object might do. Getters and Setters aren't really behaviours, they just either tell you a state or sets a state, so such things are better to keep in abstract class in my opinion.


Nice way of explaining getters and why they don't belong in interfaces


I'd create Employee class and put everything what is common among descendants (name.. and that kind of stuff) while in descendent classes you put specifics.


This is what I was after for two days. Thanks for clearing it up.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Probably worth to mention that there are tons of different scenarios. Not always you need abstract class, so getter and setter you keep in that particular class of interest.
I'm sure there are cases when you may want to add even some kind of getter in interface to unsure implementing class provides that functionality, but probably at your stage with your assignment you don't want that.

Need to analyse case by case and see what makes sense and what's not. Sometimes you may find along the way writing program that your decisions were not optimum, so you'd need to re-think and re-do - but that is the beauty of programming isn't it.
For experienced programmers that is more natural, so their gut feelings tell them more from the beginning, while for us not seasoned developers need to jump over one or two barriers to reach the finish line
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hank Emery wrote:. . . Lets say I have two classes that share the same attributes. . . . I'm required to have getters for these attributes . . .
What do you mean about two classes with the same attributes? Does that mean they are subclasses of the same superclass and only have the fields which the superclass has? Remember that fields shou‍ld be private and private members aren't inherited, so they would have to have public methods which are inherited. That doesn't necessarily mean getXXX methods.
Who is requiring you to implement interfaces with only getXXX methods? Have you discussed that with them? Is this an assignment? Unfortunately we see lots of exercises which appear to require strange designs. If your assignment tells you that, you will have to comply if you want full marks.
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Hank Emery wrote:. . . Lets say I have two classes that share the same attributes. . . . I'm required to have getters for these attributes . . .
What do you mean about two classes with the same attributes? Does that mean they are subclasses of the same superclass and only have the fields which the superclass has? Remember that fields shou‍ld be private and private members aren't inherited, so they would have to have public methods which are inherited. That doesn't necessarily mean getXXX methods.
Who is requiring you to implement interfaces with only getXXX methods? Have you discussed that with them? Is this an assignment? Unfortunately we see lots of exercises which appear to require strange designs. If your assignment tells you that, you will have to comply if you want full marks.


Not an assignment. My problem comes from the thread I posted. I was making a game as a hobby project, and the topic switched to interfaces and how they are used. I struggled desperately to find an example where I had to supply getters to my classes. When I say two classes, it's just hypothetical. Two classes that happen to share for example studentID, ,studentfirstName,studentLastname, and methods. Now, as stated above, obviously I'm repeating myself with my code, so I was using an interface(I was using it as an alternative to abstract classes) that had only getters. The other thread suggested that was code smell, fine, understood.

No cheating, no assignment, and certainly not asking anyone to give me full code, just explanation.
 
Hank Emery
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:

Is it something similar what you are talking about?


See the getter for the name in the abstract class, won't be better if you made it final? So that the subclass can't override it?
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hank Emery wrote:See the getter for the name in the abstract class, won't be better if you made it final? So that the subclass can't override it?

In general, isn't a bad idea to keep things final, now, is it worth to have every single method final? Some might would say yes, and the argument probably they'd have is - anytime you can remove it, while otherway round action usually is not always possible or simply could be too late.

Probably when you really want to have method marked as final is, when method plays an important behavioural role within application, and you are sure, overriding it could lead to undesired program's flow path, then marking method as final is the way to ensure it won't happen.

Is getter playing such an important role? And at that abstraction level where important application decions are made? Probably not. At least I'd say no in most cases.

What that important role might be what I have mentioned, well, think about for example some financial data processing, regulators define, that financial data needs to be calculated letting it flow through lets call processes A, B, C and D in the sequential order to ensure data complies with regulatory standards. And imagine now, some other interrim process overrides that method and data flows first through B, C, A and D, that sounds like a serious problem, isn't it.

However, it is good to see that you are analysing each and every step, it isn't a usual practice in Beginning Java forum. Have a cow for further motivation.

Let's see what others can advice you.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please don't quote entire posts as it makes topic difficult to follow. Try to cut out only short version on which you are making a comment. Thanks.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!