Please join us at the new JavaWorld Q&A Forums. Your existing login will work there. The discussions here are now read-only.


JavaWorld Talkback >> 958484

Pages: 1 | 2 | >> (show all)
Anonymous
Unregistered




How do you avoid accessors to get (essential?) info?
      #1714 - 09/10/03 04:18 PM

Thanks for the interesting article. I have a question as to how, in some cases, getters/setters can be avoided. There may be a way, but it's not becoming obvious to me. Consider the following:

Within a JSP, you're served up a Person object which describes a human being (name, age, address, SSN, etc.). Are you saying that this Person object should _not_ have a getFirstName(), getLastName(), getSSN()?

If so, what's the alternative?

If not, where do you draw the line in terms of when you should have accessor methods?

I think that the UI example is a bit off mark becasue you can indeed ask an object "draw itself". However, the same isn't true of a non-UI object within a JSP. Am I wrong?

Thx,
AMA


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1799 - 09/11/03 07:22 PM

The way I do it is to have your Person object return a displayable version of itself. This is based on Holub's Visual Proxy pattern.
For example:

Person.getDisplay(request:HttpRequest):IDisplayablePerson

This is unlike the get methods the article is talking about since it's not a primitive but an abstracted class that doesn't expose implementation specifics.

in your JSP:

<%
IDisplayPerson personDisplay = Person.getDisplay(request);
%>
<table><tr><td>

<%= personDisplay.displayName("name_css_id") %>
<%= personDisplay.displayAddress("address_css_id") %>
</table></td></tr>

The IDisplayblePerson is an inner class of the Person object. The methods always return a String regardless of the underlying type in the Person class. The outer object contains db access and any business rules. How the person name is displayed is hidden from the jsp (text box, plain text, anchor, etc.). So if you want to pass some hidden field or extra parameters when the form is submitted, you can do that without touching your jsp. I also have the person object handle the request after the form is submitted since it generated the form fields. It knows how to extract the information and knows what the information means. (e.g. any special codes passed along with the name)

The point is to keep this person specific information centeralized in the person class. All the jsp cares about is displaying a person. It shouldn't worry about anchor tags or when to make field displayable since that information is in the domain of the person object. Your jsp's will also be cleaner since most of the logic code is in the Person object.

Paul L.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1800 - 09/11/03 07:32 PM

Even if the setters and getters are avoided, when you change the attributes of Person by adding a cell phone number or secondary address, you'd still have to change your JSP and Person class. The changes are still coupled, which is the point Holub's article is trying to avoid. Instead, you have just created unnecessary complexity.

Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1801 - 09/11/03 07:43 PM

Quote:

in your JSP:

<%
IDisplayPerson personDisplay = Person.getDisplay(request);
%>
<table><tr><td>

<%= personDisplay.displayName("name_css_id") %>
<%= personDisplay.displayAddress("address_css_id") %>
</table></td></tr>





Adding two new attributes
<%=personDisplay.displayCellNumber("cell")%>
<%=personDisplay.disPlay@ndAddress("addr")%>

means I have just touched my JSP and also need to create the two display methods in the IDispalyPerson inner class. Therefore, you're coupled.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1802 - 09/11/03 08:18 PM

Coupling is unavoidable. The point was to minimize (not eliminate) coupling and increase cohesion. So long as one object calls another, you are coupled. In the example, coupling is minimized to the bare necessities. In this case displaying person info. Cohesion is maintained since I'm keeping data not necessary for display within the Person object.

If you want to add data, you can extend the Interface without affecting other classes using the original interface. If you want to completely change the methods, you can create a new interface. Because all your code is centralized in the Person class, you should only have to make changes in that class. Any other classes and jsp's that happen to use the same interface will not be affected.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




What a crock. [Re: Anonymous]
      #1819 - 09/12/03 12:37 AM

This is a good example of why what Holub is suggesting is a crock. You are seriously suggesting the Person should know about HttpServletRequest? This now creates a package dependency from wherever Person lives to javax.servlet.http - so what if I now want to build a J2ME or Personal java interface that uses the Person code? Guess what I don't have javax.servlet.http on those platforms. What you are suggesting is totally contrary to good design - you are creating unecessary dependencies and therefore limiting the chance to resue the Person code.

Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: What a crock. [Re: Anonymous]
      #1829 - 09/12/03 02:50 AM

