OO Design Vs. RDBMS functionality

Hi All,

I am new to Java world, been Oracle DBA so far and I am dealing with the following situation and need your input/comments on this:

We have a business entity called Button and the button can be one of the following types:

HTMLButton, MenuButton, SearchButton etc.

So in our UML Diagram, we defined Button as a parent class (having members that are common to all the derived buttons like buttonId, Name, Description etc.) and the above 3 as the derived classes containing members that are specific to this particular entity. e.g., HTMLButton has a member called HTMLContents and SearchButton has a member called SearchURL etc.

On the RDBMS side, we are using a single table to store all different kinds of buttons with an additional column "Button_Type". This table contains all the members from all the parent and derived classes. The buttonId will be unique across all the button types, hence a primary key for this table.

Now, we are writing few methods for these classes that will be used by the business logic like remove(), update() and find().

There are 2 ways to code these methods that I could think of.

First Way:

-

The parent class Button implements all 3 of the methods but in the find and update method, it only handles the members that are visible to this class. So in update method, it has SQL to update only the Button members/columns based upon the Primary key buttonId. And in the find method, it returns a Button object back based upon a given buttonId.

And all the derived classes override these methods by first calling the (super).update or (super).find and then adding their own code to handle the specific members of their own code.

e.g.

public class Button {

public Button find (String buttonId)

{

Button button = new Button();

// do all the logic to select button_id, button_name, button_desc from table_name where button_id = ? " and do the getString and call the setters on button.

return button;

}

}

public class HTMLButton extends Button {

public HTMLButton find (String buttonId)

{

HTMLButton htmlButton = new HTMLButton();

Button button = (super).find(buttonId);

// call the getters on parent to set the common members first

htmlButton.setName(button.getName()); // repeat for other common memebrs

// now get the HTMLButton specific members from Database and call setters on HTMLButton.

// "select html_content, html_btn_height from tab_name where button_id = buttonId"

// do a htmlButton.setString(rs.getString("HTML_CONTENT"));

return (Button) htmlButton;

}

}

So in a nutshell, the first way, i described above, breaks the table in 2 parts and the first part is handled by the parent and the second part is handled by the derived class.

Second Way:

--

I treat Button class as Abstract or may be a class that just stores the method signatures but the actual implementation is done at the derived class level. So while writing a find method on derived class, it executes a SQL like:

"Select button_id, button_name, button_desc, html_content, html_btn_height from tab_name

where button_id = buttonId"

and then calls the setters and returns the object back.

Now the problem:

--

So I am trying to figure out which one is better way to implement.

The first approach gives me a better OO approach but at the same time, doubles my database access as each update or find will be called in 2 steps (partially by parent class and partially by child class).

The second approach makes me write duplicate code but avoids poor performance on the database side.

I can tell you one thing that there wont exist something called a Button by itself, it always belongs to some type of button.

So I will really appreciate responses on this forum and I am sure this will help me in understanding OO approach better while at the same time, giving me an efficient performace.

Thanks in advance

[4110 byte] By [ghant] at [2007-9-27 19:43:18]
# 1

As there will never exist a Button object, by definition it is not a concrete class and your "Second Way" is the correct OO approach. A good approach is to declare Button as an interface with the common methods that must be implemented by the different button types. Also, to minimize code duplication, could use a "helper" class.

HTH

Tim...

tsmcnamara at 2007-7-6 23:02:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

I feel Tim in incorrect, the correct OO approach would be the "First Way", as behaviour common to the subclasses can be captured in the button class, even if the class itself is abstract.

However, the original poster has indicated that this would bring additional overhead to the database. I would still try and do it this way, and implement some clever scheme to avoid the database overhead. Perhaps the method in Button can start the construction of the database query, but allow subclasses to extend this by overriding another method, something like:public class Button {

public (static) Button find(String buttonId) {

StringBuffer queryBuf = new StringBuffer("SELECT buttons_tbl.button_id, buttons_tbl.button_name");

query.append(getExtraSelectFields());

query.append(" FROM buttons_tbl ");

query.append(getFromExpression());

query.append(" WHERE buttons_tbl.button_id = '");

query.append(buttonId);

query.append("'");

query.append(getWhereExpression());

// fire off query and capture result

}

protected abstract String getExtraSelectFields();

protected abstract String getFromExpression();

protected abstract String getWhereExpression();

protected

}

HtmlButton would then implement just the abstract methods, e.g.:public class HtmlButton {

public String getExtraSearchFields() {

return "htmlbuttons_tbl.html_content, htmlbuttons_tbl.html_btn_height";

}

public String getFromExpression() {

return " LEFT JOIN htmlbuttons_tbl";

}

}

Well, it needs to be a bit smarter than this, but I hope you get the point.

hhor at 2007-7-6 23:02:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 3
once had a parent/child table of Agent (parent) and 'Sub' agents (children). then used a factory to instantiate the corresponding java agent reading the attributes from the tables. I think this is what you want to do.
mchan0 at 2007-7-6 23:02:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

Sorry if this seems a bit naive, but wouldn't it be better to use a factory pattern instead of relying on an RDBMS tables for storing object attributes? Depends on your problem space... but I once analyzed an app that used the DB heavily for this sort of stuff and it just led to a pretty sick schema. I always try to limit the db to handling data, not programmatic stuff.

ybakos at 2007-7-6 23:02:47 > top of Java-index,Other Topics,Patterns & OO Design...