This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Hardcoding vs. Flexibility Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Hardcoding vs. Flexibility" Watch "Hardcoding vs. Flexibility" New topic
Author

Hardcoding vs. Flexibility

Bob Wheeler
Ranch Hand

Joined: Apr 24, 2009
Posts: 317
Hi all,

right now I am stuck at the decision to hard code the db column names in my data transfer object (DTO) Room or do something else.

Better to tell you where I am right now:
- I have opted for hardcoding the order and names of the columns in my RoomTableModel of my presentation layer. My reasoning was that the gui is what the user is seeing and we have to make sure that it is user friendly. So can we rely on the db column names and order? My answer is no. Maybe the user changes his intentions and wants other names, what about tool tips or another field order. But if we rely on the db we have to change the db accordingly. I don't like that.
- On the other side, in my database layer I read the db header information and create a schema object, which is used throughout this layer. So I don't mind changing the order, names or even deleting columns. This layer would still work. But the schema has no connection to other layers.
- But what about the business layer? I have here my DTO. I added a HashMap to the room object which acts like an adapter between the db columns and the table columns, like that:


I added a static getFieldPosition method to get the position of the field in the db.
So now my application is flexible in a way, that only minor changes have to be done.
What do you think? And is it legal to add these information to a DTO?

Thanks for your help,
cheers
Bob


SCJP 6 - SCJD - SCWCD 5 - SCBCD 5
JavaEnterpriseEditionFaq - TomcatFaq
Bob Wheeler
Ranch Hand

Joined: Apr 24, 2009
Posts: 317
One note to my previous post: My Database layer is not that flexible like I thought.
I use a Room Cache, a Map<Integer, Room>, in the db layer to cache all records from the db. So I can only use the entries I have in my Room object, which is actually my DTO. But this DTO is in my business layer, so if I add or remove a db column I have to change that object as well.
Actually if I think about it. Is this Room object really a DTO? I use it in my database, business and presentation layer. I am confused

Thanks for any help.
cheers
Bob
stanislav bashkirtsev
Ranch Hand

Joined: Aug 17, 2009
Posts: 75
wiki wrote:Data transfer object (DTO), formerly known as value objects[citation needed] or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.
Do you use DAO-level hand in hand with DTO?
Is this Room object really a DTO?
I don't see actually the Room class
You can create some text file to tune collaboration of your program and DB. Maybe is should be some kind of ResourceBundle with structure:

Hardcoding always lacks flexibility.
Bob Wheeler
Ranch Hand

Joined: Apr 24, 2009
Posts: 317
Hi Stanislav,
thanks for answering.

stanislav bashkirtsev wrote:
wiki wrote:Data transfer object (DTO), formerly known as value objects[citation needed] or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.
Do you use DAO-level hand in hand with DTO?

EDIT:
I have a Service class with bookRoom and findRoom, which creates or takes a room object. So yes, I think I can call it a DTO. But I also use my "DTO" as part of the room cache. And I have a static hashmap and a static method. I am not really sure if that is allowed.


Is this Room object really a DTO?
I don't see actually the Room class

Good point, taken.
Here is part of it:

Actually this class is coupled to both directions, to the database layer and the presentation layer. So the flexibility is, I have only to do minor changes to my code if
(i) the database column order is changed
(ii) the table columns in the gui is changed (this is more likely to happen I guess)
(iii) database columns are removed or added


You can create some text file to tune collaboration of your program and DB. Maybe is should be some kind of ResourceBundle with structure:

Hardcoding always lacks flexibility.

True, but I like to follow a middle way between pure hardcoding and no hardcording at all. Like I said, in the presentation layer I don't see the advantages on the hardcoding side, whereas in the database layer I'd like to follow the flexible approach. With my approach I MUST do some minor changes to the Room class, if a db column is added or removed (in the latter case also to the gui). So this is not 100% flexible, but I think/hope that it is good enough for the assignment.
Any comment? What do you think guys and girls?

Thanks for any help.
cheers Bob
stanislav bashkirtsev
Ranch Hand

Joined: Aug 17, 2009
Posts: 75
If you don't like properties-file, you can also do something like this. First, create an enumeration, that represents properties of the Room:
Then your Room should look like
In this case you would not change your Room even if columns were changed or deleted or added. You would just add new enumerated type into your RoomProperty.
Anne Crace
Ranch Hand

Joined: Aug 29, 2005
Posts: 223
I hardcoded column names. I think it's more intuitive to the user, and also added a Record Number column, for the same reason. My table looks a bit more like a real database. I documented this in my choices.txt.


SCJP, SCJD
Bob Wheeler
Ranch Hand

Joined: Apr 24, 2009
Posts: 317
@Stanislav:
I like this idea using an Enum. Gread Idea. Why didn't I thought about it? Thanks.
This way I only have to edit the enum like you said. Not 100% flexible but that is enough for me.

Anne Crace wrote:I hardcoded column names. I think it's more intuitive to the user, and also added a Record Number column, for the same reason. My table looks a bit more like a real database. I documented this in my choices.txt.

Yeah, I agree. Hardcoding column names in the presentation layer is really an advantage for the junior programmer and it's also easier if the user wants to have changes on the GUI, like changing the column order. But I didn't use the record number in the table. I didn't see any reason for that.

cheers
Bob
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5216
    
  12

Hi Bob,