Why all the hostility? I guess it's late. Like the article says, in design, there are tradeoffs. The liklihood of me reusing the Person object for such a situation is low. I would argue, the interface for J2ME is much less robust than a web browser, so the likelihood that I would actually want to reuse the Person object in this situation is low. Anyway, it's wasteful to try to predict all future situations your code will be dealt with because it's impossible to predict accurately. Develop and optimize for the problem at hand since you may not ever need to reuse the Person object for J2ME. This is an XP tenet.

Personally I find the promise of multi-UI platform development using the same code base as not being realistic nor being desirable. Alan Cooper in his book, About Face, warns against this approach and I have personally dealt with the pitfalls when I developed with a 4GL. You end up with either bloated and unwieldy code or you compromise functionality.

Regardless, the point was that you can reuse the *interface* and change the guts. Yes, the Person class will change, but the code using the interface will not. If I didn't use this viewable Proxy, and just used the Person class directly, now the Person class and all it's public methods are tied to two platforms. It's inevitable I'll have to do some tweaking to get it to work for both platforms. But look, now I'm handcuffed to two completely disparate UI's. Make a modification for the web version - gotta make sure it doesn't mess up the J2ME version and vice versa. So if you want to talk about reusability, which interface will most likely change, the one that does only what the calling class cares about, or the one that gives the calling class access to lots of data so it can do what it cares about? I argue for the simpler more abstract interface. So then ask yourself, which is worse, modifying the class being reused or modifying every class using the class? Furthermore, would you rather have all that Person data (data that is related to displaying but not what's being displayed like permission or status codes) spread out over lots of code or would you rather have that information centralized? Public accessors basically open the flood gates of your class. You lose control.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




This explains a lot [Re: Anonymous]
      #1847 - 09/12/03 07:52 AM

Alan Cooper is widely reviled in the Java community as the biggest numbskull in the business, especially when it comes to design patterns and such. His explanation of the Singleton pattern is one of the greatest pieces of comedy ever constructed by the human mind. If he's your inspiration, this explains a lot, Holub. You're Cooper Lite (TM)!

Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Argh...what a bullshit [Re: Anonymous]
      #1853 - 09/12/03 09:48 AM

Never heard about more stupid thing. And JavaWorld put this article on the first page, forcing me to read it!
What's the point in embedding HTML back to ordinary classes when we've just used JSP to do the contrary?! We should at leasrt use servlet to be consequent.
Anyhow, it won't work this way. I need Person class to contain its data and perform some piece of business logic, but not to display its contents in some specific way. What if I need to have several slightly different representations of any field. That is, in one JSP I want name to be displayed as a static String, and in another JSP - as a textarea. According to you I need two different strategies in IDisplayPerson - instead of simple HTML code and <%=p.getName()%> where apropriate.
If you don't understand it - are you sure you are in OO programming?


Post Extras: Print Post   Remind Me!   Notify Moderator  
Maurizio
Unregistered




Re: What a crock. [Re: Anonymous]
      #1865 - 09/12/03 01:10 PM

I have to agree that a business object like Person should *never* depends on HttpServletRequest, this should be clear to anybody. In a JSP maybe you could better think to something like a decorator, which, for example, could expose internal fields always as formatted strings:

<% PersonView p = new PersonView(new Person()); %>
...
<%= p.name() %>

This leaves Person untouched and unaware of the web layer.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




What the hell are you talking about? [Re: Anonymous]
      #1868 - 09/12/03 03:18 PM

Are you perhaps meaning James W. Cooper, the JavaPro columnist?

http://www.ftponline.com/search/results.asp?find=cooper&lib=javapro



Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1874 - 09/12/03 05:37 PM

I agree, I know they're evil. Perhaps using one set with a HashMap or other collection is better? I think this sidesteps the issue. I agree getters and setters are bad in certain parts of code. ..ie: the Service/Business Logic portions. But say in a persistence layer, what alternative do you have? You could use tools with Xml mappings. This article sidesteps where legitimate needs are and doesn't mention where it IS absolutely needed or what might be a slightly better approach.

Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1884 - 09/12/03 08:17 PM

