OO Design question about batch job

R

Rhino

I have a batch program that generates several flat files. The files being
generated are of various types, including HTML, ASCII, CSS, and PDF.

At the moment, each distinct file is generated in its own separate method.
The main of the class simply executes each method in turn. The different
methods share a small amount of data via class variables.

Is that a reasonable design from an OO point of view? Or should I create a
separate class to generate each file, with an interface to share data
between the different classes? If I go with separate classes for each file:
- would it be reasonable to do all the work of writing the file in the
constructor of that class?
- would it be reasonable to create a class called FileGenerator that simply
creates each file by invoking each classes constructor?

For instance, I can picture something like this:

public class FileGenerator implements GeneratorConstants {

public static void main(String[] args) {

new FileGenerator();
}

public FileGenerator() {

new File1(); //generate HTML file

new File2(); //generate ASCII file

new File3(); //generate PDF file
}
}

This approach is certainly nice and modular but is it good OO design?

Also, what about shared resources? Some of the files access the same
ResourceBundle to display the same data but in different file formats. For
example, the code that generates File1 reads from the resource bundle and
writes the information out in HTML format while File2 writes the same
information in ASCII, etc. Should FileGenerator get the desired
ResourceBundle and then pass it to the classes that need it via their
constructors? Or would it be better OO design to let each class get its own
ResourceBundle directly?

I've never had much exposure to OO design of any kind and even less to
design of batch programs so I'm really not sure how to think of these
things. Maybe my current design where all of the files are being generated
via separate methods in the same class is perfectly good; I just don't know.

If anyone could enlighten me, I'd appreciate it.
 
T

tiewknvc9

yes, good OO design would dictate that you should create seperate
classes for each file that you want to generate. However it really
doesn't make much of a difference if you're only using it as a batch
file. Unless you are creating dozens of files that are similar.

As a class what I would do is create an FileHTMLMaker class and send it
the
ResourceBundle as a constructor variable. But I suppose it all depends
on what you're doing with it.

Classes are meant to save you developing time by allowing you to only
have to program things once, and allow yourself to reuse it. So if you
wanted to create another HTML file based on another String or
ResourceBundle, then creating a fileHTMLMaker class makes sense.
 
S

Stefan Ram

Rhino said:
Is that a reasonable design from an OO point of view?

If the different generators share a lot of common code, one
might extract this to an abstract base class and prepare
derived classes with hook methods for each target language
(file type) according to the template method pattern.

.----------------------.
| «abstract class» |
| /Writer/ |
|----------------------|
|----------------------|
| /<hookMethods>/ |
| <templateMethods> |
'----------------------'
^
/_\
«extends» |
|
|
.----------------------------------+
| |
..-----------------------. .-----------------------.
| «class» | | «class» |
| HtmlWriter | | PdfWriter |
|-----------------------| |-----------------------|
|-----------------------| |-----------------------|
| <hookMethods> | | <hookMethods> |
'-----------------------' '-----------------------'

Otherwise, if there is no significant code duplication
and the code is easy to understand and to maintain,
there is no need to change it.
 
O

Oliver Wong

Rhino said:
I have a batch program that generates several flat files. The files being
generated are of various types, including HTML, ASCII, CSS, and PDF.

At the moment, each distinct file is generated in its own separate method.
The main of the class simply executes each method in turn. The different
methods share a small amount of data via class variables.

Is that a reasonable design from an OO point of view? Or should I create a
separate class to generate each file, with an interface to share data
between the different classes? If I go with separate classes for each
file:
- would it be reasonable to do all the work of writing the file in the
constructor of that class?
- would it be reasonable to create a class called FileGenerator that
simply creates each file by invoking each classes constructor?

For instance, I can picture something like this:

public class FileGenerator implements GeneratorConstants {

public static void main(String[] args) {

new FileGenerator();
}

public FileGenerator() {

new File1(); //generate HTML file

new File2(); //generate ASCII file

new File3(); //generate PDF file
}
}

This approach is certainly nice and modular but is it good OO design?

Also, what about shared resources? Some of the files access the same
ResourceBundle to display the same data but in different file formats. For
example, the code that generates File1 reads from the resource bundle and
writes the information out in HTML format while File2 writes the same
information in ASCII, etc. Should FileGenerator get the desired
ResourceBundle and then pass it to the classes that need it via their
constructors? Or would it be better OO design to let each class get its
own ResourceBundle directly?

I've never had much exposure to OO design of any kind and even less to
design of batch programs so I'm really not sure how to think of these
things. Maybe my current design where all of the files are being generated
via separate methods in the same class is perfectly good; I just don't
know.

If anyone could enlighten me, I'd appreciate it.

1) If it ain't broke, don't fix it. Your procedural code sounds fine the
way it is, and I'm not sure why you would want to change it.
2) Constructors with side effects (e.g. creating files) might not be
such a great idea; depends on the abstraction you're trying to create.
3) When you say some files display the same data, but in different file
formats, sounds like you could use the MVC pattern (except you don't have a
Control, only a Model and a View). See http://ootips.org/mvc-pattern.html

