From: Rhino on 27 May 2010 11:20 I'm trying to implement the advice I was given the other day about the placement of constants that were shared in various classes of my project. I've managed to thin out my FooConstants class considerably on that basis of that advice but I'm having specific cases that are giving me trouble. First, let me begin by correcting an inadvertent misstatement I made about this project. I said that it was generating resumes in various formats and that all of the files were being kicked off by a single class (ResumeFileGenerator, although I didn't state its name previously). As I look at the code again a bit more closely, I see that this is not quite the case. A standalone class called ResumeApplet displays my resume in the form of an applet. Now, several of the classes that generate resumes, including ResumeApplet, are making use of colors from a specific palette of colors that are embodied in an enum. The enum lists several color palettes and each palette has a color to be used for displaying text, and some contrast colors for use in JPanels or HTML or in heading text in PDFs. I want to make sure that all of the classes that generate Resumes use the exact same color palette to do their jobs; I don't want the applet to use a predominantly red palette while the HTML page uses a predominantly green palette. Every instinct I have says that I should be establishing exactly which palette I want to use ONCE for the project and that all classes should use that same palette. Clearly, the color palette is not a file/path kind of information that might best be situated in a properties file and isn't a String anyway. Does this constitute "configuration" information? If so, where do I put it? And if it's not configuration information, where should I put it so that all classes in the project use that specific color palette? It's just one line of code: ColorPalette colorPalette = ColorPalette.BLUES; but I'm really struggling with where it needs to be. I need to be sure that other classes in the project don't suddenly start using ColorPalette.REDS (or whatever) and that's the obvious risk if I have a line defining which colorPalette I want in each class that needs colors. I was thinking of establishing the color palette in the ResumeFileGenerator class, probably in the constructor, and then passing a reference to each class that needed it but this won't help me with the standalone ResumeApplet. -- I have a few other constants which strike me as problematic too, although the color palette feels like the big one. Let me mention these too now in case they have different solutions than Color Palette. Several of the classes write the word "Resume" in one or another places and I am trying to write it so that the acute accents on the two e's appear correctly. I've got several constants for the different variations: public static final String RESUME_HTML_LOWERCASE = "résumé"; public static final String RESUME_HTML_CAMELCASE = "Résumé"; public static final String RESUME_UNICODE_LOWERCASE = "r\u00e9sum\u00e9"; public static final String RESUME_UNICODE_CAMELCASE = "R\u00e9sum\u00e9"; I need the first two in HTML documents that are being generated and the latter two in ASCII, PDF, and CSS documents that are being generated. Since each of these is used in at least two different classes, I'm not sure where best to place these. All of the classes in the project share a common set of ResourceBundles. (I want to keep open the possibility of generating resumes in foreign languages since I have a working knowledge of two other languages and could picture working in countries where those languages are spoken. I haven't actually translated phrases like "Job Target" or "Format Education" to the other languages but I _could_ and might do that.) The base name of the ResourceBundles is used in both ResumeFileGenerator and ResumeApplet. Where should I put its definition so that both classes use the exact same name? Lastly, let me raise the case of what I'll call a "convenience constant". I tend to prefer writing the name of a String constant called NEWLINE rather than a "\n" in my statements simply because the former seems a little clearer to me. I've used this technique in many classes in many projects so this constant has much wider scope than just this one project. Would it make sense to have a class of constants in my Common project and just accumulate any similar widely used constants there? If not, what is a better way to handle this kind of situation? Let me stress that these "convenience constants" are not a big deal to me; if good OO design opposes the very notion and prefers use of "\n" in all cases rather than a constant, that's fine by me. I'm just trying to understand how a constant that is widely used in many projects should be handled. One (or more) of the responders to my original question said that classes containing Constants weren't absolutely unthinkable, although there were usually better ways. I haven't stumbled on exceptions that really DO belong in a FooConstants class have I? -- Rhino
From: Tom Anderson on 27 May 2010 12:46 On Thu, 27 May 2010, Rhino wrote: > It's just one line of code: > > ColorPalette colorPalette = ColorPalette.BLUES; > > but I'm really struggling with where it needs to be. Presumably, you have a Resume class (or even better, a ResumePresentation). Who makes instances of that? Where does it get its information from? Where, for instance, is your name stored? > Several of the classes write the word "Resume" in one or another places > and I am trying to write it so that the acute accents on the two e's > appear correctly. I've got several constants for the different > variations: > > public static final String RESUME_HTML_LOWERCASE = "résumé"; > public static final String RESUME_HTML_CAMELCASE = "Résumé"; > public static final String RESUME_UNICODE_LOWERCASE = "r\u00e9sum\u00e9"; > public static final String RESUME_UNICODE_CAMELCASE = "R\u00e9sum\u00e9"; > > I need the first two in HTML documents that are being generated Not necessarily - if you're using a character encoding that contains the e with an acute accent, like UTF-8 or ISO-Latin-1, you can just use it directly, rather than writing an escape. > and the latter two in ASCII, You aren't going to have a lot of luck using those in ASCII documents, considering that those strings have non-ASCII characters in. Did you mean 'plain text (in some suitable character encoding)'? > PDF, and CSS documents that are being generated. > > Since each of these is used in at least two different classes, I'm not > sure where best to place these. Firstly, i'd be tempted not to do this with constants, but to write the string once (in a resource bundle), and use methods to (a) escape characters for HTML and (b) twiddle the case of the leading letter. Then, if you change the string in question, you only have to change one string literal, rather than four. Secondly, if there is a constant which is used by several classes, and more than one of them has a strong claim to ownership of the constant, then it can certainly go in some constant-holding class or interface. Such things are to be avoided where possible, but are the right solution when that is not possible. > All of the classes in the project share a common set of ResourceBundles. > (I want to keep open the possibility of generating resumes in foreign > languages since I have a working knowledge of two other languages and > could picture working in countries where those languages are spoken. I > haven't actually translated phrases like "Job Target" or "Format > Education" to the other languages but I _could_ and might do that.) The > base name of the ResourceBundles is used in both ResumeFileGenerator and > ResumeApplet. Where should I put its definition so that both classes use > the exact same name? Same problem as above. This belongs to whoever is in charge of making Resume objects. If there are several places where Resume objects are made, then refactor until there is only one, and put it there. > Lastly, let me raise the case of what I'll call a "convenience > constant". I tend to prefer writing the name of a String constant called > NEWLINE rather than a "\n" in my statements simply because the former > seems a little clearer to me. I've used this technique in many classes > in many projects so this constant has much wider scope than just this > one project. Would it make sense to have a class of constants in my > Common project and just accumulate any similar widely used constants > there? If not, what is a better way to handle this kind of situation? > Let me stress that these "convenience constants" are not a big deal to > me; if good OO design opposes the very notion and prefers use of "\n" in > all cases rather than a constant, that's fine by me. I'm just trying to > understand how a constant that is widely used in many projects should be > handled. Firstly, you should probably be saying System.getProperty("line.separator") rather than "\n", so you get the right line ending on heathen platforms. Secondly, i know of no OO or general programming principle that opposes constants like that in the general case. The same analysis as above applies: if they're owned equally by several classes, but them in some neutral place, like a constants class. > One (or more) of the responders to my original question said that > classes containing Constants weren't absolutely unthinkable, although > there were usually better ways. I haven't stumbled on exceptions that > really DO belong in a FooConstants class have I? Sounds like it. tom -- the themes of time-travel, dreams, madness, and destiny are inextricably confused
From: Rhino on 27 May 2010 13:37 "Tom Anderson" <twic(a)urchin.earth.li> wrote in message news:alpine.DEB.1.10.1005271735220.16072(a)urchin.earth.li... > On Thu, 27 May 2010, Rhino wrote: > >> It's just one line of code: >> >> ColorPalette colorPalette = ColorPalette.BLUES; >> >> but I'm really struggling with where it needs to be. > > Presumably, you have a Resume class (or even better, a > ResumePresentation). Who makes instances of that? Where does it get its > information from? Where, for instance, is your name stored? > The DATA on the resume is all stored in a ResourceBundle, including my name, email address, job target, experience and all of that. The labels used to present that information, like "Job Target", "Formal Education" etc. are likewise stored in the same ResourceBundle. I have a Resume class. It's job is to find the obtain the information from the ResourceBundle. It is basically a bunch of small getters, like getJobTargetText() which returns the label "Job Target" (it would return the French translation of Job Target if I create a French-language resume) and getJobTargetData() which returns the jobs that I am targeting with this resume. ResumeFileGenerator kicks off most of the classes which create resumes. I'm not sure the proper name of this kind of class - driver? framework? - but it instantiates all but one of the classes that generate a resume. ResumeFileGenerator is a plain Java application, not a servlet or whatever. The code in ResumeFileGenerator looks like this: public class ResumeFileGenerator { public static void main(String[] args) { ResumeFileGenerator resumeFileGenerator = new ResumeFileGenerator(); resumeFileGenerator.generateResumes(); System.out.println("\n===Program ends==="); } public ResumeFileGenerator() { localizationUtils = LocalizationUtils.getInstance(); resumeResources = localizationUtils.getResources(Locale.getDefault(), ResumeConstants.LIST_BASE); /* Establish the color palette that will be used by these classes. */ ColorPalette colorPalette = ColorPalette.RC_BLUES; /* Get database connection. */ /* Set up logging. */ } /** * Generates various resume files. */ public void generateResumes() { /* Get an instance of the data that will be used by all of the resume writers. */ Resume resume = new Resume(resumeResources); /* Write the resume in HTML format. */ ResumeFileWriterHtml resumeFileWriterHtml = new ResumeFileWriterHtml(); resumeFileWriterHtml.writeResume(resume); /* Write the resume in ASCII format. */ ResumeFileWriterAscii resumeFileWriterAscii = new ResumeFileWriterAscii(); resumeFileWriterAscii.writeResume(OUTPUT_FILE_PATH + ResumeFileGeneratorConstants.RESUME_ASCII_FILE, resume); /* Write the resume in property format. */ ResumeFileWriterProperty resumeFileWriterProperty = new ResumeFileWriterProperty(); resumeFileWriterProperty.writeResume(OUTPUT_FILE_PATH + RESUME_PROPERTY_FILE, resume); /* Write the resume in PDF format. */ ResumeFileWriterPdf resumeFileWriterPdf = new ResumeFileWriterPdf(); resumeFileWriterPdf.writeResume(OUTPUT_FILE_PATH + ResumeFileGeneratorConstants.RESUME_PDF_FILE, resume); ..... } } That's the gist of it. ResumeApplet is a standalone applet that also uses the colors from the color palette for painting the resume. I don't have a ResumePresentation class at all. Is a "Presentation" class part of one of the design patterns? I'm afraid I don't know those very well.... If I should be using a particular design pattern here, which one should I use? I have some Design Pattern links and can find examples of the desired patterns use if you can point me to the one I should be using..... >> Several of the classes write the word "Resume" in one or another places >> and I am trying to write it so that the acute accents on the two e's >> appear correctly. I've got several constants for the different >> variations: >> >> public static final String RESUME_HTML_LOWERCASE = >> "résumé"; >> public static final String RESUME_HTML_CAMELCASE = >> "Résumé"; >> public static final String RESUME_UNICODE_LOWERCASE = >> "r\u00e9sum\u00e9"; >> public static final String RESUME_UNICODE_CAMELCASE = >> "R\u00e9sum\u00e9"; >> >> I need the first two in HTML documents that are being generated > > Not necessarily - if you're using a character encoding that contains the e > with an acute accent, like UTF-8 or ISO-Latin-1, you can just use it > directly, rather than writing an escape. > >> and the latter two in ASCII, > > You aren't going to have a lot of luck using those in ASCII documents, > considering that those strings have non-ASCII characters in. Did you mean > 'plain text (in some suitable character encoding)'? > Honestly, I don't remember why I created the escaped versions any more. They seemed necessary at the time and they work in the sense that the accents appear where they should but I may be able to revise them to simply use a direct e-acute rather than the escaped versions. I'll look into that and change it if I can. However, I still need each version of each string in at least two different places so I still need to understand where to place the definitions. >> PDF, and CSS documents that are being generated. >> Since each of these is used in at least two different classes, I'm not >> sure where best to place these. > > Firstly, i'd be tempted not to do this with constants, but to write the > string once (in a resource bundle), and use methods to (a) escape > characters for HTML and (b) twiddle the case of the leading letter. Then, > if you change the string in question, you only have to change one string > literal, rather than four. > Fair enough. > Secondly, if there is a constant which is used by several classes, and > more than one of them has a strong claim to ownership of the constant, > then it can certainly go in some constant-holding class or interface. Such > things are to be avoided where possible, but are the right solution when > that is not possible. > There are indeed multiple classes that use each string and no obvious candidate for which one is more of an owner than any of the others. I'm not really trying to get permission to use a Constants class here; I just want to make sure I've exhausted all other reasonable alternatives before using a Constants class. I'm just not sure if I have exhausted all the other reasonable possibilities or whether I'm overlooking better approaches. >> All of the classes in the project share a common set of ResourceBundles. >> (I want to keep open the possibility of generating resumes in foreign >> languages since I have a working knowledge of two other languages and >> could picture working in countries where those languages are spoken. I >> haven't actually translated phrases like "Job Target" or "Format >> Education" to the other languages but I _could_ and might do that.) The >> base name of the ResourceBundles is used in both ResumeFileGenerator and >> ResumeApplet. Where should I put its definition so that both classes use >> the exact same name? > > Same problem as above. This belongs to whoever is in charge of making > Resume objects. If there are several places where Resume objects are made, > then refactor until there is only one, and put it there. > Hmm. I'm not sure I'm understanding you correctly. Based on my description so far (in the original post and this followup) would you agree that ResumeFileGenerator is the place where the Resume objects are made? Or are you talking about the specific classes that generate each Resume, like ResumeFileWriterAscii, ResumeFileWriterHtml, ResumeFileWriterPdf and so forth? And what about my standalone ResumeApplet? The resume in that is NOT created by ResumeFileGenerator. >> Lastly, let me raise the case of what I'll call a "convenience constant". >> I tend to prefer writing the name of a String constant called NEWLINE >> rather than a "\n" in my statements simply because the former seems a >> little clearer to me. I've used this technique in many classes in many >> projects so this constant has much wider scope than just this one >> project. Would it make sense to have a class of constants in my Common >> project and just accumulate any similar widely used constants there? If >> not, what is a better way to handle this kind of situation? Let me stress >> that these "convenience constants" are not a big deal to me; if good OO >> design opposes the very notion and prefers use of "\n" in all cases >> rather than a constant, that's fine by me. I'm just trying to understand >> how a constant that is widely used in many projects should be handled. > > Firstly, you should probably be saying > System.getProperty("line.separator") rather than "\n", so you get the > right line ending on heathen platforms. > Good point ;-) And that basically eliminates the issue in this case.... > Secondly, i know of no OO or general programming principle that opposes > constants like that in the general case. The same analysis as above > applies: if they're owned equally by several classes, but them in some > neutral place, like a constants class. > Okay, that sounded logical to me but I'm trying to be sure I haven't overlooked other important considerations. Even if my NEWLINE constant is not an issue any more, I can picture other constants that may arise that ARE used in many classes. It's good to know that some constants in a Common project that are (potentially) shared by all projects are not going to present a problem. >> One (or more) of the responders to my original question said that classes >> containing Constants weren't absolutely unthinkable, although there were >> usually better ways. I haven't stumbled on exceptions that really DO >> belong in a FooConstants class have I? > > Sounds like it. > I'm surprised. I had assumed that I was just missing some obvious (to you) alternate techniques.... -- Rhino
From: Jeff Higgins on 27 May 2010 14:34 On 5/27/2010 11:20 AM, Rhino wrote: > I'm trying to implement the advice I was given the other day about the > placement of constants that were shared in various classes of my project. By writing paragraphs of English prose? <http://xmlresume.sourceforge.net/> Yes, I know, there are XML naysayers. It's the thought that counts.
From: Jeff Higgins on 27 May 2010 14:51
On 5/27/2010 1:37 PM, Rhino wrote: > That's the gist of it. <http://groups.google.com/group/comp.lang.java.programmer/msg/154ffc8e2c0e0cba?hl=en> |