Prev: JNI win32 and Layered windows.
Next: Design Question
From: Rhino on 16 Mar 2010 14:39 On Mar 15, 3:59 pm, Patricia Shanahan <p...(a)acm.org> wrote: > Rhino wrote: > > Is it possible to do a full-on assignment of specific values to a HashMap > > in an interface? If so, how? > > Before actually doing this, I recommend reviewing your design to see > whether this really makes sense. AMapseems a bit too much > implementation to belong naturally in an interface. However, if you do > want to do it, you can put a method to generate themapin a static > member class declaration. > > import java.awt.Color; > import java.util.HashMap; > import java.util.Map; > > public interface ColorMapTest { > Map<String, Color> EIGHT_BIT_COLORS = ColorMapInitializer > .getMap(); > > static class ColorMapInitializer { > staticMap<String, Color> getMap() { > Map<String, Color> result = new HashMap<String, Color>(); > result.put("Black", new Color(0, 0, 0)); > result.put("Obscure Gray", new Color(51, 51, 51)); > result.put("Dark Gray", new Color(102, 102, 102)); > result.put("Light Gray", new Color(153, 153, 153)); > result.put("Pale Gray", new Color(204, 204, 204)); > result.put("White", new Color(255, 255, 255)); > return result; > } > } > > > > }- Hide quoted text - > > - Show quoted text - Thank you, Patricia! Several people replying to my question have raised the issue of why I am initializing a Map in an interface. Unfortunately, I've been having major issues with my newsreader ever since posting my two questions yesterday and have been unable to reply to this newsgroup in any way other than Google Groups, to my great regret. Let me finally answer that question now and perhaps people can advise me on a better design if putting the Map in an interface turns out to be a bad idea. The map I'm trying to create contains all of the 216 8-bit web-safe colors, the ones that are supposed to render correctly, without dithering, on virtually every 8-bit or better OS on virtually every moniI know that the need for web-safe colors is virtually non-existent these days on newer OSes with better graphic cards but I'm doing this primarily as an intellectual exercise, not something that absolutely has to be done. Therefore, my Map will contain the 216 web-safe colors and provide sort of a universe of colors. I want to create some additional classes called ColorSet and ColorPalette. A ColorSet contains a limited number of coordinating colors that each have a specific function on a web page (or an Applet that will appear in a web page). For example, one color in each ColorSet is for text and another is for backgrounds for that text. (A ColorPalette is just a bunch of ColorSets that are selectable by a program. The user chooses a desired ColorSet from the ColorPalette and can be assured that the ColorSet colors will mesh nicely with one another.) I want to make sure that a ColorSet contains only Colors from the Map of web-safe colors. Since the Map of web-safe Colors is effectively immutable - the 216 colors have been defined and there aren't going to be any additions or deletions to the list - it seems reasonable to put them in a some kind of permanent structure, like an Interface. But maybe there are better options, like the Enum or EnumMap that someone suggeested elsewhere in the thread. Or in a class. I'm not particularly wedded to putting the Map in an interface or even to using a Map at all. I'm really just looking for a good way to ensure that ColorSets can only contain specific values rather than any old Color that can be defined in Java. That's the part of the problem that interests me. I have no formal Java training so I'm just trying to figure out a good way to ensure that a given group of somethings, in this case a ColorSet, is always a subset of another set. Another example of the same issue might be two-letter country codes. Given that there is a list of recognized two-letter country codes, 'us' for United States, 'ca' for Canada, etc., how could I ensure that a group of country codes - let's say, a list of North American countries - only contains legitimate country codes like 'us' and 'ca' and no non-existent codes, like 'xx'? (Unlike the web-safe colors, the list of country codes is mutable as new countries, like Slovakia, emerge and countries like the Soviet Union disappear. But you get the idea.) I'd be delighted to get some guidance on the best way to handle this sort of situation. -- Rhino
From: Eric Sosman on 16 Mar 2010 15:12 On 3/16/2010 2:39 PM, Rhino wrote: > [...] > Since the Map of web-safe Colors is effectively immutable - the 216 > colors have been defined and there aren't going to be any additions or > deletions to the list - it seems reasonable to put them in a some kind > of permanent structure, like an Interface. But maybe there are better > options, like the Enum or EnumMap that someone suggeested elsewhere in > the thread. Or in a class. An interface feels wrong for this. The primary purpose of an interface is to be implemented by classes, to ensure that the implementing classes provide methods with the right names and signatures. Sometimes an interface defines constants, in essence conveniences for the implementors and callers, but this has now mostly been supplanted (and improved on) by Enums. A few interfaces exist that specify no methods at all and merely define constants; this is now viewed as Something We Did When We Were Too Young To Know Any Better. > I'm not particularly wedded to putting the Map in an interface or even > to using a Map at all. I'm really just looking for a good way to > ensure that ColorSets can only contain specific values rather than any > old Color that can be defined in Java. That's the part of the problem > that interests me. I have no formal Java training so I'm just trying > to figure out a good way to ensure that a given group of somethings, > in this case a ColorSet, is always a subset of another set. Putting a Map<String,Color> in an interface will not enforce any such guarantee on the classes that implement it. Making an `enum SafeColor' would be a first step, and then you could write interfaces whose methods took SafeColor parameters and returned SafeColor values (or List<SafeColor>, etc.). If the interface specifies methods that return plain Colors, though, there's no way to guarantee that the Colors come from your chosen few. > Another example of the same issue might be two-letter country codes. > Given that there is a list of recognized two-letter country codes, > 'us' for United States, 'ca' for Canada, etc., how could I ensure that > a group of country codes - let's say, a list of North American > countries - only contains legitimate country codes like 'us' and 'ca' > and no non-existent codes, like 'xx'? (Unlike the web-safe colors, the > list of country codes is mutable as new countries, like Slovakia, > emerge and countries like the Soviet Union disappear. But you get the > idea.) One way would be to have a Country class, with a static method like `Country getCountryForCode(String countryCode)'. The caller hands it a (supposed) country code, and it returns the designated Country or null (or throws up, if you prefer). I do not see how an interface would be of any help here. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Rhino on 16 Mar 2010 16:17 On Mar 16, 2:12 pm, Eric Sosman <esos...(a)ieee-dot-org.invalid> wrote: > On 3/16/2010 2:39 PM, Rhino wrote: > > > [...] > > Since theMapof web-safe Colors is effectively immutable - the 216 > > colors have been defined and there aren't going to be any additions or > > deletions to the list - it seems reasonable to put them in a some kind > > of permanent structure, like an Interface. But maybe there are better > > options, like the Enum or EnumMap that someone suggeested elsewhere in > > the thread. Or in a class. > > An interface feels wrong for this. The primary purpose of > an interface is to be implemented by classes, to ensure that > the implementing classes provide methods with the right names > and signatures. Sometimes an interface defines constants, in > essence conveniences for the implementors and callers, but this > has now mostly been supplanted (and improved on) by Enums. A > few interfaces exist that specify no methods at all and merely > define constants; this is now viewed as Something We Did When > We Were Too Young To Know Any Better. > I remember being told that an Interface containing only constants was a good (or at least reasonable) idea on this same newsgroup some years ago.... Then again, as you say, the Java Community has gradually evolved better ways of doing things. I have been away from Java for several years and things have obviously evolved in my absence. I need to play some catchup now. What is a better way to keep persistent data if an Interface is not the best way? I have a variety of interfaces containing only constants for various programs. For instance, I use them to store the base names of the resource bundles I use for a given program and for the name of the log file that the program should be generating. It sounds like I need to revisit these and change the way I handle this kind of data. I'm just not sure what approach I should be using nowadays. > > I'm not particularly wedded to putting theMapin an interface or even > > to using aMapat all. I'm really just looking for a good way to > > ensure that ColorSets can only contain specific values rather than any > > old Color that can be defined in Java. That's the part of the problem > > that interests me. I have no formal Java training so I'm just trying > > to figure out a good way to ensure that a given group of somethings, > > in this case a ColorSet, is always a subset of another set. > > Putting aMap<String,Color> in an interface will not enforce > any such guarantee on the classes that implement it. Making an > `enum SafeColor' would be a first step, and then you could write > interfaces whose methods took SafeColor parameters and returned > SafeColor values (or List<SafeColor>, etc.). If the interface > specifies methods that return plain Colors, though, there's no > way to guarantee that the Colors come from your chosen few. > Okay, then a Map in an interface is not the optimum design. That's fine. I could certainly put the web-safe colors in an Enum. I'm not clear yet on the rest though. Let's say that I want to pre-define some ColorSets that would ship with program. But customers would also be given a program that would generate additional ColorSets. However, all ColorSets, including the ones I define and the ones they define, need to choose their colors from the set of web-safe colors. How should that be done? I'm not quite picturing what you have in mind yet. > > Another example of the same issue might be two-letter country codes. > > Given that there is a list of recognized two-letter country codes, > > 'us' for United States, 'ca' for Canada, etc., how could I ensure that > > a group of country codes - let's say, a list of North American > > countries - only contains legitimate country codes like 'us' and 'ca' > > and no non-existent codes, like 'xx'? (Unlike the web-safe colors, the > > list of country codes is mutable as new countries, like Slovakia, > > emerge and countries like the Soviet Union disappear. But you get the > > idea.) > > One way would be to have a Country class, with a static > method like `Country getCountryForCode(String countryCode)'. > The caller hands it a (supposed) country code, and it returns > the designated Country or null (or throws up, if you prefer). > > I do not see how an interface would be of any help here. > Fair enough. I expect that I am still thinking in obsolete ways. An enum that lists all valid country codes could easily be used to validate a country code that someone proposed to type on a form, for example. Have the form validations check the country code provided on the form (I'm assuming a simple text box here, rather than a List) to see if it's in the Enum; if it is, it's a valid code and if it's not, the country code is invalid. But this time you suggested a class with a static method, not an Enum. Is that because the list of countries is mutable whereas the list of web-safe colors is immutable? -- Rhino
From: Eric Sosman on 16 Mar 2010 18:15 On 3/16/2010 4:17 PM, Rhino wrote: > On Mar 16, 2:12 pm, Eric Sosman<esos...(a)ieee-dot-org.invalid> wrote: >> On 3/16/2010 2:39 PM, Rhino wrote: >>> [...] > I remember being told that an Interface containing only constants was > a good (or at least reasonable) idea on this same newsgroup some years > ago.... Then again, as you say, the Java Community has gradually > evolved better ways of doing things. I have been away from Java for > several years and things have obviously evolved in my absence. I need > to play some catchup now. You must have been away quite a while. Bloch recommended against constant-only interfaces in the first edition of "Effective Java," copyright 2001. > What is a better way to keep persistent data > if an Interface is not the best way? "Persistent data" could mean a lot of different things, and I don't know which you intend. > I have a variety of interfaces containing only constants for various > programs. For instance, I use them to store the base names of the > resource bundles I use for a given program and for the name of the log > file that the program should be generating. It sounds like I need to > revisit these and change the way I handle this kind of data. I'm just > not sure what approach I should be using nowadays. Usually, such things are located in relation to a class in a jar file, often the "Main" class of the "program." Without more specifics, I can't say whether that makes sense for (or to) you. > I could certainly put the web-safe colors in an Enum. I'm not clear > yet on the rest though. > > Let's say that I want to pre-define some ColorSets that would ship > with program. But customers would also be given a program that would > generate additional ColorSets. However, all ColorSets, including the > ones I define and the ones they define, need to choose their colors > from the set of web-safe colors. How should that be done? I'm not > quite picturing what you have in mind yet. enum SafeColor { // define instances for all (and only) the safe colors } then public interface ColorSet implements Set<SafeColor> { ... } or public interface ColorSet { SafeColor getSafeColorByName(String name); SafeColor getSafeColorByHue(Color hue); SafeColor getNearestSafeColor(Color hue); ... } Since the methods must return SafeColors, you can be sure they return nothing that isn't in the enum you defined. If there's some "default" implementation to go with this stuff, make ColorSet a class (abstract optional) instead of an interface. >>> Another example of the same issue might be two-letter country codes. >>> Given that there is a list of recognized two-letter country codes, >>> 'us' for United States, 'ca' for Canada, etc., how could I ensure that >>> a group of country codes - let's say, a list of North American >>> countries - only contains legitimate country codes like 'us' and 'ca' >>> and no non-existent codes, like 'xx'? [...] >> >> One way would be to have a Country class, with a static >> method like `Country getCountryForCode(String countryCode)'. >> The caller hands it a (supposed) country code, and it returns >> the designated Country or null (or throws up, if you prefer). >> >> I do not see how an interface would be of any help here. >> > Fair enough. I expect that I am still thinking in obsolete ways. An > enum that lists all valid country codes could easily be used to > validate a country code that someone proposed to type on a form, for > example. Have the form validations check the country code provided on > the form (I'm assuming a simple text box here, rather than a List) to > see if it's in the Enum; if it is, it's a valid code and if it's not, > the country code is invalid. But this time you suggested a class with > a static method, not an Enum. Is that because the list of countries is > mutable whereas the list of web-safe colors is immutable? Mostly. You could use a Country enum if you liked, at the cost of having to recompile and ship a new version of Country whenever something changed. A Country class that initialized itself by reading a code/country list from some resource might be easier to mutate. (The resource might even be a URL somewhere, saving you the effort of "pushing" new files to the installed base.) There's more than one way to skin a cat. Which is a good thing, because cats come in different sizes and ferocities ... -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Lew on 16 Mar 2010 21:47 Rhino wrote: >> I remember being told that an Interface containing only constants was >> a good (or at least reasonable) idea on this same newsgroup some years Bad advice. >> ago.... Then again, as you say, the Java Community has gradually >> evolved better ways of doing things. I have been away from Java for >> several years and things have obviously evolved in my absence. I need >> to play some catchup now. Eric Sosman wrote: > You must have been away quite a while. Bloch recommended > against constant-only interfaces in the first edition of "Effective > Java," copyright 2001. <http://java.sun.com/docs/books/effective/> 2nd ed.: "Item 19: Use interfaces only to define types" He calls it the constant interface pattern, but you'll see it in the literature as the "Constant Interface Antipattern". One extremely important insight from this chapter is the focus on types. Java programming with types rides the synergy of interfaces and generics to build solid code. From the world of types, it makes perfect sense that interfaces not hold the kind of Map you describe. That there's a Map in there makes no difference to the kind of type you need, an immutable set of particular colors with associated names over which one can search or correlate by or to names. The difference is in the behaviors and characteristics of that structure, much as Eric and others have outlined. From this thread I see that you can use an enum, a static immutable Map (in a utility class!), an EnumMap, or whatever. I showed an immutable Map approach upthread. I use the idiom frequently: private static final Collection<T> stuff; // immutable static { Collection<T> ffuts = // ... instantiate something appropriate fillWithStuffToBeImmutable( ffuts ); // type T instances need to be immutable stuff = Collections.unmodifiableCollection( ffuts ); } and similarly for finer-grain types like List, or for Maps. Rhino wrote: >> What is a better way to keep persistent data >> if an Interface is not the best way? In a utility class. Eric Sosman wrote: > "Persistent data" could mean a lot of different things, and > I don't know which you intend. I guess from context they mean data that hangs around immutably. Eric Sosman wrote: > There's more than one way to skin a cat. Which is a good > thing, because cats come in different sizes and ferocities ... -- Lew
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: JNI win32 and Layered windows. Next: Design Question |