- Oliver
 
R

Rhino

tiewknvc9 said:
yes, good OO design would dictate that you should create seperate
classes for each file that you want to generate.

Good, at least I reasoned that out correctly :)
However it really
doesn't make much of a difference if you're only using it as a batch
file. Unless you are creating dozens of files that are similar.
I'm generating three HTML files, two CSS files, two PDFs and one ASCII file.
But the HTML files don't resemble each other in content aside from very
similar code in the <head> area. The CSS files don't resemble each other
very much in content. The PDFs don't resemble each other in content at all.

I'm not sure if the similarity of format and some overlapping content is
enough to justify making a class to generate HTML when the content has only
As a class what I would do is create an FileHTMLMaker class and send it
the
ResourceBundle as a constructor variable. But I suppose it all depends
on what you're doing with it.

Classes are meant to save you developing time by allowing you to only
have to program things once, and allow yourself to reuse it. So if you
wanted to create another HTML file based on another String or
ResourceBundle, then creating a fileHTMLMaker class makes sense.
I wonder if I should be basing the class on content rather than file
format??

One of the HTML files, the ASCII file, and one of the PDFs are basically the
same information (a resume) expressed in different formats. Should I make a
ResumeGenerator class to create all three of those files? Or would it be bad
design to have a single class generating three differently-formatted files
of the same information? (The remaining files would presumably be generated
via their own distinct classes.)

Also, with respect to the FileGenerator class I described in my question,
should that be a class at all? Or should I simply implement a batch script
that executes each of the file generating classes as standalone programs?

I'm not sure if the FileGenerator class should exist at all if its only
function is to instantiate the different classes that actually generate the
files; an Ant script would initiate those classes just as well. Of course,
the shared resources issue muddies the water a bit: having FileGenerator get
that ResourceBundle and pass it to the classes lets the FileGenerator bring
something unique to the table that couldn't easily be accomplished by an Ant
script.

Also, I'm still uneasy about the structure of the individual file generating
classes, such as class ResumeAscii. If these classes consist only of a
constructor that does all the work and these classes are only invoked via
'new ResumeAscii()' in the FileGenerator class, it all seems a bit weird
since the object, an instance of ResumeAscii, never really gets used. Would
it make more sense to make ResumeAscii a class that has a single method in
it that does all of the work of writing the file?

Something like this perhaps:

----------------------------------------
public class ResumeAscii {

public static writeResume() {

}
}
----------------------------------------

Then, in FileGenerator, have this:

----------------------------------------
ResumeAscii.writeResume();
----------------------------------------

It just seems odd to have ResumeAscii look like this:

----------------------------------------
public class ResumeAscii {

public ResumeAscii() {

//create writer
//write lines
//close writer

}
}
----------------------------------------

and be invoked like this:
----------------------------------------
new ResumeAscii();
----------------------------------------
when no ResumeAscii is actually instantiated or used [as would be the case
if I did:
ResumeAscii myResumeAscii = new ResumeAscii();]

Or am I just thinking about this the wrong way?

Rhino
 
R

Rhino

Stefan Ram said:
If the different generators share a lot of common code, one
might extract this to an abstract base class and prepare
derived classes with hook methods for each target language
(file type) according to the template method pattern.

.----------------------.
| «abstract class» |
| /Writer/ |
|----------------------|
|----------------------|
| /<hookMethods>/ |
| <templateMethods> |
'----------------------'
^
/_\
«extends» |
|
|
.----------------------------------+
| |
.-----------------------. .-----------------------.
| «class» | | «class» |
| HtmlWriter | | PdfWriter |
|-----------------------| |-----------------------|
|-----------------------| |-----------------------|
| <hookMethods> | | <hookMethods> |
'-----------------------' '-----------------------'

Otherwise, if there is no significant code duplication
and the code is easy to understand and to maintain,
there is no need to change it.

See my reply to 'tiewknvc9' for more information about what I'm doing.

I'm really not sure if my level of duplication justifies creating abstract
classes; I rather suspect not. Phrases like "_signficant_ code duplication"
are always rather subjective; some people would say two common lines of code
is enough to justify making a new class while others would not see enough
commonality unless there were dozens or hundreds of lines of code common to
the classes.

I understand the benefits of having the abstract class in general; I'm just
not sure if it's worth doing in my case.

What do you think, based on what you've heard (and seen in my reply to
'tiewknvc9')?

I guess I'm looking for a rule of thumb to help me decide if I have enough
commonality between the different file generators to justify making an
abstract class.

Also, could you possibly define the concepts "hookMethods" and
"templateMethods" for me? I have a vague idea what you might mean but a
little more detail would be very helpful.

Rhino
 
S

Stefan Ram

Rhino said:
What do you think, based on what you've heard (and seen in my
reply to 'tiewknvc9')?

