In my answer from yesterday I called the following piece of code "a hack":
final class MyMap extends HashMap<SomeSuperLongIdentifier, OtherSuperLongIdentifier> {}
// declared MyMap as an alias for readability purposes only
MyMap a = new MyMap();
a.put("key", "val");
Giving it another thought, this does not seem like a bad idea at all, but I might be missing something. Are there any potholes I missed out on? Is this an acceptable (possibly creative) way for declaring aliases in Java?
The drawback would be that you won't be able to directly use any methods that return a correctly typed Map, because they will never return a MyMap. Even if they could return a Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier>.
For example you wouldn't be able to use the filter() methods in Maps (provided by Google Collections). They would accept a MyMap instance as input, but they would return only a Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier>.
This problem can be somewhat reduced, by writing your MyMap to delegate to another Map implementation. Then you could pass the return value of such a method into the constructor and still have a MyMap (without copying, even). The default constructor could just set the delegate to a new HashMap instance, so the default usage would stay the same.
I would object to the name MyMap: Since you create an alias, make it document its purpose by giving it a useful name. Other than that, I like it.
I think it surely a convenient way to declare type synonyms. Some languages have direct support for that (in Delphi (pascal), for example, you can do that like that:
type MyMap = HashMap<SomeSuperLongIdentifier, OtherSuperLongIdentifier>;
Since Java does not, I think you can use inheritance for that. You need to document, that this declaration is just a synonym and noone should add meethods to this class. Note also, that this consumes a little memory for VMT storage.
I personally would not do this, and would flag it in a review, but this is a matter of opinion.
Google Collections helps mitigate this problem, by letting you declare:
Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier> a = Maps.newHashMap();
I'd look for ways to refactor code to not have to declare so many instances of this Map, perhaps.
As long as developers using your code have IDEs and are able to quickly jump to the class definition and read the comments for its purpose (which are in place, no?), I can see nothing wrong with it.
I wouldn't call it an 'alias'. It isn't. It can't be used interchangeably with the type it is supposed to be aliasing. So if that's the intention, it fails.
I think that inheritance is a very big gun compared to the problem at hand. At the very least I would have made this "alias class" final, with a big fat comment describing the reason for its existence.
Well, there are two contradictory aspects here.
On a modelling point of view, your declaration is right, because it emphasizes the encapsulation your class provides.
On a coding point of view, your declaration may be considered as wrong because you add a class only as a modelling support, with absolutely no added feature.
However, I find your approach quite right (although I never though about it before), since it provides a much appreciated (well, to me, at least) compilable model : classes from your model are perfectly reflected in your code, making your specifications executable, what is very cool.
All this brings me to say it's definitely a great idea, provided you support it with documentation.
I wouldn't call it a hack. Personally, I've created an alias for the purpose of declaring generic type parameters which cannot be changed and creating some clarity.
You also couldn't use this map in serialization if sending to another jvm which does not have your MyMap class.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am maintaining some Java code that utilizes an interface (let's call it BunchOfConstants) to simply store an abundance of public static final Strings. Occasionally these string names change or string names are added / removed. (which causes a bit of a headache for maintanance)
The only current use for this interface is to compare to input later in a big ugly if/then construct like this:
if(BunchOfConstants.CONSTANT1.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT2.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT3.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}
...
I thought it would be more elegant to create a class that implements Iterable or even a class that stores this data in a hashMap.
I can not figure out why the original developers decided to use an interface for this design as the interface is never actually implemented anywhere. Does anyone have any input?
Would you agree that an iterable class with these members as constants would be more appropriate?
Use enums. Then get myenum.values() and then apply a for-each loop over the values.
I would consider using enums instead as constants are not type safe (e.g., they are just ints, or strings, etc.).
This (having dedicated interface for storing constants) was a fairly common way of storing constants before the era of enums. (Pre Java 5 times.) It saved you the hassle of prefixing your constants with the containing class name. I personally never really liked this practice, but this is the reason people did it.
As for what it can be replaced with:
An enum and a switch/case construct. This requires the least modification but only has modest benefits in readability. It does give you type and value safety, plus you can get warnings out of your IDE if you forget to handle a possible value (no case for it and no default block either).
A properties file. This obviously only works if you don't want to branch based on your constant values. (I.e. if your constants don't have to appear in your source code.) This is important, otherwise you'd end up with a secondary set of constants and a properties file, which is as bad as it gets.
A doSomeStuff() factory. For this you have to wrap your doSomeStuff() implementations in separate operation classes and you can configure your factory either statically or from a properties file. (via a constant value->operation class mapping). This is the most "enterprisey" solution, which means that although it looks nice and is very flexible, a lot of the time it is an overkill.
I think this is a good candidate for enum
Well, this looks like the Constant Interface antipattern and maybe should not be used. Using an enum might be a way as suggested, or at least using a final class with private constructor.
If you want to have different implementations for doSomeStuff based on the input string, you might also consider using the strategy pattern, i.e. have a Map<String, Strategy> and then lookup the strategy for whatImLookingFor. If you found the strategy, execute its doSomeStuff, otherwise handle the "not found" case.
I would suggest you to use a property file to store all your constants. This way you can load your properties into a HashMap as you suggest in your question.
Note that property support is brought natively with java: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html
Well, enums are the way to go ... but if the 'dosomestuff' is semantically dependent upon the specific value then why not add a 'dosomestuff' method to the enum itself. That is one that this is really great about Java enums - they are not merely data but as all good objects they have semantics. Then you just loop over the enums invoking dosomestuff(whatIamLookingFor) and whatever happens happens.
Hard to say.
Yes, I agree, that it will be more elegant - at least for you. But think, what the next programmer will think about it. It will be even more complicated.
Previously mentioned strategy pattern and java's enum are definitely better solution, but since you are maintaining this code, I'm not sure if your boss will be happy with time consuming refactoring. My advice would be to use enums - not so big code change.
Looking at some code cleanup and I was wondering the best way to deal with this:
Have a class with some private variables like:
myBool1, myBool2, myBool3
myInt1, myInt2, myInt3
myString1, myString2, myString3
What's the best way to do a getter function that is generic to the return value? So if I do a call to the getter with something like:
myNewBool=<blah>.get("myBool1")
myNewString=<blah>.get("myString2")
myNewInt=<blah>.get("myInt3")
Anyone have any suggestions?
You can't really have a generic getter if you don't know what you want to get, for example :
boolean myNewBool= get("myString1");
If get returns something, but you don't really know if this something is compatible with a boolean, and terrible things could happen.
You could try this:
public <T> get(String element){
return (T) elementToGet;
}
But you would have to specify the return type when you call the get method.
String element = myObject.<String>get("element");
Here are the bad sides :
You can't work directly with primitives
You can have a lot of ClassCastException
If you misspell an attribute name you won't see it until you run it
You don't expose a nice public API, people would have to know evert possible attribute to use it, and as said above, a misspelled attribute (or an inexistant one) wouldn't be seen until runtime.
You have to know the return time and type it each time you use your method
You would have to type a really long (and smelly) code in your get method either to use each possible attribute (if you still want have some private and not accessible) or worse, use reflection to find the right attribute.
So definitively not a good idea.
What you can do instead is using the good old getters//setters and if there is a lot of them, generate them with your IDE.
Another way would be to use the project lombok.
Resources :
Project Lombok
On the same topic :
Create automatically only getters in Eclipse
Eclipse Generate All getters setters in package
Java Getters and Setters
First you should ask what would be the pros and cons of such a solution.
Pros:
One method instead of many
Cons:
Non-intuitive to the users of your class (classical getters are more common)
You cannot have an overload that only differs by a return type, therefore you will have to have methods like getBool, getInt etc.
It's slower - you have to pass the string, check for validity, do a lookup in a map...
The only advantage of your proposed solution would be not repeating the get()/set() code. However, as these methods are usually generated by your IDE and contain only a single-line command, I wouldn't see that as a big problem.
To answer your actual question - you can create a HashMap with name-attribute mapping. Alternatively, you may use Java reflection to access the attributes. The second solution is more general but also harder to write.
This is really a terrible idea. I'm not sure why creating a getter/setter for each private variable is a problem, but passing around strings that map to a variable's symbolic name would be hard to maintain and confusing. You don't need this to be generic; each variable represents a different quantity and they should be accessed as such.
It wouldn't be clean up but mess up. I'd either created 3 getter methods for the fields or redesign it completely. But calling a function, with a name of a field to return, as an argument can bring nothing good.
When you code, you must be refactoring your code for all the time you are coding. But not like this. Solution is delegating logic to another class, wrapping code into more utilizable methods or changing and simplifying domain objects...
Whenever we talk about objects we have instances, methods : functions : behavior, member variable: state, like so many interchangeable words. but for "Class" till now i didnt see people who have used some other word. So is there any other word in java which can be used(or in use)(dont tell any English synonym) which i can use. while explaining my code.
EDIT: Dont invent looking at this question it should be in use which i might not know
The concept of class is related to 'universal' and all that logic (abstraction/universal against instantiation/particular) comes from Aristotle (derived from Plato) philosophy. The OOP seems to take concepts from that filosophy.
The question for me is very relevant. Here is a link from wikipedia (http://en.wikipedia.org/wiki/Aristotle#Universals_and_particulars), and if you read this resume you could understand the relations between Aristotle philosophy and OOP.
Aristotle disagreed with Plato on this point, arguing that all universals are instantiated. Aristotle argued that there are no universals that are unattached to existing things. According to Aristotle, if a universal exists, either as a particular or a relation, then there must have been, must be currently, or must be in the future, something on which the universal can be predicated. Consequently, according to Aristotle, if it is not the case that some universal can be predicated to an object that exists at some period of time, then it does not exist.
Cool ah?
I hope it helps...
Instances, methods, functions, behaviour, etc., are all English words, so I don't quite comprehend your restriction.
So, for Class: Type.
Actually, those all have slightly different meanings: A method is a function attached to a class (they are often incorrectly used interchangably), while behaviour refers at a higher level to what a function/method does.
State refers to the specific value of a variable, or of many variables combined.
To answer your question, another word for class would be object, as you said yourself.
[Edit] It appears I spoke too tongue-in-cheek. As many people have pointed out, 'object' can also refer to an instance of a class. I think your safest bet would be to use class when you mean a class, instance when you mean an instance, spade a spade etc.
Well I heard people referring to it as a blueprint (meaning that it is a definition of what kind of state and what operations an instance will provide).
I'm pretty sure that class is the best way to describe a class in Java.
It is a pretty specific idea, and any synonym will not be able to capture the full meaning of the word.
I saw many times the word Clazz used in the code to avoid the reserved word. Does that help?
Prototype?
I would suggest "Mould" to describe the role of a class
Refer to SoloLearn on google playstore.
Class is also known as Object Factory.
But FYKI, only "class" keyword is used to create a class.
Good luck
I work on a team of Java programmers. One of my co-workers suggests from time-to-time that I do something like "just add a type field" (usu. "String type"). Or code will be committed laden with "if (foo instanceof Foo){...} else if( foo instanceof Bar){...}".
Josh Bloch's admonition that "tagged classes are a wan imitation of a proper class hierarchy" notwithstanding, what is my one-line response to this sort of thing? And then how do I elaborate the concept more seriously?
It's clear to me that - the context being Java - the type of Object under consideration is right in front of our collective faces - IOW: The word right after the "class", "enum" or "interface", etc.
But aside from the difficult-to-demonstrate or quantify (on the spot) "it makes your code more complicated", how do I say that "duck-typing in a (more or less) strongly-typed language is a stupid idea that suggests a much deeper design pathology?
Actually, you said it reasonably well right there.
The truth is that the "instance of" comb is almost always a bad idea (the exception happening for example when you're marshaling or serializing, when for a short interval you may not have all the type information at hand.) As josh says, that's a sign of a bad class hierarchy otherwise.
The way that you know it's a bad idea is that it makes the code brittle: if you use that, and the type hierarchy changes, then it probably breaks that instance-of comb everywhere it occurs. What's more, you then lose the benefit of strong typing; the compiler can't help you by catching errors ahead of time. (This is somewhat analogous to the problems caused by typecasts in C.)
Update
Let me extend this a bit, since from a comment it appears I wasn't quite clear. The reason you use a typecast in C, or instanceof, it that you want to say "as if": use this foo as if it were a bar. Now, in C, there is no run time type information around at all, so you're just working without a net: if you typecast something, the generated code is going to treat that address as if it contained a particular type no matter what, and you should only hope that it will cause a run-time error instead of silently corrupting something.
Duck typing just raises that to a norm; in a dynamic, weakly typed language like Ruby or Python or Smalltalk, everything is an untyped reference; you shoot messages at it at runtime and see what happens. If it understands a particular message, it "walks like a duck" -- it handles it.
This can be very handy and useful, because it allows marvelous hacks like assigning a generator expression to a variable in Python, or a block to a variable in Smalltalk. But it does mean you're vulnerable to errors at runtime that a strongly typed language can catch at compile time.
In a strongly-typed language like Java, you can't really, strictly, have duck typing at all: you must tell the compiler what type you're going to treat something as. You can get something like duck typing by using type casts, so that you can do something like
Object x; // A reference to an Object, analogous to a void * in C
// Some code that assigns something to x
((FoodDispenser)x).dropPellet(); // [1]
// Some more code
((MissleController)x).launchAt("Moon"); // [2]
Now at run time, you're fine as long as x is a kind of FoodDispenser at [1] or MissleController at [2]; otherwise boom. Or unexpectedly, no boom.
In your description, you protect yourself by using a comb of else if and instanceof
Object x ;
// code code code
if(x instanceof FoodDispenser)
((FoodDispenser)x).dropPellet();
else if (x instanceof MissleController )
((MissleController)x).launchAt("Moon");
else if ( /* something else...*/ ) // ...
else // error
Now, you're protected against the run-time error, but you've got the responsibility of doing something sensible later, at the else.
But now imagine you make a change to the code, so that 'x' can take the types 'FloorWax' and 'DessertTopping'. You now must go through all the code and find all the instances of that comb and modify them. Now the code is "brittle" -- changes in the requirements mean lots of code changes. In OO, you're striving to make the code less brittle.
The OO solution is to use polymorphism instead, which you can think of as a kind of limited duck typing: you're defining all the operations that something can be trusted to perform. You do this by defining a superior class, probably abstract, that has all the methods of the inferior classes. In Java, a class like that is best expressed an "interface", but it has all the type properties of a class. In fact, you can see an interface as being a promise that a particular class can be trusted to act "as if" it were another class.
public interface VeebleFeetzer { /* ... */ };
public class FoodDispenser implements VeebleFeetzer { /* ... */ }
public class MissleController implements VeebleFeetzer { /* ... */ }
public class FloorWax implements VeebleFeetzer { /* ... */ }
public class DessertTopping implements VeebleFeetzer { /* ... */ }
All you have to do now is use a reference to a VeebleFeetzer, and the compiler figures it out for you. If you happen to add another class that's a subtype of VeebleFeetzer, the compiler will select the method and check the arguments in the bargain
VeebleFeetzer x; // A reference to anything
// that implements VeebleFeetzer
// Some code that assigns something to x
x.dropPellet();
// Some more code
x.launchAt("Moon");
This isn't so much duck typing as it is just proper object-oriented style; indeed, being able to subclass class A and call the same method on class B and have it do something else is the entire point of inheritance in languages.
If you're constantly checking the type of an object, then you're either being too clever (though I suppose it's this cleverness that duck typing aficionados enjoy, except in a less brittle form) or you're not embracing the basics of object-oriented programming.
hmmm...
correct me if I am wrong but tagged classes and duck-typing are two different concepts though not necessarely mutally exclusive.
When one has the urge of using tags in a class to define the type then one should, IMHO, revise their class hiearchy as it is a clear sing of conceptual bleed where an abstract class needs to know the the implementation details that the class parenthood tries to hide. Are you using the correct pattern ? In other words are you trying to coerce behaviour in a pattern that does not naturally support it ?
Where as duck-typing is the ability to loosely define a type where a method can accept any types just so long as the necessary methods in the parameter instance are defined. The method will then use the parameter and call the necessary methods without too much bother on the parenthood of the instance.
So here... the smelly hint is, as Charlie pointed out, the use of instanceof. Much like static or other smelly keywords, whenever they appear one must ask "Am I doing the right thing here ?", not that they are inhertitly wrong but they are oftenly used to hack through a bad or ill fitted OO desing.
My one line response would be that you lose one of the main benefits of OOP: polymorphism. This reduces the time to develop new code (developers love to develop new code, so that should help your argument :-)
If, when adding a new type to an existing system, you have to add logic, aside from figuring out which instance to construct, then, in Java, you are doing something wrong (assuming that the new class should simply be a drop in replacement for another).
Generally, the appropriate way to handle this in Java is to keep the code polymorphic and make use of interfaces. So anytime they find themselves wanting to add another variable or do an instanceof they should probably be implementing an interface instead.
If you can convince them to change the code it is pretty easy to retrofit interfaces into the existing code base. For that matter, I'd take the time to take a piece of code with instanceof and refactor it to be polymorphic. It is much easier for people to see the point if they can see the before and after versions and compare them.
You might want to point your co-worker to the Liskov substitution principle, one of the five pillars in SOLID.
Links:
Wikipedia entry
Article written by Uncle Bob
When you say "duck typing in strongly-typed languages" you actually mean "imitating (subtype) polymorphism in statically-typed languages".
It's not that bad when you have data objects (DTOs) that don't contain any behaviour. When you do have a full-blown OO model (ask yourself if this is really the case) then you should use the polymorphism offered by the language where appropriate.
Although I'm generally a fan of duck-typed languages like python, I can see your problem with it in java.
If you are writing all the classes that will ever be used with this code, then you don't need to duck-type, because you don't need to allow for cases where code can't directly inherit from (or implement) an interface or other unifying abstraction.
A downside of duck-typing is that you have an extra class of unit tests to run on your code: a new class could return a different type than expected, and subsequently cause the rest of the code to fail. So although duck-typing allows backward-flexibility, it requires a lot of forward thinking for tests.
In short you have a catch-all (hard) instead of a catch-few (easy). I think that's the pathology.
Why "imitate a class hierarchy" instead of designing and using it? One of the refactoring methods is replacing "switch"es (chained ifs are almost the same) with polymorphism. Why use switches where polymorphism would lead to cleaner code?
This isn't duck typing, it is just a bad way to simulate polymorphism in a language that has (more or less) real polymorphism.
Two arguments to answer the titled question:
1) Java is supposed to be "write once, run anywhere," so code that was written for one hierarchy shouldn't throw RuntimeExceptions when we change the environment somewhere. (Of course, there are exceptions -- pun -- to this rule.)
2) The Java JIT performs very aggressive optimizations that rely on knowing that a given symbol must be of one type and one type only. The only way to work around this is to cast.
As others have mentioned, your "instance of" doesn't match with the question I've answered here. Anything with any types, duck or static, may have the issue you described. There are better OOP ways to deal with it.
Instead of instanceof you can use the Method- and the Strategy-Pattern, mixed together the code looks much better than before...
Before the introduction to generics to the Java language I would have written classes encapsulating collections-of-collections-of-collections. For example:
class Account {
private Map tradesByRegion; //KEY=Region, VALUE=TradeCollection
}
class TradeCollection {
private Map tradesByInstrument; //KEY=Instrument, Value=Trade
}
Of course, with generics, I can just do:
class Account {
private Map<Region, Map<Instrument, Trade>> trades;
}
I tend to now opt for option #2 (over a generified version of option #1) because this means I don't end up with a proliferation of classes that exist solely for the purpose of wrapping a collection. But I have a nagging feeling that this is bad design (e.g. how many nested collections should I use before declaring new classes). Opinions?
2 is better because:
Less code accomplishes the same
effect (better, actually, as in #1
some of your type information exists
only in comments)
It's completely clear what's going
on.
Your type errors will be caught at compile time.
What is there to recommend 1? admittedly the Map< Integer , < Map < String, < Map< ... generics are a bit hard to get used to, but to my eye it's much easier to understand than code with maps, and lists of maps, and maps of lists of maps, and custom objects full of lists of maps.
Combination of the two. While you can use generics to replace custom classes, you still will want to use a class to encapsulate your concepts. If you're just passing maps of maps of maps of lists to everything, who controls what you can add? who controls what you can remove?
For holding the data, generics is a great thing. But you still want methods to validate when you add a trade, or add an account, and without some kind of class wrapping your collections, nobody controls that.
Normally there will also be some code to operate on the collections. When this becomes nontrivial I package up the collection with the behavior in a new class. The deeper the nesting is the more likely this will be the case.
I have made this simple rule for me: Never more than two <'s and two commas in a generics declaration and preferably only one comma. After that I introduce custom types. I think this is the point where the readability suffers enough to warrant additional concepts.
There is a real good reason to avoid too deep generics: The complexity is not only in the actual declaration but usually tends to be equally visible in the construction logic. So a lot of code has a tendency to become convoluted if you nest these declarations too deeply. Creating intermediate classes can help a lot. The trick is often to find the proper intermediate classes.
I definitely think you should go a slight bit back towards your old standard. Actually your second sample is the exact pain-point where I'd still accept generics-only.
I think it's better to keep objects in mind and emphasize the collections a bit less. Reification is your friend.
For example, it's natural to have Student and Course objects if you're modeling a system for a school. Where should grades be captured? I'd argue that they belong in an object where Student and Course meet - a ReportCard. I wouldn't have a GradeCollection. Give it some real behavior.
I prefer #2. It is clearer what is going on, and is typesafe at compile time (I prefer having as many things go wrong at compile time as possible, as opposed to having them happen at runtime... in general I like it when nothing goes wrong).
Edit:
Well there are two ways that I can see... I guess it depends on which you would use:
class Account
{
private Map<Region, TradeCollection> tradesByRegion;
}
class TradeCollection
{
private Map<Instrument, Trade> tradesByInstrument;
}
or
class Account<R extends Region, I extends Instrument, T extends Trade, C extends TradeCollection<I, T>>
{
private Map<R, C> tradesByRegion;
}
class TradeCollection<I extends Instrument, T extends Trade>
{
private Map<I, T> tradesByInstrument;
}
I think the answer to this is that it depends on the situation. Generally, introducing a type is useful if that also introduces methods related to the type, if those intermediate types are passed around independently, etc.
You might find this bit of advice from Rich Hickey (the creator of Clojure) about creating interoperable libraries kind of interesting:
http://groups.google.com/group/clojure/browse_thread/thread/e0823e1caaff3eed
It's intended as specific advice to Clojure library writers but I think is interesting food for thought even in Java.