Of course the articel is right. If you lets say change the getters of your Adress Object you would also have to change all pages using it.

On the other hand MVC is also quite good. Page-designers just don't like changing for each new picture Java code. And of course the View needs access to the Model.

May be this could be a solution:

The Adress Object has just one method print(HttpServletResponse res, String jsp-name).

Than there is a directory which is reserved for the Adress class. It contains the templates which render the adress class. The templates can be freely changed and defined by the page-designer.

When the print method is called the adress class puts its internal data on the request (May be as an Object with a lot of getter and setters). Than it renders the template from its directory the user named through the second argument. (Afterwards it removes the internal data again from the Request)

Of course if the Adress class changes its internal data the templates in the directory of the Adress class have to be changed as well. However because you have encapsulted the internal data to this one directory, you may be sure that no where else changes have to made. (I guess having a such a dedicated directory would also foster rendering-code reuse).

P.s.: I speak of templates and not of JSPs because I use Freemarker (just better). The aproach works for JSPs of course as well.



Post Extras: Print Post   Remind Me!   Notify Moderator  
Jelmo
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Anonymous]
      #1889 - 09/12/03 09:29 PM

Quote:

Within a JSP, you're served up a Person object which describes a human being (name, age, address, SSN, etc.). Are you saying that this Person object should _not_ have a getFirstName(), getLastName(), getSSN()?




This is the outline of a solution:

Code:
public class Person {
private String name, address;
//other stuff...
public void fillHandler(PersonHandler handler) {
handler.setName(name);
handler.setAddress(address);
}
}

public interface PersonHandler {
void setName(String name);
void setAddress(String address);
}

public class PersonFormatter {
public PersonFormatter(Person person) {
person.fillHandler(new PersonHandler() {
public void setName(String name) {
//do something with name
}
public void setAddress(String address) {
//do something with address
}
});
}

public void write(Writer writer){
//write the person data
}
}



This code never use accessors and also clearly separates the domain object from the code needed to represent it (I don't like at all the getView() idiom proposed by Holub).
Why this code is better than usual code with getters? Because changes will be more localized. Suppose you want to split the address attribute of Person as street/city attributes. If you use getters, in order to keep the previous formatting behavior, you need to change all the classes that use the getAddress() accessor, replacing it with the new getStreet/getCity accessors. With the solution proposed, you only need to change code in the Person class: in the fillHandler() method, pass the the appropriate value to setAddress().

Someone could argue that we could leave a getAddress() accessor in class Person to avoid changes in other classes, but (1) this is not always desiderable and (2) the purpose of this example was to quickly show how changes spread with and without getters.

Clearly this idiom don't eliminate all coupling: if you need to change the PersonHandler interface, then you still need to change all the classes using it. But interfaces are less prone to change that implementation details, so it remains a good design decision.

my 2 cts.

Carlo Jelmini


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Your example is stupid... [Re: Jelmo]
      #1893 - 09/12/03 11:38 PM

... as is the advice given by the article

Post Extras: Print Post   Remind Me!   Notify Moderator  
Jelmo
Unregistered




Re: Your example is stupid... [Re: Anonymous]
      #1894 - 09/13/03 12:13 AM

Your comment is not contributing anything to the discussion. If you have something interesting to say about my post, please elaborate your thoughts.
In particular, I would like to see you giving a counterexample with getters that demonstrate less coupling than a solution without getters.

Carlo Jelmini


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: This explains a lot [Re: Anonymous]
      #1908 - 09/13/03 12:51 PM

Never heard of Alan Cooper being related to the Java community. He's a UI designer. I admit, he's a bit of an iconoclast and very opinionated like Holub, which may be the reason I respect him. I see a lot of herd mentality and band-wagoning in the developer community. People just don't think on their own. I suspect that's why you get comments like "This guy's crazy" "What a piece of junk" and the ilk without much real dialogue.

Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: Argh...what a [censored] [Re: Anonymous]
      #2156 - 09/21/03 02:03 AM

I'm sure you're not reading this anymore, but I've got nothing better to do right now. My assumption is that the determination of whether to display Person data as a text area or a read-only string is based on data within the Person class. To me you're example is missing information. You now not just call getName() but you call another getter to get information that will determine how to display the name. Well basically you've now lowered cohesion because you barfed out Person data and logic related to that data outside of the Person class and you increased coupling by introducing extra methods. So maybe I don't understand OO the way you do. To me OO is another tool to help the developer organize and maintain code through decreased coupling and higher cohesion. Your example seems to do the opposite. If you want me to explain why I believe high cohesion and low coupling are desireable, let me know.

Post Extras: Print Post   Remind Me!   Notify Moderator  
DikHed
Unregistered




Re: Your example is stupid... [Re: Jelmo]
      #2423 - 09/30/03 04:53 PM

Why don't you shut the hell up!
His comment was relevant and made you look like a godamn idiot.
Don't blame him for your effing stupidity.
Here's a counter-example:
Go to the effing fridge and Getter me a beer!


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: Your example is stupid... [Re: DikHed]
      #12792 - 10/25/04 03:31 AM

haha DikHed sucks

Post Extras: Print Post   Remind Me!   Notify Moderator  
Gabor
Unregistered




Re: How do you avoid accessors to get (essential?) info? [Re: Jelmo]
      #13331 - 11/16/04 08:49 AM

Carlo,

Thank You for your clear answer. I'm a newbie for OO paradigme (I have som VB experience), so apologize for the stupid question.

Does it mean, if we have an association between two classes, and need some attribute from the server object, we have to send the client object via interface to the server, that fills the requested properties via interface's method?

Thanks

Gabor


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) [Re: Anonymous]
      #13772 - 12/01/04 11:34 PM