Eventually, it depends on what you want to optimize. For
example, if you want to optimize you income, you might ask:
Could I make more money by spending the time for another
project instead? Or, if you would want to optimize your
health, you might compare the effects on your health of time
spent on optimizing this code with the same amount of time
relaxing yourself. Or you might want to optimize a functional
like "0.34 · fun + 0.33 · profit + 0.33 · health".
I guess I'm looking for a rule of thumb to help me decide if I
have enough commonality between the different file generators
to justify making an abstract class.

If this is the only project, the time saved by making future
maintenance easier should outweigh the effort spend to
refactor the code now - using the best current estimate of the
likelihood of future need to maintain that code and the amount
of maintenance expected.

If there are also other projects, one might also compare
whether time spent on another project might save more time or
generate more income than the refactorization of this project.
Also, could you possibly define the concepts "hookMethods" and
"templateMethods" for me? I have a vague idea what you might
mean but a little more detail would be very helpful.

Say, now there is:

public void dumpListAscii()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( "-" + s + "\n" ); }}

public void dumpListHtml()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( "<li>" + s + "</li>" ); }}

This might be refactored to the abstract base class

public abstract class Lister
{
public void dump()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( this.entry( s )); }}

protected java.lang.String entry
( final java.lang.String text );
/* ... */ }

Therein, "dump" is the template method and "entry"
is the "hook method". Then the concrete classes
specify different hook methods:

public class AsciiLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "-" + text + "\n"; }}

public class HtmlLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "<li>" + text + "</li>"; }}

This, was somewhat simplified; and I have not tested the code,
but it might suffice to grasp these notions.

One sees that factoring out the common code also creates new
overhead, so another natural measure for the threshold to do
this might be that the reduction in duplication of code must
outweighs the overhead added.
 
S

Stefan Ram

This might be refactored to the abstract base class
public abstract class Lister
{ public void dump()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( this.entry( s )); }}
protected java.lang.String entry
( final java.lang.String text ); }
public class AsciiLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "-" + text + "\n"; }}
public class HtmlLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "<li>" + text + "</li>"; }}

When I wrote this, I was already wondering, why I never used
this (I never ever declared an abstract class in production
code).

In fact, I'd rather use independent classes and interfaces
than inheritance and abstract classes, so:

public interface Language
{ java.lang.String entry( java.lang.String text ); }

public class Lister
{ public Lister( final Language l ){ this.l = l; }
public void dump()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( this.l.entry( s )); }}
/* ... */ }

public class Ascii implements Language
{ public java.lang.String entry
( final java.lang.String text )
{ return "-" + text + "\n"; }}

public class Html implements Language
{ public java.lang.String entry
( final java.lang.String text )
{ return "<li>" + text + "</li>"; }}
 
R

Rhino

Oliver Wong said:
Rhino said:
I have a batch program that generates several flat files. The files being
generated are of various types, including HTML, ASCII, CSS, and PDF.

At the moment, each distinct file is generated in its own separate
method. The main of the class simply executes each method in turn. The
different methods share a small amount of data via class variables.

Is that a reasonable design from an OO point of view? Or should I create
a separate class to generate each file, with an interface to share data
between the different classes? If I go with separate classes for each
file:
- would it be reasonable to do all the work of writing the file in the
constructor of that class?
- would it be reasonable to create a class called FileGenerator that
simply creates each file by invoking each classes constructor?

For instance, I can picture something like this:

public class FileGenerator implements GeneratorConstants {

public static void main(String[] args) {

new FileGenerator();
}

public FileGenerator() {

new File1(); //generate HTML file

new File2(); //generate ASCII file

new File3(); //generate PDF file
}
}

This approach is certainly nice and modular but is it good OO design?

Also, what about shared resources? Some of the files access the same
ResourceBundle to display the same data but in different file formats.
For example, the code that generates File1 reads from the resource bundle
and writes the information out in HTML format while File2 writes the same
information in ASCII, etc. Should FileGenerator get the desired
ResourceBundle and then pass it to the classes that need it via their
constructors? Or would it be better OO design to let each class get its
own ResourceBundle directly?

I've never had much exposure to OO design of any kind and even less to
design of batch programs so I'm really not sure how to think of these
things. Maybe my current design where all of the files are being
generated via separate methods in the same class is perfectly good; I
just don't know.

If anyone could enlighten me, I'd appreciate it.

1) If it ain't broke, don't fix it. Your procedural code sounds fine
the way it is, and I'm not sure why you would want to change it.

Well, I'm not sure I _should_ change it, which is why I was asking in the
first place :) Maybe I've been reading too many OO-oriented discussions but
I was nervous that one big class doing a bunch of different things was Very
Bad, even if the individual methods were very simple code without a single
if in them.
2) Constructors with side effects (e.g. creating files) might not be
such a great idea; depends on the abstraction you're trying to create.

I'm not sure if I'm trying to create an abstraction at all! :) I was just
curious whether people who were experienced OO designers would look
favourably on a single class that produced several different files, with
each file produced by a method that was moderately lengthy but didn't
branch. I had a mental picture of people recoiling in horror that the code
wasn't refactored to break it into smaller classes. But maybe that sort of
thinking doesn't apply for the situation I'm describing.