My solution provided a dynamic read of the database schema:
  • If a column is made bigger or smaller, it can be done without changing anything in the code (although that's not exactly true, because in the gui I used hard-coded values instead of using the information from the database-schema). I documented that (using database-schema in the gui) as outside the scope of this assignment.
  • If a column is added or removed, the only thing you have to change is the conversion method between my transfer-object and String[] (and vice versa). And of course also the GUI if the new field should be visible for the user.


  • Also didn't use the record number in the table, because it has no added value (an average CSR doesn't have any knowledge of how a database or table looks like).

    Kind regards,
    Roel


    SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
    http://www.javaroe.be/
    Bob Wheeler
    Ranch Hand

    Joined: Apr 24, 2009
    Posts: 317
    Hi Roel,

    thanks for answering.

    Roel De Nijs wrote:
    My solution provided a dynamic read of the database schema:
  • If a column is made bigger or smaller, it can be done without changing anything in the code (although that's not exactly true, because in the gui I used hard-coded values instead of using the information from the database-schema). I documented that (using database-schema in the gui) as outside the scope of this assignment.


  • Agree. One question about the validation of the column entries. Where do you validate the syntax of the customer id and the date, I mean in which class? I did the validation in my transfer object Room, because I thought the format of them (8-digit and yyyy/mm/dd) can't be read from the database columns (at least if the db is empty) and can also be seen as a business rule. Who knows, maybe the client will move to Germany or Belgium and use another date format.
    I guess the length of the fields has to be hardcoded on the gui side, like you said.


  • If a column is added or removed, the only thing you have to change is the conversion method between my transfer-object and String[] (and vice versa). And of course also the GUI if the new field should be visible for the user.


  • If you talk about the conversion method I guess you talk about the constructor and a getRecord method, at least that is my method:

    So you change these methods directly if the db schema changes. Did I understand you right?
    And did you care if the order of the db columns changes or if the gui table changes its order? Or is this way to much work I do?

    Thanks for your help.
    cheers
    Bob
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 5216
        
      12

    Hi Bob,

    I'll try to answer your question as good as I can:
  • a date I don't validate (because it is never entered by a user). customer number is restricted by the gui (only digits can be entered, maximum 8 digits can be entered, as long as less than 8 digits are entered, user can only cancel not book). in my business service i check if the provided customer number is valid (meaning it is a 8 digit number), if it's not I throw an IllegalArgumentException (this exception will be never thrown from my application of course).
  • i have a utility class with 2 static methods to do the conversion between TO and String[] (and vice versa). If a database schema change (an extra column for example) is made which I have to handle, I have to change these conversion methods (otherwise program won't run anymore)
  • i display the columns in the gui table like they appear in the database. if another order is required i have to change my custom table model slightly. user can switch the order of the columns, but these changes are not persisted (so with a following search for example the order of the columns is back in the initial position)


  • 1 great advice i can give you: always keep it as easy as possible and don't do things that are not required.

    Kind regards,
    Roel
    Bob Wheeler
    Ranch Hand

    Joined: Apr 24, 2009
    Posts: 317
    Roel De Nijs wrote:
    I'll try to answer your question as good as I can:
    l

    Thanks a lot, Roel. Great help.

    Thanks all.
    cheers
    Bob
    Ehsan Rahman
    Ranch Hand

    Joined: Feb 16, 2009
    Posts: 59

    Bob Wheeler wrote:
    I use a Room Cache, a Map<Integer, Room>, in the db layer to cache all records from the db. So I can only use the entries I have in my Room object, which is actually my DTO.
    ...
    I have a Service class with bookRoom and findRoom, which creates or takes a room object. So yes, I think I can call it a DTO. But I also use my "DTO" as part of the room cache.


    Hi Bob,

    If I understand correctly, the data file records have been cached in terms of Room DTOs. Just out of curiosity, are data file records (of type String[]) also being cached in order for the public int [] find(String [] criteria) {} interface contract to still hold?

    Re Hardcoding vs. Flexibility: I think that providing flexibility in the data layer in terms of extraction isn't difficult and the customer might appreciate this for a new field they want to display. However it is hard to know if the customer would always want a new field's data to be sent and displayed to clients (e.g. meta-data), so it might be better to keep such code fixed and readable for configuration.


    SCJP 1.5, SCJD 1.6
    Bob Wheeler
    Ranch Hand

    Joined: Apr 24, 2009
    Posts: 317
    Hi Ehsan,
    Ehsan Rahman wrote:
    If I understand correctly, the data file records have been cached in terms of Room DTOs. Just out of curiosity, are data file records (of type String[]) also being cached in order for the public int [] find(String [] criteria) {} interface contract to still hold?

    I have a Map where the room objects (my DTO) are mapped by a record number. If I need a String array, I call a converter method on the room object. So no need for a second cache.

    Ehsan Rahman wrote:
    Re Hardcoding vs. Flexibility: I think that providing flexibility in the data layer in terms of extraction isn't difficult and the customer might appreciate this for a new field they want to display. However it is hard to know if the customer would always want a new field's data to be sent and displayed to clients (e.g. meta-data), so it might be better to keep such code fixed and readable for configuration.

    Yeah, it's hard to know, but you have to think about the possibility that some new room properties are added or removed. In my code only minor changes has to be done.

    cheers
    Bob
    Ehsan Rahman
    Ranch Hand

    Joined: Feb 16, 2009
    Posts: 59

    Bob Wheeler wrote:
    If I need a String array, I call a converter method on the room object. So no need for a second cache.


    Howdy Bob, gotcha! Thanks
     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
     
    subject: Hardcoding vs. Flexibility