When you define an enum for something that can be "undefined" in your interfaces, should you
define a separate enum value for that, or
just use enumValue = null for those situations?
For example,
serviceX.setPrice(Price priceEnum)
enum Price {
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE, UNKNOWN
}
and priceEnum.UNKNOWN when needed
or
enum Price {
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE
}
and priceEnum = null when needed?
Having a little debate on this. Some points that come to mind:
using Price.UNKNOWN saves some "if (price == null)" code. You can handle Price x's all values in a single switch-case
Depending on view technology, it may be easier to localize Price.UNKNOWN
using Price.UNKNOWN kind of causes "magic number" problem in the code, IMO. Here we have Price.UNKNOWN, elsewhere maybe Color.UNDEFINED, Height.NULLVALUE, etc
using priceValue = null is more uniform with how other data types are handled in Java. We have Integer i = null, DomainObject x = null, String s = null for unknown values as well, don't we?
Price.UNKNOWN forces you to decide whether null value is allowed univerally for all use cases. We may have method Price getPrice() which may return Price.UNKNOWN and setPrice(Price p) which is not allowed to accept Price.UNKNOWN. Since Price.UNKNOWN is always included in the enum's values, those interfaces look a little unclean. I know priceValue = null has the same problem (you cannot define in the interface whether null is accepted or not) but it feels a little cleaner and a little less misleading(?)
This is actually an example of applying Null Object pattern. IMHO it is always better to have a dummy object rather than null. For instance you can add dummy methods to null-object rather than scattering your code with null-checks all over the place. Very convenient.
Also the name of the enum gives you some additional semantics: is the price unknown, undefined, not trustworthy, not yet known? And what does it mean if the price is null?
UPDATE: As Aaron Digulla points out, Null Object pattern requires memory. But this isn't actually the case most of the time. In the traditional implementation you typically have a singleton for Null object used everywhere as there is no need for separate instances. It gets even better with enums because you get singleton semantics for free.
Another point is that null reference and reference to some object occupy the same amount of memory (say 4 bytes on 32-bit machine). It is the object being referenced that occupies some extra memory. But if this is a singleton, there is practically no memory overhead here.
I'd say go with Price.UNKNOWN if that's a valid value for a price.
I agree with the drawbacks of dealing with null references that you mention, and I think they motivate the decision enough.
New languages, take Scala for example (and some older ones, Haskell) strain away from null references all together and uses option / maybe monads instead... for good reasons.
It depends how are you going to use this enum. If you use it in switch/case statements it does not matter.
If you create method(s) into the enum you actually must define UNKNOWN.
For example you can define abstract method
public abstract Icon icon();
into your enum and then implement this method for each member of Price. Probably you will want to display question mark for unknown price. In this case just implement method icon() that creates appropriate icon.
There is the Enum-Switch-Null-Trap.
So it seems that just like with any property that is an object,
if it doesn't exist then it is null.
Color or Height would be used in the program logic. Them cannot handle with an undefined color.
A Price is userdata and may be unknown.
The color may be userdata else, but to be used as color in the code, they must be defined.
So Price may be UNKNOWN (instead of null), Color not (null may indicate error).
Related
When I should go for wrapper class over primitive types? Or On what circumstance I should choose between wrapper / Primitive types?
Others have mentioned that certain constructs such as Collections require objects and that objects have more overhead than their primitive counterparts (memory & boxing).
Another consideration is:
It can be handy to initialize Objects to null or send null parameters into a method/constructor to indicate state or function. This can't be done with primitives.
Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.
This will also set the scene for a NullPointerException when something is being used incorrectly, which is much more programmer-friendly than some arbitrary bug down the line.
Generally, you should use primitive types unless you need an object for some reason (e.g. to put in a collection). Even then, consider a different approach that doesn't require a object if you want to maximize numeric performance. This is advised by the documentation, and this article demonstrates how auto-boxing can cause a large performance difference.
In my opinion, if my class members are wrapper variables, it does not rely on default values, which is developer friendly behavior.
1.
class Person {
int SSN ; // gets initialized to zero by default
}
2.
class PersonBetter {
Integer SSN; //gets initialized to null by default
}
In the first case, you cannot keep SSN value uninitialized. It may hurt if you are not checking if the value was set before you attempt to use it.
In the second case, you can keep SSN initialized with null. Which can lead to NullPointerException but it is better than unknowingly inserting default values(zero) as SSN into to the database whenever you attempt to use it without initializing SSN field.
I would only use the wrapper types if you have to.
In using them you don't gain much, besides the fact that they are Objects.
And, you lose overhead in memory usage and time spent boxing/unboxing.
Practically I had encountered a situation where use of wrapper class can be explained.
I created a service class which had a long type variable
If the variable is of type long - when not initialized, it will be set to 0 - this will be confusing to the user when displayed in GUI
If the variable is of type Long - when not initialized, it will be set to null - this null value won't show up in GUI.
This applies to Boolean as well where values can be more confusing when we use primitive boolean(as default value is false).
Collections are the typical case for the simple Java wrapper objects. However, you might consider giving the Wrapper a more specific meaning in the code (value object).
IMHO there's almost always a benefit to use value objects when it boils down to readability and maintainance of the code. Wrapping simple data structures inside of objects when they have certain responsibilities often simplifies the code. This is something that is very important in Domain-Driven Design.
There is of course the performance issue, but I tend to ignore that until I have the possibility to measure the performance with proper data and do more directed actions towards the problematic area. It might also be easier to understand the performance issue if the code is easy to understand as well.
performance of applications that are dominated by numerical calculations can benefit greatly from the use of primitives.
primitive types, one uses the == operator, but for wrapper the preferred choice is to call the equals() method.
"Primitive types considered harmful" because they mix "procedural semantics into an otherwise uniform object-oriented model.
Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.
If you want to use Collections, you must use Wrapper classes.
Primitive types, are used for arrays. Also, to represent data that has no behaviour,for example, a counter, or a boolean condition.
Since autoboxing, the "when to use primitive or wrapper" frontier has become quite fuzzy.
But remember, Wrappers are objects, so you get all the fancy Java features. For example, you can use reflexion to create Integer objects, but not int values. Wrapper classes also have methods such as valueOf.
When to Use Primitive Types
When doing a large amount of calculations, primitive types are always faster — they have much less overhead.
When you don’t want the variable to be able to be null.
When you don’t want the default value to be null.
If the method must return a value
When to Use Wrapper Class
When you are using Collections or Generics — it is required
If you want the MIN_SIZE or MAX_SIZE of a type.
When you want the variable to be able to be null.
When you want to default value to be null.
If sometimes the method can return a null value.
from https://medium.com/#bpnorlander/java-understanding-primitive-types-and-wrapper-objects-a6798fb2afe9
If you want to create a value type. Something like a ProductSKU or AirportCode.
When a primitive type (string in my examples) defines equality, you'll want to override equality.
Primitive values in Java are not object. In order to manipulate these values as object the java.lang package provides a wrapper class for each of the primitive data type.
All Wrapper classes are final. The object of all wrapper classes that can be initiated are immutable that means the value in the wrapper object can not be changed.
Although, the void class is considered a wrapper class but it does not wrap any primitive values and is not initiable. It does not have public constructor, it just denotes a class object representing the keyword void.
Assuming we have an object inside an object, inside another object, what is the best way to retrieve the value of a private variable outside the two objects?
The simplest way seems to be to do something like this:
object1.object2.object3.getvalue();
Is this acceptable? Or would it be better to call a method which calls a method, which calls a method?
The second option seems unnecessarily laborious, considering you would basically be having the same method created in 3 different classes.
use getter to get any object
ex: Object obj = object1.getObject2().getObject3();
It depends on your definition of "acceptable". It may be acceptable in your case. It is hard to tell without proper context.
However, there are something you may consider, level-by-level:
1. Use of getters
Although such kind of getters are still far from satisfactory, it is still better than using direct property access
i.e. Instead of accessing object1.object2 by direct field access, provide Object2 getObject2() in Object1, so that the code looks like:
object1.getObject2().getObject3().getValue()
2. Null handling
Usually when we chained such kind of property navigation, we will have problem that in some level, null is returned, which makes object1.getObject2().getObject3().getValue() throwing NPE.
If you are using Java 8, consider returning Optional<>. e.g. in Object1, getter of object2 should look like Optional<Object2> getObject2()
With such change, your code can be made null-safe by something like:
Value value = object1.getObject2()
.flatMap(Object2::getObject3)
.map(Object3::getValue)
.orElse(Value.emptyValue())
3. Law of Demeter
In order to make a more loosely-coupled design, you may want to provide access to that value in API of Object1, instead of exposing multiple levels of indirection. Hence:
Value value = object1.getFooValue();
(Keep using Optional<> if it fit your need)
for which internally it retrieve the value from Object3. (Of course, Object2 may also want to do something similar)
4. Getter is evil
Always remember you should try to avoid providing internal representation of your object. Your objects should provide meaningful behavior instead of simply act as a value object for you to get or set data. It is hard to give an example here but ask yourself, why do you need to get the value for? Is that action more appropriate to be provided by your object itself?
The best way is to not think of your objects as data stores. A class should be defined to have some work to do, some cluster of related responsibilities. In order to perform that work to fulfill those responsibilities some internal data may be kept, and some nested objects contained. Serving out data should not be the goal of your objects, generally speaking.
Encapsulation
The whole idea of encapsulation in object-oriented programming is to not expose that internal data and nested objects. Instead publish the various available chores by declaring methods on your higher/outer object. Encapsulation frees you to change those internals without breaking the outside calling code – avoiding fragility is the goal.
For example, an Invoice object can contain a collection of LineItem objects. In turn each LineItem object contains other objects for product, quantity, price, extended cost, taxability, tax rate, tax amount, and line cost. If you want to know the total amount of sales tax added across the items, instead of asking the Invoice for the LineItem, and then asking the LineItem for TaxAmount object, define this chore as a method on Invoice, getTotalTaxAmount. Let that method figure out (and keep to itself!) how to go through the contained objects to collect the relevant information.
If you absolutely must expose that nested data, again define a method at the highest level that returns a copy of the desired data or a collection of the desired objects (probably copies of those objects). Again, the goal is to avoid exposing the objects within objects within objects.
Then, within that highest method, as the correct Answer by Raaga stated, define a getter that calls a getter.
Getter Methods versus Direct Member Access
In a very simple structure of data you could access the objects directly. But generally better to use getter methods. Again the reason is encapsulation. Having a getter method allows you the flexibility of redefining the implementation details of the stored data.
For example, presently you could store the "Sex" variable as a String with values of "F" or "M". But later you may decide to take advantage of Java's nifty enum feature. So you replace those single-character "F" & "M" strings with enum instances Sex.FEMALE and Sex.MALE. Having a getter provides a level of insulation, so the Strings can be replaced internally with enums. The getter method continues to return a String (and internally translating the enum to an "F" or "M" String to be returned). This way you can work on restructuring your class without breaking those dependent outside objects.
object1.object2.object3.getvalue();
This chaining seems incorrect...Object chaining under such scenario is always object1.someMethod().someOtherMethod(). Or something like suggested above in an answer using getter object1.getObject2().getObject3().
I hope it helps.
What you described may be the simplest way (if object2 and object3 are accessible) but it is definitely not the way to go. As Raaga pointed out getters are a lot better to retrieve members of a class and these members should then be private or protected to prevent errors.
If you can do
object1.object2.object3.getvalue();
you can also do something like
object1.object2 = null;
which is most likely not what you want to allow. This is one of the basic concepts of object oriented programming. Classes should handle their implementation details / secrets and not directly offer them to the outside! This is what getters/setters are for.
This way you have more control over the access and what can be done and what can't. If you should only be able to retrieve object2 from object1 but not be able to change it, you can only offer a getter and no setter.
If you should also be able to change it, it is also better to use setter for more control, because you can do checking in your setter to prevent my example where I put a null pointer as your object2
And just in case you worry about efficiency that calling a method might not be as efficient as directly accessing a member, you can rely on Java to internally optimize your method call that it is not any slower than the direct access.
I'm in the middle of QA'ing a bunch of code and have found several instances where the developer has a DTO which implements Comparable. This DTO has 7 or 8 fields in it. The compareTo method has been implemented on just one field:
private DateMidnight field1; //from Joda date/time library
public int compareTo(SomeObject o) {
if (o == null) {
return -1;
}
return field1.compareTo(o.getField1());
}
Similarly the equals method is overridden and basically boils down to:
return field1.equals(o.getField1());
and finally the hashcode method implementation is:
return field1.hashCode;
field1 should never be null and will be unique across these objects (i.e. we shouldn't get two objects with the same field1).
So, the implementations are consistent which is good, but should I be concerned that only one field is used? Is this unusual? Is it likely to cause problems or confuse other developers? I'm thinking of the scenario where a list of these objects are passed around and another developer uses a Map or Set of somesort and gets unusual behaviour from these objects. Any thoughts appreciated. Thanks!
I suspect that this is a case of "first use wins" - someone needed to sort a collection of these objects or put them in a hash map, and they only cared about the date. The easiest way of implementing that was to override equals/hashCode and implement Comparable<T> in the way you've said.
For specialist sorting, a better approach would be to implement Comparator<T> in a different class... but Java doesn't have any equivalent class for equality testing, unfortunately. I consider it a major weakness in the Java collections, to be honest.
Assuming this really isn't "the one natural and obvious comparison", it certainly smells in terms of design... and should be very carefully document.
Strictly speaking, this violates the Comparable spec:
http://download.oracle.com/javase/6/docs/api/java/lang/Comparable.html
Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.
Similarly, it looks like the equals method will throw NPE on equals(null) instead of returning false (unless of course you "boiled" out the null handling code).
Is it likely to cause problems or confuse other developers?
Possibly, possibly not. It really depends on how large your project is and how widespread/"reusable"/long-lived your object source code is expected to be used:
Small/short-lived/limited use == probably not a problem.
Large/long-lived/widespread use == counter-intuitive implementation may cause future problems
You shouldnt be concerned with it, if field1 is really unique. If it`s not, you may have problems. Anyway, my advise is to do some unit tests. They should show the truth.
I don't think you need to be concerned. The contract between the three methods is kept and it's consistent.
Whether it's correct from a business logic point of view is a different question.
If e.g. field1 maps to a primary key in the database it's perfectly valid. If field1 is the "firstname" of a person, I would be concerned
When I should go for wrapper class over primitive types? Or On what circumstance I should choose between wrapper / Primitive types?
Others have mentioned that certain constructs such as Collections require objects and that objects have more overhead than their primitive counterparts (memory & boxing).
Another consideration is:
It can be handy to initialize Objects to null or send null parameters into a method/constructor to indicate state or function. This can't be done with primitives.
Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.
This will also set the scene for a NullPointerException when something is being used incorrectly, which is much more programmer-friendly than some arbitrary bug down the line.
Generally, you should use primitive types unless you need an object for some reason (e.g. to put in a collection). Even then, consider a different approach that doesn't require a object if you want to maximize numeric performance. This is advised by the documentation, and this article demonstrates how auto-boxing can cause a large performance difference.
In my opinion, if my class members are wrapper variables, it does not rely on default values, which is developer friendly behavior.
1.
class Person {
int SSN ; // gets initialized to zero by default
}
2.
class PersonBetter {
Integer SSN; //gets initialized to null by default
}
In the first case, you cannot keep SSN value uninitialized. It may hurt if you are not checking if the value was set before you attempt to use it.
In the second case, you can keep SSN initialized with null. Which can lead to NullPointerException but it is better than unknowingly inserting default values(zero) as SSN into to the database whenever you attempt to use it without initializing SSN field.
I would only use the wrapper types if you have to.
In using them you don't gain much, besides the fact that they are Objects.
And, you lose overhead in memory usage and time spent boxing/unboxing.
Practically I had encountered a situation where use of wrapper class can be explained.
I created a service class which had a long type variable
If the variable is of type long - when not initialized, it will be set to 0 - this will be confusing to the user when displayed in GUI
If the variable is of type Long - when not initialized, it will be set to null - this null value won't show up in GUI.
This applies to Boolean as well where values can be more confusing when we use primitive boolean(as default value is false).
Collections are the typical case for the simple Java wrapper objects. However, you might consider giving the Wrapper a more specific meaning in the code (value object).
IMHO there's almost always a benefit to use value objects when it boils down to readability and maintainance of the code. Wrapping simple data structures inside of objects when they have certain responsibilities often simplifies the code. This is something that is very important in Domain-Driven Design.
There is of course the performance issue, but I tend to ignore that until I have the possibility to measure the performance with proper data and do more directed actions towards the problematic area. It might also be easier to understand the performance issue if the code is easy to understand as well.
performance of applications that are dominated by numerical calculations can benefit greatly from the use of primitives.
primitive types, one uses the == operator, but for wrapper the preferred choice is to call the equals() method.
"Primitive types considered harmful" because they mix "procedural semantics into an otherwise uniform object-oriented model.
Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.
If you want to use Collections, you must use Wrapper classes.
Primitive types, are used for arrays. Also, to represent data that has no behaviour,for example, a counter, or a boolean condition.
Since autoboxing, the "when to use primitive or wrapper" frontier has become quite fuzzy.
But remember, Wrappers are objects, so you get all the fancy Java features. For example, you can use reflexion to create Integer objects, but not int values. Wrapper classes also have methods such as valueOf.
When to Use Primitive Types
When doing a large amount of calculations, primitive types are always faster — they have much less overhead.
When you don’t want the variable to be able to be null.
When you don’t want the default value to be null.
If the method must return a value
When to Use Wrapper Class
When you are using Collections or Generics — it is required
If you want the MIN_SIZE or MAX_SIZE of a type.
When you want the variable to be able to be null.
When you want to default value to be null.
If sometimes the method can return a null value.
from https://medium.com/#bpnorlander/java-understanding-primitive-types-and-wrapper-objects-a6798fb2afe9
If you want to create a value type. Something like a ProductSKU or AirportCode.
When a primitive type (string in my examples) defines equality, you'll want to override equality.
Primitive values in Java are not object. In order to manipulate these values as object the java.lang package provides a wrapper class for each of the primitive data type.
All Wrapper classes are final. The object of all wrapper classes that can be initiated are immutable that means the value in the wrapper object can not be changed.
Although, the void class is considered a wrapper class but it does not wrap any primitive values and is not initiable. It does not have public constructor, it just denotes a class object representing the keyword void.
I recently watched this youtube tutorial on the Null Object design pattern. Even though there were some errors in it: such as the NullCar that doesn't do anything creates an infinite loop, the concept was well explained. My question is, what do you do when the objects that can be null have getters, and are used in your code? How do you know which value to return by default? Or should I implement this pattern inside all the objects? What if I need to return strings or primitives? I'm talking from a Java perspective.
EDIT: won't I be trading null objects testing for default value testing ? If not , why not ?
The objective of a Null Object is to avoid having Null references in the code. The values returned by Null Object getters depend on your domain. Zero or empty string are usually appropriate.
If we transpose the Null Object pattern to real life, what you're asking is similar to ask "how old is nobody ?".
Perhaps your design can be improved as you seem not to follow the tell, don't ask principle.
EDIT: the Null Object design pattern is typically used when an object delegates behavior to another object (such as in Strategy or State Design Patterns) ; as Tom Hawtin - tackline commented, use Special Case Objects for objects returning values.
As far as I've understood it the idea is that the null object's value is as close to "nothing" as possible. That unfortunately means you have to define it yourself. As an example I personally use "" when I can't pass a null String, null object number for me is -1 (mostly because by default most database sequences start at 1 and we use those for item id:s a lot so -1 is dead giveaway it's a null object), with lists/maps/sets it's Collections.EMPTY_SET, EMPTY_MAP or EMPTY_LIST and so on and so forth. If I have custom class I have to create a null object from, I remove all actual data from it and see where that takes me and then apply what I just mentioned until it's "empty".
So you really don't "know" which value to return by default, you just have to decide it by yourself.
what do you do when the objects that can be null have getters , and are used in your code ? How do you know which value to return by default ?
How do you know which classes to implement? This is a design question, it depends on the application.
Generally speaking the purpose of the NullObject pattern is to support a Replace Conditional with Polymorphism refactoring in the special case where the the conditional is a comparison against the null value of the programming language.
A correct implementation of the example in the video would require delegating the driveCar method to the Car classes. The SlowCar and FastCar classes would perform the loop, presumably through a shared implementation in a base class, and the NullCar would just return immediately.
In a Java context, the NullCar.speed attribute would probably be an unboxed int. So setting it to null is not an option. I would probably hide the attribute behind accessor, and have NullCar.getSpeed raise an exception. Any client code that would need a test to avoid this exception would instead move into the car classes.
Delegating all operations that directly depend on a speed value being available is an application of the Tell Don't Ask principle of object-oriented design mentioned by philippe
What should be the integration point of Null design pattern in code ? I think that DAO objects are the fisrt level client for this design pattern as they lookup an entity in database and return it simply.
The nullability check of these objects pollute the code in service layer or command layer where they are actually accessed and used.
Please comment.
It should return the null object for the class you are getting. For example, if you have a class A with a getter that returns an object of class B, then the corresponding NullA's getter should return NullB.