Basically, I want to be able to show my code, including this class, to an
OO-savvy prospective employer and be satisfied that he will not think me a
completely untrainable buffoon with no concept of OO design.
3) When you say some files display the same data, but in different file
formats, sounds like you could use the MVC pattern (except you don't have
a Control, only a Model and a View). See
http://ootips.org/mvc-pattern.html
I'll have a look at that tomorrow.

Right now, I've got to go feed my cats before they start eating _me_. ;-)

Rhino
 
R

Rhino

Stefan Ram said:
Eventually, it depends on what you want to optimize. For
example, if you want to optimize you income, you might ask:
Could I make more money by spending the time for another
project instead? Or, if you would want to optimize your
health, you might compare the effects on your health of time
spent on optimizing this code with the same amount of time
relaxing yourself. Or you might want to optimize a functional
like "0.34 · fun + 0.33 · profit + 0.33 · health".


If this is the only project, the time saved by making future
maintenance easier should outweigh the effort spend to
refactor the code now - using the best current estimate of the
likelihood of future need to maintain that code and the amount
of maintenance expected.

If there are also other projects, one might also compare
whether time spent on another project might save more time or
generate more income than the refactorization of this project.
Fair enough; I see how the reasoning goes.
Say, now there is:

public void dumpListAscii()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( "-" + s + "\n" ); }}

public void dumpListHtml()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( "<li>" + s + "</li>" ); }}

This might be refactored to the abstract base class

public abstract class Lister
{
public void dump()
{ foreach( final java.lang.String s : list )
{ java.lang.System.out.println( this.entry( s )); }}

protected java.lang.String entry
( final java.lang.String text );
/* ... */ }

Therein, "dump" is the template method and "entry"
is the "hook method". Then the concrete classes
specify different hook methods:

public class AsciiLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "-" + text + "\n"; }}

public class HtmlLister extends Lister
{ protected java.lang.String entry
( final java.lang.String text )
{ return "<li>" + text + "</li>"; }}

This, was somewhat simplified; and I have not tested the code,
but it might suffice to grasp these notions.

One sees that factoring out the common code also creates new
overhead, so another natural measure for the threshold to do
this might be that the reduction in duplication of code must
outweighs the overhead added.
I'm going to think about this for a while. I'll post back tomorrow if I have
any followup questions. With any luck, you'll be able to clarify if that
happens.

Rhino
 
A

Andrew McDonagh

Rhino said:
I have a batch program that generates several flat files. The files being
generated are of various types, including HTML, ASCII, CSS, and PDF.

At the moment, each distinct file is generated in its own separate
method. The main of the class simply executes each method in turn. The
different methods share a small amount of data via class variables.

Is that a reasonable design from an OO point of view? Or should I create
a separate class to generate each file, with an interface to share data
between the different classes? If I go with separate classes for each
file:
- would it be reasonable to do all the work of writing the file in the
constructor of that class?
- would it be reasonable to create a class called FileGenerator that
simply creates each file by invoking each classes constructor?

For instance, I can picture something like this:

public class FileGenerator implements GeneratorConstants {

public static void main(String[] args) {

new FileGenerator();
}

public FileGenerator() {

new File1(); //generate HTML file

new File2(); //generate ASCII file

new File3(); //generate PDF file
}
}

This approach is certainly nice and modular but is it good OO design?

Also, what about shared resources? Some of the files access the same
ResourceBundle to display the same data but in different file formats.
For example, the code that generates File1 reads from the resource bundle
and writes the information out in HTML format while File2 writes the same
information in ASCII, etc. Should FileGenerator get the desired
ResourceBundle and then pass it to the classes that need it via their
constructors? Or would it be better OO design to let each class get its
own ResourceBundle directly?

I've never had much exposure to OO design of any kind and even less to
design of batch programs so I'm really not sure how to think of these
things. Maybe my current design where all of the files are being
generated via separate methods in the same class is perfectly good; I
just don't know.

If anyone could enlighten me, I'd appreciate it.

1) If it ain't broke, don't fix it. Your procedural code sounds fine
the way it is, and I'm not sure why you would want to change it.

cause its procedural - (besides Java being an OO language), we get most
out of it if we develop in OO.
Well, I'm not sure I _should_ change it, which is why I was asking in the
first place :) Maybe I've been reading too many OO-oriented discussions but
I was nervous that one big class doing a bunch of different things was Very
Bad, even if the individual methods were very simple code without a single
if in them.

You are right too be nervous...
I'm not sure if I'm trying to create an abstraction at all! :) I was just
curious whether people who were experienced OO designers would look
favourably on a single class that produced several different files, with
each file produced by a method that was moderately lengthy but didn't
branch. I had a mental picture of people recoiling in horror that the code
wasn't refactored to break it into smaller classes. But maybe that sort of
thinking doesn't apply for the situation I'm describing.

Basically, I want to be able to show my code, including this class, to an
OO-savvy prospective employer and be satisfied that he will not think me a
completely untrainable buffoon with no concept of OO design.

In that case, this isn't a good example of your 'skill'

