Java Forum / General / December 2005
OO Design question about batch job
Rhino - 21 Dec 2005 18:50 GMT 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.
 Signature Rhino
tiewknvc9 - 21 Dec 2005 19:20 GMT 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.
Rhino - 21 Dec 2005 21:36 GMT > 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 a few lines of <head> in common. Ditto for the CSS and PDF files which have even less content in common.
> As a class what I would do is create an FileHTMLMaker class and send it > the [quoted text clipped - 5 lines] > 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
Stefan Ram - 21 Dec 2005 19:24 GMT >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.
Rhino - 21 Dec 2005 21:44 GMT >>Is that a reasonable design from an OO point of view? > [quoted text clipped - 29 lines] > 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
Stefan Ram - 21 Dec 2005 22:44 GMT >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.
Stefan Ram - 21 Dec 2005 22:57 GMT >This might be refactored to the abstract base class >public abstract class Lister [quoted text clipped - 11 lines] > ( 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>"; }}
Rhino - 22 Dec 2005 00:52 GMT >>What do you think, based on what you've heard (and seen in my >>reply to 'tiewknvc9')? [quoted text clipped - 21 lines] > 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.
>>Also, could you possibly define the concepts "hookMethods" and >>"templateMethods" for me? I have a vague idea what you might [quoted text clipped - 43 lines] > 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
Oliver Wong - 21 Dec 2005 21:33 GMT >I have a batch program that generates several flat files. The files being >generated are of various types, including HTML, ASCII, CSS, and PDF. [quoted text clipped - 49 lines] > > 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
Rhino - 22 Dec 2005 00:50 GMT >>I have a batch program that generates several flat files. The files being >>generated are of various types, including HTML, ASCII, CSS, and PDF. [quoted text clipped - 52 lines] > 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
Andrew McDonagh - 22 Dec 2005 01:26 GMT >>>I have a batch program that generates several flat files. The files being >>>generated are of various types, including HTML, ASCII, CSS, and PDF. [quoted text clipped - 52 lines] >> 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...
>> 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. [quoted text clipped - 10 lines] > 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.
>> 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 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
Oliver Wong - 22 Dec 2005 18:20 GMT >>> 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. 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... > [quoted text clipped - 10 lines] > 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
Chris Uppal - 23 Dec 2005 11:03 GMT > 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. I don't think there's anything in the distinction between batch and on-line[*] processing which makes one or the other more or less suited by an OO approach. I'd agree that there's less call for OO thinking to handle a very linear program flow (as Rhino described his program(s) to have). Perhaps that's what you meant ?
> OO's main strength is reusability [...] I wouldn't agree with that either ;-)
> 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. I think that is something of an abuse of the View concept. Views (as in MVC, and -- to a lesser degree -- as in database "views") are about individualised renderings of a model. I don't think that the binary/text format of a PDF file vs, say, a HTML file is a particularly fruitful application of that flexibility. It seems to me that the aim here is to produce the /same/ document in different formats. So the abstraction that is introduced to allow that flexibility is some sort of document writer, rather than a flavour of View.
To try to make that clearer. Consider an extension to Rhino's requirements where a View abstraction /would/ be fruitful. If we decide that now we want to have different versions of the CV (aka resume) for different purposes. A short version with no or limited contact information for posting to a website. A version with that three-year stretch for drug smuggling elided for submitting to government jobs ;-). And so on. That would be cause for introducing a View abstraction. Different Views would take a Resume object, and a DocumentWriter object, and extract a customised sub-set of the data from the Resume and send it, possibly with modifications, to the DocumentWriter. For instance one View might write out the description of each job that Rhino's had in chronological order, whereas another might choose to do it in reverse-chronological order[*]. Notice how the DocumentWriter abstraction is still needed. It is no part of a View's responsibility to know about HTML formatting or the PDF spec. The end result is that we can generate any view of Rhino's CV in any format. Which is nice ;-)
([*] This ability to re-order and/or reinterpret the data is what makes me prefer to call these things "views" rather than a mere "filters".)
Of course, for one of our Views to be able to function properly, the Resume object would have to have more structure than it has needed hitherto. Instead of being a simple collection of paragraphs, we would probably have to introduce more objects so that a view could ask for the various job descriptions and their durations. It might have to be able to distinguish between contact info and other text. And so on. All of which is more work, more complexity, and -- unless you are creating something like a job-search website, or support software for an employment agency -- almost certainly more work than could possibly be justified. Easier just to type the damned thing into Word(tm) and have done. Which is a sort of answer to Rhino's earlier question about a rule-of-thumb for when you are going over the top. If a design for something gets to the point where it seems easier just to do without it, then you've gone too far ;-)
-- chris
Andrew McDonagh - 23 Dec 2005 13:10 GMT >> 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 [quoted text clipped - 16 lines] > > I think that is something of an abuse of the View concept. snipped none too bad reasons ;)
for me the biggest reason MVC or even the more popular MVP pattern does fit the OPs problem space is how Oliver is proposing the lack of use of the controller (or presenter in MVP). A Model - View pattern degenerates into something little more than Observer or Publish Subscribe patterns (either the pull or push variants).
In which case the nearest I see is a strategy or command pattern usage - one command or strategy class for each type of file. The common code would then be in another class that makes use of those commands/strategies (i.e. the dispatcher)...
for Oliver's benefit...
a dispatchers with commands... http://www.industriallogic.com/xp/refactoring/conditionDispatcherWithCommand.html
strategies instead of conditional logic... http://www.industriallogic.com/xp/refactoring/conditionalWithStrategy.html
But this is just a gut feeling, like I said early...I'd let the design evolve using TDD....
happy holidays everyone...
Andrew
Oliver Wong - 23 Dec 2005 16:49 GMT > for me the biggest reason MVC or even the more popular MVP pattern does > fit the OPs problem space is how Oliver is proposing the lack of use of > the controller (or presenter in MVP). A Model - View pattern degenerates > into something little more than Observer or Publish Subscribe patterns > (either the pull or push variants). Yeah, MVC is like a fancier version of Observer; except it's specifically the benefits of Observer (dynamically changed models) which I think we are uninterested in for the problem we're trying to solve.
What I'm pushing is the M in MVC, really, the model. I think it would be a really good idea to have one single representation of the contents to be emitted which is indepedent of the file format that the content will be emitted in. Otherwise, as Chris suggested, the "View" should probably be thought more of as a "DocumentWriter". We don't have to worry about keeping the View "in sync" with the model, because it is unlikely that the model will change during runtime.
> In which case the nearest I see is a strategy or command pattern usage - > one command or strategy class for each type of file. The common code would [quoted text clipped - 8 lines] > strategies instead of conditional logic... > http://www.industriallogic.com/xp/refactoring/conditionalWithStrategy.html I'm familiar with the Command pattenr and the Strategy pattern. It's really the "Dispatcher with [foo]" that I've never heard of before, and it looks like these two pages only vaguely address the "dispatcher" part (in fact, it sounds like "dispatcher" is the "old" code that is being eliminated in the refactoring effort).
As for Command, it seems to me that there are only two possibilies: Either a single command object will generate the whole document, or it won't. In the former case, then it's just another name for the same set of classes as "Model-DocumentWriter"; in the latter case, you'd have to construct a sequence of command objects to incrementally build up the document, and the only benefit of this is that the command objects can act as "lego blocks" so you have a slightly higher level programming language to compose your document-building-logic with -- something I think will not be of much use to this problem.
As for "Strategy", I think again it's another name for the same set of classes.
- Oliver
Oliver Wong - 23 Dec 2005 16:40 GMT >> I don't know Rhino's exact requirements, but in general, the >> situation [quoted text clipped - 5 lines] > processing which makes one or the other more or less suited by an OO > approach. You forgot to put the footnote for the above, I think.
And as an aside, I always felt OO was not a good fit for online processing (the stateless HTML forms interface), but I haven't been able to find, or come up with, a better paradigm yet.
> I'd agree that there's less call for OO thinking to handle a very linear > program flow (as Rhino described his program(s) to have). Perhaps that's > what > you meant ? Yes.
>> With Model-View, you'd create a model object representing the >> document [quoted text clipped - 14 lines] > that flexibility is some sort of document writer, rather than a flavour of > View. "DocumentWriter" is probably a better name for the class than "View", but I believe that it's unlikely, for example, for the ASCII or PDF file format to change (HTML, to a lesser extent...), while it does seem perfectly reasonable to change the contents of the Model.
And I do believe that there may be significant differences in the structure or order in which the content might be processed for these different formats (I'm alluding to your example of re-ordering the data, which I've snipped and am too lazy to un-snip).
For example, say the resume layout that Rhino wishes to use has columns in it. I won't comment on PDF, because I don't know the details of its file format. With ASCII, you will probably want to process the data on a line by line basis, which means you may be reading the contents of multiple columns simultaneously (i.e. the first line of each of the 3 columns, then the second line of each of the 3 columns, etc.) HTML, on the other hand, will probably go cell-by-cell, if using a tables-based design, or might do column-by-column if using a table-less DIV/SPAN/CSS style design.
One of the advantages of MVC is that when the model is updated, all the views are updated. However, the model is not likely to be updated during the execution time of the program, so yes, this feature is "wasted", and so perhaps MVC is not a perfect fit.
Another way to look at the problem is that it is essentially the same as a re-targettable compiler. You have some source file, which you parse, and then load in memory in some intermediate format (what would be the Model in MVC). You then pass the model to document writers to output the "compiled binaries", e.g. in PDF, HTML or ASCII format.
- Oliver
Chris Uppal - 23 Dec 2005 19:42 GMT > > I don't think there's anything in the distinction between batch and > > on-line[*] > > processing which makes one or the other more or less suited by an OO > > approach. > > You forgot to put the footnote for the above, I think. I did. Nothing world-shaking. I had intended to include an explanation that I was using the term "on-line processing" in the wide sense where it just describes processing that doesn't expect to have all the data it needs available when it starts. Webservers, programs with GUIs, and many other kinds of program, are special cases of "on-line" (in that sense).
-- chris
Rhino - 22 Dec 2005 19:13 GMT >>>>I have a batch program that generates several flat files. The files >>>>being generated are of various types, including HTML, ASCII, CSS, and [quoted text clipped - 101 lines] > 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 a.s 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
Oliver Wong - 22 Dec 2005 20:53 GMT > I've been needing to get off my a.s 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/0596007124/qid=1135284563/sr=8-1/ref=pd_bbs_1/1 03-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
Andrew McDonagh - 22 Dec 2005 21:00 GMT >>I've been needing to get off my a.s and pick up the theory for a long >>time. I think I've really hit the point where I can't procrastinate any [quoted text clipped - 26 lines] > > - Oliver and comp.object.....
Chris Uppal - 23 Dec 2005 10:00 GMT > 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, [quoted text clipped - 7 lines] > 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 ! ;-).
Andrew McDonagh - 23 Dec 2005 10:22 GMT >>The only book I have on the subject is "Object-Oriented Modeling and snip
>>generalities. > [quoted text clipped - 4 lines] > 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
Chris Uppal - 23 Dec 2005 11:28 GMT > as for HUOA, that phrase is usually used by those who don't know better > - poor buggers I guess I asked for that ;-)
Cheers, and Happy Christmas !
-- chris
Andrew McDonagh - 23 Dec 2005 12:59 GMT >>as for HUOA, that phrase is usually used by those who don't know better >>- poor buggers [quoted text clipped - 4 lines] > > -- chris
:) merry Christmas and a happy new year!
Roedy Green - 23 Dec 2005 13:07 GMT On Fri, 23 Dec 2005 10:00:57 -0000, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
> Object Design > Roles, Responsibilities, and Collaborations > Rebacca Wirfs-Brock and Alan McKean for future reference that book is linked under "object oriented" in the Java glossary.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Andrew McDonagh - 23 Dec 2005 13:14 GMT > I have previously recommended: > > Object Design > Roles, Responsibilities, and Collaborations > Rebacca Wirfs-Brock and Alan McKean Object Thinking by Dave West is very good.
http://www.amazon.com/gp/product/0735619654/103-8850102-4225413?v=glance&n=283155
Chris Uppal - 23 Dec 2005 20:18 GMT > Object Thinking by Dave West is very good. http://www.amazon.com/gp/product/0735619654/103-8850102-4225413?v=glance&n=283155
I like it myself, in fact I like it a lot, but with some big reservations.
The central message -- objects are central -- is something I agree with entirely.
I'm not too happy with the way he tends to lump "object thinking" and Extreme Programming together, which is unwise (IMO) and unjustified. Also, he tends to use words in rather odd ways which can only be decoded if you understand both the view he is attempting to promote /and/ the view(s) that he is reacting against[*] which makes the book, IMO, unsuitable for beginners or near beginners. But what I /really/ don't like is the impression he gives that thinking in objects is some sort of Zen-like higher thought, which only a few masters (after long and arduous training) can master. Object thinking is /supposed/ to be easy and natural -- why bother otherwise ? -- if your teacher suggests that fasting for 40 days and nights is a good start then my advice is to find a new teacher ;-) Yes, it can be difficult to drop old ways of thinking -- just as in every other domain -- but it isn't /that/ hard, and there's nothing so /very/ mystical about discovering that OO is a good deal easier than non-OO.
([*] For instance there is a passage on object state that would seem to suggest that designs produced by true Object Thinkers have little state -- of course that's wrong, what he means is that such designs have as much object-state as anyone else's designs, but that it's not /interesting/)
BTW, for Rhino or anyone else reading this thread who is looking for "good" books on OO. There are two aspects to OO programming, and the books that Andrew and I have been discussing address only one of them. The first aspect is the technical stuff in whatever language you use that allows one to do OO in the first place; in Java that's things like classes, abstract classes, interfaces, polymorphism, and method overriding. I'm told that "Effective Java" is a good introduction to the techniques and pitfalls here (but I haven't read it myself). The other question -- which is almost entirely language-independent -- is about how to /use/ those techniques once one has acquired them. The "Object Design" and "Object Thinking" books are about that.
-- chris
Andrew McDonagh - 24 Dec 2005 23:30 GMT snipped...
> 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 [quoted text clipped - 11 lines] > With that in mind, can you (or anyone else) suggest a good way to learn OO > Design? personally, doing, rather than reading is the only way I made the mental transition from procedural to OO. It is a different way of conceptualizing the solution and so will take time gain experience with.
Its a lot more than simply uses classes, regardless what most non-oo (Procedural, Functional, Set, etc ) people say.
For me, the transition sped up when I understood the mechanics of how virtual method calls worked....it was like the snow ball turning into a snow man...turning into an avalanche.
Once I understood that, then all of the talk about 'messages sent to objects' became clearer. They were talking about method invocation...so why talk about it so abstractly? Aha!.... you get the picture...
> 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, [quoted text clipped - 7 lines] > examples and does poorly when concepts are explained with only vague > generalities. Whilst some of the older OO books as certainly worth looking at, I'd stick with the newer ones or new editions of those older ones. Like everything, OO has moved on substantially since 91.
> 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, [quoted text clipped - 4 lines] > > Rhino Online groups.
comp.object - but they tend to fight a lot over the theory so getting actual useful advice can be difficult - but worth the try.
TestDrivenDevelopment yahoo group - though not specifically about OO, it has a large number of very talented OO people, who more importantly, are willing to be helpful, rather than argue amongst themselves.
Refactoring Yahoo group - same as above.
Articles:
Most from Object mentor are good - Robert C Martin, et al. http://www.objectmentor.com/resources/articleIndex http://www.objectmentor.com/resources/listArticles?key=topic&topic=Design%20Prin ciples http://www.objectmentor.com/resources/listArticles?key=topic&topic=Object%20Orie nted%20Design
Theres enough for a lifetime out there...as you may have seen.
In the mean time, feel free to post your java design questions here.
All the best and merry Christmas!
Andrew
Chris Uppal - 22 Dec 2005 11:42 GMT > 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" ;-)
Rhino - 22 Dec 2005 19:36 GMT >> 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 [quoted text clipped - 16 lines] > tendency to > over-engineer everything. Exactly!
> You /might/ be able to explain that you had deliberately over-engineered > the [quoted text clipped - 9 lines] > 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 [quoted text clipped - 28 lines] > > 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 > [quoted text clipped - 3 lines] > 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
Chris Uppal - 23 Dec 2005 10:58 GMT > 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
Rhino - 23 Dec 2005 17:16 GMT >> 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 [quoted text clipped - 10 lines] > the UK) > has been fairly positive, but then I've always been picky... I'm really not sure how many employers here (Canada) would qualify as "good" either.
The job descriptions in this area always seem to demand the sun, the moon and the stars, plus the ability to walk on water without freezing it first. I know that the standard advice is to look at the job description that way and assume that the employer would really be willing to settle for considerably less in most cases. But it never ceases to bother me when a job description distinguishes between "Must have" and "Should have" and the "must have" list contains completely unrealistic points. For instance, I remember one job description from around 1998 that had a "must have" of "minimum 5 years professional Java coding experience": at that point, I believe Java had only been available for 2 years!
I'm sure I'll find out the reality of what they will accept compared to what they'd like as I go through the job-search/interview process :-)
>> When I've succeeded in properly learning OO Design principles, I can >> revise my example programs to fit those principles better _and_ change my [quoted text clipped - 5 lines] > newsgroup postings ;-) You can only become practised in OO by > /practicing/. I couldn't agree more! I'm not a great one for understanding much of anything without a good dose of hands-on practice. I've met people who actually seem to understand things simply from reading a book and seeing a quick example or two; I envy those people and I envy them but I am definitely not one of them!
For me - and, I believe, a great many other people - theory has to be combined with practice before you really understand something and can apply it properly. I say that from the perspective of someone who has been a professional instructor of computer subjects for most of the past two decades.
> You have to read and write OO programs. So putting off re-writing your > own [quoted text clipped - 27 lines] > reasons to > look for objects -- there's comprehensibility too.) I'm definitely not opposed to trying to create my own _private_ versions of the resume generator program that I've mentioned in this thread; I think it would be a valuable learning experience, particularly as I envision changing requirements along the lines you suggest. I've even made a start at that by breaking the code for generating each file into its own separate class and having an interface that they share for common data. That's the version that I will share with a prospective employer.
But the key realization I have made from this thread is that my current program does _not_ reflect a good OO design; I really wasn't sure about that before. Unfortunately, I don't have the luxury of spending weeks or months learning more about OO design so that I can revise my design to fit OO design precepts correctly, otherwise I would do so and present a properly designed program to those prospective employers _and_ amend my resume to claim some skill with OO Design. Therefore, I will present the current version of the program _without_ any claim to OO Design abilities. I will emphasize that it works and is simple throwaway code but acknowledge that it isn't good OO Design. I will also stress that I want to learn OO design and am working at learning it on my own but haven't mastered it yet; I'll add that a chance to work on a team that has good OO design skills would help me learn OO design better and faster. I think that's the best I can do at this point, given my time constraints.
Thank you - and everyone else who responded - for your time and your very helpful contributions! I've learned a lot and have a good path to explore to help me improve my skills.
Rhino
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|