What about...
<%
IDisplayPerson personDisplay = Person.getDisplay(request);
%>
<table><tr><td>

<%= personDisplay.getProperty("name_css_id") %>
<%= personDisplay.getProperty("address_css_id") %>
</table></td></tr>


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: Argh...what a [censored] [Re: Anonymous]
      #14110 - 12/16/04 01:37 PM

----------------
If you want me to explain why I believe high cohesion and low coupling are desireable, let me know.
----------------
good one
that should shut some of those 'closed-minded, unwilling to admit that they're not world's greatest programmers' suckers up...


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) [Re: Anonymous]
      #14211 - 12/20/04 06:47 AM

I agree with this method of minimizing the coupling between objects. But in the area's of persistence and viewing this method is only adding to the complexity. Secondly. I have to alter the java code when the interface changes, thats a big NONO in my book. The people that design the interface no nothing about java code, this means I need 2 people to do 1 simple thing.

I think this way of programming (Which I also do) is best used in the business domain and the controller domain. view and persistence domain are not suitable (with current tools) to adopt the suggested method in the article.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Pedant
Unregistered




Re: Your example is stupid... [Re: DikHed]
      #15596 - 02/17/05 08:31 AM

Dear Mr. Hed,
How can you tell if there is beer in the fridge (the Heisenberg's Beer Dilema) ?
Just tell the beer to go drink itself !


Post Extras: Print Post   Remind Me!   Notify Moderator  
Anonymous
Unregistered




Re: How do you avoid accessors to get (essential?) [Re: Anonymous]
      #22058 - 09/22/05 09:57 AM

you just made an business object dependent on HttpRequest. you will never be able to use this person class in any other environment but a web application.
i think introducing a dependency from business layer to presentation layer is much much more evil then getters/setters.

remember: data goes up, dependencies go down !


Post Extras: Print Post   Remind Me!   Notify Moderator  
Pages: 1 | 2 | >> (show all)



Extra information
0 registered and 1 anonymous users are browsing this forum.

Moderator:   

Print Topic

Forum Permissions
      You cannot start new topics
      You cannot reply to topics
      HTML is disabled
      UBBCode is enabled

Rating:
Topic views: 23297

Rate this topic

Jump to

Contact us JavaWorld

Powered by UBB.threads™ 6.5.5