Google the following principles... 'Single Responsibility Principle',
'Law Of Demeter', 'Dependency Inversion', 'Dependency Injection'

Then look at the design patterns (GoF, etc).

The problem space you describe above could be solved in many OO ways...


Builder Pattern
Dispatcher & Strategy objects
Dispatcher & Command Objects.
etc.


MVC is not right for this....if all we have is a hammer, is everything a
nail?
I'll have a look at that tomorrow.

Right now, I've got to go feed my cats before they start eating _me_. ;-)

Rhino

Andrew
 
C

Chris Uppal

Rhino said:
Basically, I want to be able to show my code, including this class, to an
OO-savvy prospective employer and be satisfied that he will not think me a
completely untrainable buffoon with no concept of OO design.

That changes the situation. The bottom line is that throw-away code is not
going to be a good advertisement for your skills. If you write sensible code
given what you are gong to use it for, then there will be nothing much there to
show that you are capable of structuring code differently when the situation
calls for it. OTOH, if you structure your code /as if/ it were going to be an
important part of a long-lived system where many changes to requirements can be
anticipated, then you are going to look as if you have an ingrained tendency to
over-engineer everything.

You /might/ be able to explain that you had deliberately over-engineered the
code just for fun and as a design exercise. And I would certainly rather try
to persuade an interviewer of that, than to explain that the reason I was
showing crappy, simplistic, code was that I wanted to show that I was capable
of evaluating the need for "clever" design on a case-by-case basis ;-)
Alternatively, you could present the code as extracted from a larger system (it
would help if that were true, of course), which called for more structure than
was actually needed for this "trivial" application.

As for the design, if I were doing this (and assuming I decided to push the
boat out on the design front[*]), I would probably split the responsibilities
differently. I would have a DocumentWriter role, and a Resume role. Objects
that were DocumentWriter would know how to write formatted text onto an
OutputStream. The would have methods like setPageHeader(String),
setPageFooter(String), writeParagraph(String), and so on. There would be
specific classes that implemented DocumentWriter by emitting HTML, PDF, ASCII,
"Rich Text", and so on. The main job of Resumes would be to hold the data
defining a resume, one specific ability that they would have would be to dump
that data to a DocumentWriter. So they would have a method roughly like:

void
writeTo(DocumentWriter writer)
{
writer.setPageHeader("My CV");
writer.setPageFooter(... today's date ...);
for (String paragraph : m_paragraphs)
writer.writeParagraph(paragraph);
}

The main program would instantiate a Resume (getting the data from a file or
something), and a DocumentWriter of the desired type, tell the Resume to dump
itself to the DocumentWriter, and then clean up.

Elaborate as desired...

-- chris

([*] which I almost certainly would do -- I find it easier to think in terms of
suitable abstractions even for throwaway code. For some suitable definition of
"suitable" ;-)
 
O

Oliver Wong

Andrew McDonagh said:
cause its procedural - (besides Java being an OO language), we get most
out of it if we develop in OO.

My point is that given the description of the problem (batch job
generating flat files), an OO approach might not be appropriate at all. Java
was designed with OO in mind, but that does not stop us from using Java to
write procedural code.

I don't know Rhino's exact requirements, but in general, the situation
he's in (again, batch job generating flat files) sounds like it would be
expressed more naturally with procedural code than object oriented code.

OO's main strength is reusability, but it sounds like Rhino is not
concerned about reusability with respect to this project (it is referred to
as "throw away" code elsewhere in this thread)

Procedural's main strength is batch processing, and that is exactly how
this project is described.

Draw your own conclusions from that.
The problem space you describe above could be solved in many OO ways...


Builder Pattern
Dispatcher & Strategy objects
Dispatcher & Command Objects.
etc.



MVC is not right for this....if all we have is a hammer, is everything a
nail?

You, who is recommending OO for a batch process, is telling me to use
the right tool for the right job? =P

I'm not familiar with your "dispatcher" design pattern (google and
wikipedia seem to turn up nothing), but I believe MV[C] is a better fit than
Builder.

I'm assuming when you say "builder", you intend to have one abstract
builder class (or interface), and then several concrete builders, such as
HtmlBuilder, AsciiBuilder, PdfBuilder, and so on.

Then, having these multiple instances, you would give instruct them how
to build their respective documents. E.g. setTitle("myResume");,
setContent("blablabla");, etc.

Finally, you would instruct the builder to actually "build" the
document, and then save what gets generated to a file.

With Model-View, you'd create a model object representing the document
to be generated, and pass it to a HtmlView, an AsciiView and a PdfView, each
one taking care of generating the file in the appropriate file format.

There's a conceptual advantage to Model-View, in that methods like
setTitle() should really be on the model, and not on the builder. That is,
you're setting the title of the resume, and not of the thing that is
building the resume.

There's also a slight performance advantage to Model-View: Since these
are documents we are working with, there's a good chance that the "content"
part of the document may be very large (possibly several megabytes). With
Model-View, you store the content once in the Model object, and re-use it
across all the views.

With builders, you have to build the content in each builder, tripling
your work in the case where you have 3 file formats you want to output to.

