HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

java.util.Observable but with generics to avoid casts

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
utilwithbutcastsjavaobservableavoidgenerics

Problem

This is an Observable class similar to java.util.Observable. The difference is that it uses generics to avoid casts. The question is: Is it really worth the effort? What are the problems with this code?

```
import java.util.ArrayList;
import java.util.Collection;

/**
* like java.util.Observable, But uses generics to avoid need for a cast.
*
* For any un-documented variable, parameter or method, see java.util.Observable
*/
public class Observable {
private boolean changed = false;

// Holds registered observers.
// @TODO if class is not final can we make this protected? (should we?).
private final Collection> observers;

/**
* observersSet gives the opportunity of changing the implementing set. The
* benefit is, final user can specify the 'order' of observers notified.
* Generally, not a good idea at all.
*
* @TODO should this be private and the class final?.
*/
protected Observable(Collection> observersSet) {
this.observers = observersSet; }

public static ObservablegetInstance() {
// return getInstance(container);
ArrayList> container = new ArrayList<>();
return new Observable<>(container);
}

/**
* Before this method can be actually used, this.update(T arg) must be fixed.
* It has a hard-coded ArrayList. Generally, not a good idea, not at all.
*
* User would expect the call getInstance(ArrayList ar) to
* work however it wont. It must be:
* getInstance(ArrayList ar);
*
* It's bad, ugly, and more importantly, violating.
*
* Unless of course the first example could be made to work. Maybe a cast
* will do.
*/
@SuppressWarnings("UnusedParameters")
public static Observable
getInstance(Collection> observersSet) {
throw new UnsupportedOperationException("Not yet implemented.");
// return new Observable<>(observersSet);
}

// @TODO null check maybe for add?
public synchronized boolean add(final Observer o)

Solution

Pick a convention for your curly brackets/indentation and stick with it. You code has all of the following:

  • Brackets included, one-lined statement



  • Brackets omitted, one-lined statement



  • New line after opening bracket, closing bracket on same line.



  • New line after opening bracket, closing bracket on different line.



  • Un-indented code inside brackets.



  • Padding spaces to vertically aligning opening brackets (with multiple different vertical lines being padded to).



  • Single space padding opening brackets.



  • Blank line before closing bracket.



The Java convention is:

public synchronized boolean add(final Observer o) {
   return !this.observers.contains(o) && observers.add(o);
}


It is best to always include curly brackets even when they could be omitted. If you start with an if that does not include brackets and then need to add a second line, forgetting to would have the second line execute unconditionally.

It is safer to synchronize on a private instance variable than on the class instance. You have no control over what someone does with the instance of your class. Maybe they think it would be a good idea to use it to synchronize some other code. Now you have two different pieces of code using the same lock instance that might be result in a deadlock because they are not coordinated properly. A private lock variable guarantees that this can't happen.

You have to synchronize all accesses to observers. countObservers() could be called while you are adding or removing an observer.

Don't create aliases for your methods. It will only lead to confusion if there are multiple ways to do the same things.

observersSet is not a Set Don't make the argument name appear as if it is expecting one. If you do want it to be a set (you might since you are checking for duplicates in add()), then change the type from Collection to Set. If you need observers to be called in the order in which they were added, LinkedHashSet satisfies this requirement. If you accept any Collection when creating the instance, there is nothing to prevent the collection from already containing a duplicate.

Code Snippets

public synchronized boolean add(final Observer<? super T> o) {
   return !this.observers.contains(o) && observers.add(o);
}

Context

StackExchange Code Review Q#76924, answer score: 5

Revisions (0)

No revisions yet.