How to specify the steps of a method

I need to define a common "pattern" for the methods in a class.

As example I want all the methods to:

1) Retrieve data from a common scope object;

2) Test this data;

3) Execute the specific functionalites using this data;

4.1) If everything work fine -> output the results;

4.2) If an error occurs -> display the error.

As you can see, only point 3) is different according to the method I'm invoking.

Obviously I don't want to copy & paste the code each time!

Any idea?

[542 byte] By [mbm63a] at [2007-10-2 5:57:49]
# 1

> As you can see, only point 3) is different according

> to the method I'm invoking.

I take your word for it, but I can't see it obviously : data retrieval, data checking, and error handling might all be different depending on the method's logic.

> Obviously I don't want to copy & paste the code each time!

Why?

I mean, copy/paste code is certainly bad for maintenance, because you have to ensure manually the consistency of all "copies" when you modify one.

But in your case you seem to say that the structure of your methods will NOT change over time : there will always be your 4 phases, even if the contents of each phase evolves over time.

So you can copy/paste this structure (see below).

> Any idea?

Extract each of steps 1, 2, and 4 into their own private method:

retrieveData(Context);

checkData(Context);

handleError(Context, Result);

Then each method becomes:

public void someSpecificMethod(Context ctx) {

Data currentData = retrieveData(Context);

if (checkData(Context)) {

// Put your method-specific logic here

...

result result = ...;

handleResultAndErrors(Context, Result);

}

jdupreza at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

If even repeating this pattern of code is too much of a hassle, you can:

- extract the method-specific code in classes implementing Method Objects (is that the accepted name for this construction? Or is that a degenerate case of Strategy?)

- and use the Template Method (GoF) pattern.

e.g.:

public void performAddition(Context ctx) {

AdditionPerformer additionner = new AdditionPerformer();

additioner.perform(ctx)

}

public void performDivision(Context ctx) {

DivisionPerformer divider = new DivisionPerformer();

divider.perform(ctx);

}

then

public class AdditionPerformer extends TemplatePerformer {

protected int performSpecifics(int op1, int op2) {

return op1+op2;

}

}

jdupreza at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Note that I mentioned Division purposefully, to show that the "common" part 2 (data checking) indeed often depends on the method specifics...

And that using template method for the checking part too, with a sensible default instead of an abstract method, is still a nice way to handle such specificities!

jdupreza at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

Thanks jduprez for your suggestions.

The "example" I described in my message is not a real "user case".

I just wanted to explain my problem in a short/simple way.

You can change the methods I wrote with wathever you want...

I know that the "common methods" might all be different depending on the method's logic.

What I'm trying to wrtie is a kind of framework to build in a fast way CRUD applications.

I don't want the programmer to write each time the common logics of the Create, Retrieve, Update and Delete processes.

He just need to tell me the data that distinguish the class he is writing.

Your solution is something I've already considered.

In effect I'm using an "implementation" of what you suggest through the use

of interfaces combined with abstract classes.

I don't want to explain it now because I'd like to find different points of view

on the question and I don't want to influence other people ideas.

mbm63a at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

>

> I know that the "common methods" might all be

> different depending on the method's logic.

>

> What I'm trying to wrtie is a kind of framework to

> build in a fast way CRUD applications.

>

> I don't want the programmer to write each time the

> common logics of the Create, Retrieve, Update and

> Delete processes.

> He just need to tell me the data that distinguish the

> class he is writing.

>

Generate your code.

Write a parser/compiler which takes an input file and generates all the appropriate classes and methods.

Your input file might be, for example, the SQL schema for the database itself. The output would be a class file(s) for each table with appropriate method for CRUD and appropriate data members for the fields in each table.

For relationships you can generate that too or manually create it.

jschella at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 6
> I need to define a common "pattern" for the methods> in a class.That's called subtyping and is the basis without which no pattern could exist.
.u....j.a at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

> The "example" I described in my message is not a real

> "user case".

> I just wanted to explain my problem in a short/simple

> way.

Sorry I hadn't noticed it was only an example. So you're looking for something even more generic than that?...

> I know that the "common methods" might all be

> different depending on the method's logic.

> What I'm trying to wrtie is a kind of framework to

> build in a fast way CRUD applications.

> I don't want the programmer to write each time the

> common logics of the Create, Retrieve, Update and

> Delete processes.

I'm not sure the "common logics" is that big... The logic fo creation, for example, has to check whether the creation is allowed, depending on the existing data, new data, user's credential, time of day, whatever...

If what you want to provide is only the "persistence" part of the CRUD, be aware that a number of technologies and frameworks already exist in this area.

If you want something more generic, including the organization of classes code in logical steps, I'm afraid you'll end up with something so generic that it provides low value (pre- and post- callbacks?).

Unless you target a segment of CRUD applications that have more commonalities between them, such as a range of CRUD apps within one organization, or around a certain domain model?

> He just need to tell me the data that distinguish the

> class he is writing.

OK I'll sound pedantic here, but I don't think data distinguish classes... unless, again, you're talking of a restricted range of classes (e.g. Data Transfer Objects) or applications?

> Your solution is something I've already considered.

Yeah, I've noticed this pattern within your other threads too :o)

> I don't want to explain it now because I'd like to find different points of view

> on the question and I don't want to influence other people ideas.

Still, can you elaborate a little more? You don't need to describe your design... but you should describe your goal, or business requirements, in more details.

jdupreza at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

Ok, I'll show you something I've done to clarify the situation.

I'm concerning about the Business Logic Tier (the DAO tier can be

implemented using Hibernate, IBatis, ... whatever you want...)