In the end, comprehension beats performance, so if Rhino really feels
builder is easier to understand than MV, then he should go with builder.
Likewise, if he feels MV is easier to understand than builder (which is the
case for me), he should go with MV.

- Oliver
 
R

Rhino

Andrew McDonagh said:
Rhino said:
I have a batch program that generates several flat files. The files
being generated are of various types, including HTML, ASCII, CSS, and
PDF.

At the moment, each distinct file is generated in its own separate
method. The main of the class simply executes each method in turn. The
different methods share a small amount of data via class variables.

Is that a reasonable design from an OO point of view? Or should I create
a separate class to generate each file, with an interface to share data
between the different classes? If I go with separate classes for each
file:
- would it be reasonable to do all the work of writing the file in the
constructor of that class?
- would it be reasonable to create a class called FileGenerator that
simply creates each file by invoking each classes constructor?

For instance, I can picture something like this:

public class FileGenerator implements GeneratorConstants {

public static void main(String[] args) {

new FileGenerator();
}

public FileGenerator() {

new File1(); //generate HTML file

new File2(); //generate ASCII file

new File3(); //generate PDF file
}
}

This approach is certainly nice and modular but is it good OO design?

Also, what about shared resources? Some of the files access the same
ResourceBundle to display the same data but in different file formats.
For example, the code that generates File1 reads from the resource
bundle and writes the information out in HTML format while File2 writes
the same information in ASCII, etc. Should FileGenerator get the desired
ResourceBundle and then pass it to the classes that need it via their
constructors? Or would it be better OO design to let each class get its
own ResourceBundle directly?

I've never had much exposure to OO design of any kind and even less to
design of batch programs so I'm really not sure how to think of these
things. Maybe my current design where all of the files are being
generated via separate methods in the same class is perfectly good; I
just don't know.

If anyone could enlighten me, I'd appreciate it.


1) If it ain't broke, don't fix it. Your procedural code sounds fine
the way it is, and I'm not sure why you would want to change it.

cause its procedural - (besides Java being an OO language), we get most
out of it if we develop in OO.
Well, I'm not sure I _should_ change it, which is why I was asking in the
first place :) Maybe I've been reading too many OO-oriented discussions
but I was nervous that one big class doing a bunch of different things
was Very Bad, even if the individual methods were very simple code
without a single if in them.

You are right too be nervous...
I'm not sure if I'm trying to create an abstraction at all! :) I was
just curious whether people who were experienced OO designers would look
favourably on a single class that produced several different files, with
each file produced by a method that was moderately lengthy but didn't
branch. I had a mental picture of people recoiling in horror that the
code wasn't refactored to break it into smaller classes. But maybe that
sort of thinking doesn't apply for the situation I'm describing.

Basically, I want to be able to show my code, including this class, to an
OO-savvy prospective employer and be satisfied that he will not think me
a completely untrainable buffoon with no concept of OO design.

In that case, this isn't a good example of your 'skill'

Google the following principles... 'Single Responsibility Principle', 'Law
Of Demeter', 'Dependency Inversion', 'Dependency Injection'

Then look at the design patterns (GoF, etc).

The problem space you describe above could be solved in many OO ways...


Builder Pattern
Dispatcher & Strategy objects
Dispatcher & Command Objects.
etc.


MVC is not right for this....if all we have is a hammer, is everything a
nail?
Okay, I've begun reading the articles you have suggested but it's going to
take a bit of time to digest it all and figure out how to apply the theory
that is expostulated in the articles.

I'm very glad you pointed me to these sources; I've been writing Java for
several years but I know I have not been paying sufficient attention to OO
design principles, mostly because I don't really know them. My Java code
tends to be too procedural, based on my background in structured
analysis/design/programming.

I've been needing to get off my ass and pick up the theory for a long time.
I think I've really hit the point where I can't procrastinate any more.

With that in mind, can you (or anyone else) suggest a good way to learn OO
Design?

The only book I have on the subject is "Object-Oriented Modeling and
Design", which I'll call OOM&D from now on, by Rumbaugh, Blaha, Premerlani,
Eddy and Lorensen, published in 1991. It mentions the Law of Demeter but not
Single Responsibility Principle, Dependency Inversion, Dependency Injection
or design patterns. [However, I have a link to a Java Design Patterns book
which I use occasionally at
http://www.patterndepot.com/put/8/JavaPatterns.htm so maybe that's good
enough for my purposes.] Perhaps I need one or more newer books to replace
OOM&D with something more current? I'm also someone who thrives on good
examples and does poorly when concepts are explained with only vague
generalities.

If anyone can recommend a book or books, or online tutorials, or newsgroups
or other resources that will help me learn OO Design, preferably quickly,
thoroughly and inexpensively, I would love to hear from you. I'd be
especially interested in resources that give you some way of getting
specific questions answered; it's very hard to ask a book a question when
something isn't clear :)

Rhino
 
R

Rhino

Chris Uppal said:
That changes the situation. The bottom line is that throw-away code is
not
going to be a good advertisement for your skills. If you write sensible
code
given what you are gong to use it for, then there will be nothing much
there to
show that you are capable of structuring code differently when the
situation
calls for it. OTOH, if you structure your code /as if/ it were going to
be an
important part of a long-lived system where many changes to requirements
can be
anticipated, then you are going to look as if you have an ingrained
tendency to
over-engineer everything.
Exactly!

You /might/ be able to explain that you had deliberately over-engineered
the
code just for fun and as a design exercise. And I would certainly rather
try
to persuade an interviewer of that, than to explain that the reason I was
showing crappy, simplistic, code was that I wanted to show that I was
capable
of evaluating the need for "clever" design on a case-by-case basis ;-)
Alternatively, you could present the code as extracted from a larger
system (it
would help if that were true, of course), which called for more structure
than
was actually needed for this "trivial" application.
They say great minds think alike; we're certainly "on the same page" in this
case :)

But the main thing is that I don't want to lie. I have no intention of
passing myself off as an OO Design expert. Frankly, I'd come off as an utter
fraud if I tried, unless the interviewer were a complete imbecile. I have no
intention of mentioning any OO Design skills on my resume until I feel I
have gotten a solid grasp on the those principles.

So maybe my best bet is to leave the program in its old procedural form. It
demonstrates at least some competence in writing Java - the program works
just fine - and leave it at that. In addition, I fully understand the code
since I wrote it. If I put together a quasi-OO version of the program that I
only half-understand, I could easily crash and burn if someone asked me why
I did such-and-such. That would do more harm than good. It would be better
for me to emphasize that I want to work for the employer so that I can learn
more about good OO Design from my competent colleagues than it would be to
claim that I already know OO Design inside out. That is actually a major
motivation for me wanting to work for someone else; I've been puttering
around essentially on my own and haven't had the benefits of peers to
discuss these issues with.

Of course the downside of this approach is that an employer might reject me
on the grounds that I should know OO Design backwards and forwards to
qualify for the job. But the reality is that I can't delay job hunting for
another six months or whatever while I master OO Design. Still, I don't
think I could fake a mastery of OO Design so I just have to tell the truth
and make it as palatable as I can....

When I've succeeded in properly learning OO Design principles, I can revise
my example programs to fit those principles better _and_ change my resume to
claim some competence in OO Design at the same time. That should be helpful
when I look for the next job.
As for the design, if I were doing this (and assuming I decided to push
the
boat out on the design front[*]), I would probably split the
responsibilities
differently. I would have a DocumentWriter role, and a Resume role.
Objects
that were DocumentWriter would know how to write formatted text onto an
OutputStream. The would have methods like setPageHeader(String),
setPageFooter(String), writeParagraph(String), and so on. There would be
specific classes that implemented DocumentWriter by emitting HTML, PDF,
ASCII,
"Rich Text", and so on. The main job of Resumes would be to hold the data
defining a resume, one specific ability that they would have would be to
dump
that data to a DocumentWriter. So they would have a method roughly like:

void
writeTo(DocumentWriter writer)
{
writer.setPageHeader("My CV");
writer.setPageFooter(... today's date ...);
for (String paragraph : m_paragraphs)
writer.writeParagraph(paragraph);
}

The main program would instantiate a Resume (getting the data from a file
or
something), and a DocumentWriter of the desired type, tell the Resume to
dump
itself to the DocumentWriter, and then clean up.

Elaborate as desired...
Yeah, I was thinking along those same lines as I've read the replies to my
post and investigated some of the suggestions I got.
-- chris

([*] which I almost certainly would do -- I find it easier to think in
terms of
suitable abstractions even for throwaway code. For some suitable
definition of
"suitable" ;-)
I need to get in that habit :) I find myself doing it more and more as I
learn more about OO design but it isn't automatic to do it that way yet.

Rhino
 
O

Oliver Wong

Rhino said:
I've been needing to get off my ass and pick up the theory for a long
time. I think I've really hit the point where I can't procrastinate any
more.

With that in mind, can you (or anyone else) suggest a good way to learn OO
Design?

I've found the book "Head First Design Patterns" to be excellent:

http://www.amazon.com/gp/product/05...103-5047137-3618220?n=507846&s=books&v=glance

However, when I had read it, I was already fairly comfortable with OO
design, and somewhat comfortable with design patterns (I wanted to just
solidify my understanding of the latter). This book is certainly appropriate
if you know OO but have no previous exposure to design patterns. I'm not so
sure if it's adequate for someone with little to no OO experience.

There is a "Head First Java 2" book in the same series, but I haven't
actually read it, so I can't comment much on it.
If anyone can recommend a book or books, or online tutorials, or
newsgroups or other resources that will help me learn OO Design,
preferably quickly, thoroughly and inexpensively, I would love to hear
from you. I'd be especially interested in resources that give you some way
of getting specific questions answered; it's very hard to ask a book a
question when something isn't clear :)

I recommend comp.lang.java.help and comp.lang.java.programmer.

- Oliver
 
A

Andrew McDonagh