I've written a group of interfaces:

bo.interfaces.BaseInterface

bo.interfaces.Deletable

bo.interfaces.Inquirable

bo.interfaces.Insertable

bo.interfaces.Replaceable

bo.interfaces.Updateable

[...]

and a group of routines:

bo.routines.Delete

bo.routines.Inquiry

bo.routines.Insert

bo.routines.Replace

each routine implements the interface

bo.routines.Routine

that defines only the method

java.lang.Object exec(BaseInterface baseInterface);

As example, the interface bo.interfaces.Insertable exposes the following methods:

// The facade method of the insert process.

java.lang.Object insert(java.lang.Object data)

// The facade method to check the data for the insert process.

java.lang.Object insertionAllowed(java.lang.Object data)

// Checks if the data is insertable.

ErrorList getUninsertableDataReason()

// Checks if the key is insertable

java.lang.String getUninsertableKeyReason()

// Inserts the data.

void insertData()

// Returns the data from the persistence layer

java.lang.Object getData()

The first step of the method exec in the routine bo.routines.Insert

is a class cast of the argument to a bo.interfaces.Insertable object:

public Object exec(BaseInterface baseInterface) throws BOException, BOFault {

Insertable insertable = (Insertable) baseInterface;

[...]

}

Only a bo.interfaces.Insertable object can execute the insertion process...!!!

Now I can call the methods of the interface on the object insertable

following the insertion pattern I prefer...

public Object exec(BaseInterface baseInterface) throws BOException, BOFault {

Insertable insertable = (Insertable) baseInterface;

String uninsertableMsg = insertable.getUninsertableKeyReason();

if (uninsertableMsg != null) {

[...]

}

if (insertable.getData() != null) {

[...]

}

[...]

}

In this way when I create a new class I can decide the interfaces I need to implement:

public class ItemMasterBO

implements

Inquirable,

Deletable,

Insertable,

Replaceable {

// Implementation of the methods of the interfaces

[...]

}

And then all I have to do is create a new bo.routines.Routine and pass the class itself as argument of the exec method:

public class ItemMasterBO

implements

Inquirable,

Deletable,

Insertable,

Replaceable {

// Implementation of the methods of the interfaces

[...]

public Object inquiry(Object key) throws BOException, BOFault {

return (new Inquiry()).exec(this);

}

public Object insert(Object key) throws BOException, BOFault {

return (new Insert()).exec(this);

}

[...]

I like this solution...

but I seems to me it is too complex...

I was wondering if there exists something simpler...

mbm63a at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

>

> I like this solution...

> but I seems to me it is too complex...

> I was wondering if there exists something simpler...

Are you writing code so that you don't have to write as much code or so that the users of your API don't have to write as much code?

If the former then your solution is wrong. And the solution is....

1. Determine what is easiest for your users to use.

2. Write that code (and as I already suggested you can greatly minimize the code that you need to write by generating it.)

jschella at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 10
What I need is:1) A way to "guide" the users of my API in the development of his classes;2) The definition of the standard routines in such a way that I can change them,correct bugs, whatever,... without having to check all the classes that use the routines.
mbm63a at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> What I need is:

>

> 1) A way to "guide" the users of my API in the

> development of his classes;

DAOs and DTOs is one way.

Or look at hibernate.

>

> 2) The definition of the standard routines in such a

> way that I can change them,

> correct bugs, whatever,... without having to check

> all the classes that use the routines.

Which is handled completely if you generate the code rather than writing it by hand.

jschella at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 12
Look into Aspect Oriente Programming. This might be a perfect use case for aspects.
Anton_Slutskya at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

4 jschell:

I'm talking about the BO tier... not the DAO...

I already use hibernate...

I can't figure out the specific business logic, but I want the programmer

to follow a standard pattern when he is writing his code.

AOP could be a good solution...

..I need to think about it and what could be good or bad...

mbm63a at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

> 4 jschell:

>

> I'm talking about the BO tier... not the DAO...

> I already use hibernate...

DTO's are applicable between any disparate layers. Just because the J2EE patterns limits it to that doesn't mean that it can't be used elswhere.

And you specifically said "CRUD applications." If you weren't concerned about the DAO layer then you need to explain what you think CRUD means in terms of what you actualy are doing.

>

> I can't figure out the specific business logic, but I

> want the programmer

> to follow a standard pattern when he is writing his

> code.

You don't know what the pattern is but you want to force someone else to follow it?

Sounds like a good trick.

jschella at 2007-7-16 2:06:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> And you specifically said "CRUD applications."

> If you weren't concerned about the DAO layer then you need to

> explain what you think CRUD means in terms of what you actualy are doing.

persistence tier: update equals SQL update.

business tier: create equals:

1) Is there something to update?

YES -> go on;

NO -> error!

2) Are there missing values?

NO -> go on;

YES -> error!

3) Does the object exist?

YES -> go on;

NO -> error!

4) Try to update the values

OK -> go on (end);

KO -> error!

Not always so simple, but it should be clear...

> > I can't figure out the specific business logic, but I

> > want the programmer

> > to follow a standard pattern when he is writing his

> > code.

> You don't know what the pattern is but you want to force

> someone else to follow it?

I said I don't know what the BUSINESS LOGIC is...

I know the pattern!!!

business logic: release a purchase order.

pattern: exactly the same pattern of all the replace functions!

mbm63a at 2007-7-20 18:45:37 > top of Java-index,Other Topics,Patterns & OO Design...
# 16

> > And you specifically said "CRUD applications."

> > If you weren't concerned about the DAO layer then

> you need to

> > explain what you think CRUD means in terms of what

> you actualy are doing.

>

> persistence tier: update equals SQL update.

> business tier: create equals:

> 1) Is there something to update?

>YES -> go on;

>NO -> error!

> 2) Are there missing values?

>NO -> go on;

>YES -> error!

> 3) Does the object exist?

>YES -> go on;

>NO -> error!

> 4) Try to update the values

>OK -> go on (end);

>KO -> error!

>

> Not always so simple, but it should be clear...

Seems rather simple to me. The way I impement my DAO/DTOs means that all of that logic is handled either by the DTO or by the DAO.

>

>

> > > I can't figure out the specific business logic,

> but I

> > > want the programmer

> > > to follow a standard pattern when he is writing

> his

> > > code.

>

> > You don't know what the pattern is but you want to

> force

> > someone else to follow it?

>

> I said I don't know what the BUSINESS LOGIC is...

> I know the pattern!!!

>

> business logic: release a purchase order.

> pattern: exactly the same pattern of all the replace

> functions!

You have the business pattern and that is the pattern that you want followed.

You said that you didn't know what the pattern is.

jschella at 2007-7-20 18:45:37 > top of Java-index,Other Topics,Patterns & OO Design...