Oliver said:
I've found the book "Head First Design Patterns" to be excellent:

http://www.amazon.com/gp/product/05...103-5047137-3618220?n=507846&s=books&v=glance

However, when I had read it, I was already fairly comfortable with OO
design, and somewhat comfortable with design patterns (I wanted to just
solidify my understanding of the latter). This book is certainly appropriate
if you know OO but have no previous exposure to design patterns. I'm not so
sure if it's adequate for someone with little to no OO experience.

There is a "Head First Java 2" book in the same series, but I haven't
actually read it, so I can't comment much on it.




I recommend comp.lang.java.help and comp.lang.java.programmer.

- Oliver


and comp.object.....
 
C

Chris Uppal

Rhino said:
The only book I have on the subject is "Object-Oriented Modeling and
Design", which I'll call OOM&D from now on, by Rumbaugh, Blaha,
Premerlani, Eddy and Lorensen, published in 1991. It mentions the Law of
Demeter but not Single Responsibility Principle, Dependency Inversion,
Dependency Injection or design patterns. [However, I have a link to a
Java Design Patterns book which I use occasionally at
http://www.patterndepot.com/put/8/JavaPatterns.htm so maybe that's good
enough for my purposes.] Perhaps I need one or more newer books to replace
OOM&D with something more current? I'm also someone who thrives on good
examples and does poorly when concepts are explained with only vague
generalities.

Offhand I can't see much relevance in Dependency Inversion, Dependency
Injection, or the Design Patterns that Andrew mentioned, unless the aim of the
project is to /force/ objects into the program whether they are needed or not.
That's to say that I can't see a valid breakdown of the roles involved that
produces any of those patterns. My reply to Oliver has some more discussion of
what I see as potential objects.

If anyone can recommend a book or books [...]

I have previously recommended:

Object Design
Roles, Responsibilities, and Collaborations
Rebacca Wirfs-Brock and Alan McKean

It may even have been to you. If you can find that post (it was to this NG), I
have more comments there on a book I find refreshingly free from the rather too
ubiquitous head-up-own-arse syndrome[*]

-- chris

([*] for more on the HUOA syndrome see comp.object -- sorry, Andrew ! ;-).
 
A

Andrew McDonagh

Chris said:
Rhino wrote:

The only book I have on the subject is "Object-Oriented Modeling and
snip
generalities.


Offhand I can't see much relevance in Dependency Inversion, Dependency
Injection, or the Design Patterns that Andrew mentioned, unless the aim of the
project is to /force/ objects into the program whether they are needed or not.
That's to say that I can't see a valid breakdown of the roles involved that
produces any of those patterns. My reply to Oliver has some more discussion of
what I see as potential objects.


snip

-- chris

([*] for more on the HUOA syndrome see comp.object -- sorry, Andrew ! ;-).


Cause you are ;)

I mentioned them, because I understood the OPs real aim to be to learn
more about OO, rather than solve the 'mickey mouse' problem that was
described.

That being said, if I was to design and implement a solution to his
problem, it would be done using TestDrivenDevelopment, which usually
results in the use of one or more of those principles/patterns.

as for HUOA, that phrase is usually used by those who don't know better
- poor buggers

Andrew
 
C

Chris Uppal

Rhino said:
It would be better for me to emphasize that I want to work for the
employer so that I can learn more about good OO Design from my competent
colleagues than it would be to claim that I already know OO Design inside
out. That is actually a major motivation for me wanting to work for
someone else; [...]

I would like to say that any good employer would see that as a positive reason
to hire you (unless, of course, they specifically need someone who is OO-savvy
from day 1 -- which might be the case). I don't know how common "good"
employers are in your part of the world, though. My own experience (in the UK)
has been fairly positive, but then I've always been picky...

When I've succeeded in properly learning OO Design principles, I can
revise my example programs to fit those principles better _and_ change my
resume to claim some competence in OO Design at the same time. That
should be helpful when I look for the next job.

One point. You won't gain fluency in using objects by reading books -- or even
newsgroup postings ;-) You can only become practised in OO by /practicing/.
You have to read and write OO programs. So putting off re-writing your own
stuff until after you have done some OO is missing a chance to get some
practise in. For instance we have discussed a few different ways of OO-ing
your resume generator in response to different (hypothetical) pressures. You
could try producing different resume-generators along the lines we've
discussed. You could also try any other ideas that occur to you. Perhaps some
of them would turn out to be mistakes, but so what ? You don't have to show
them to anybody (a significant advantage over practising on "real" work ;-)
Objects tend to emerge as the external constraints change, so what would your
design look like if, say, you decided that you would /never/ generate anything
except PDF documents ? Or if you had to get the raw resume data from one of
several different sources ? Or if the output had to go to somewhere other than
a file ? Or if the output should be sent to a Swing window ? Or if you wanted
to create new Views via a GUI ? Or if the formatted data had to be embedded as
only /part/ of the complete output stream ? Where you need flexibility, there
you'll find objects. (Not that flexibility and change are the only reasons to
look for objects -- there's comprehensibility too.)

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top