0

I have a big repository of data, thousands of objects. Here's a simplified interface:

public interface Score {
    public Float getValue();
    public void setValue(Float newValue);
}

Now, the big repository holds these objects in indexes for fast retrieval, so it's important that setValue not be called outside of the repository context. In fact, I don't want clients of the repository to change any part of the score objects.

At first I thought that I should return copies of the Scores, but that would get pretty expensive - the data is queried often. My next idea is making an UnmodifiableScore interface:

public interface UnmodifiableScore {
    public Float getValue();
}

public interface Score extends UnmodifiableScore {
    public void setValue(Float newValue);
}

Then, my repository could return UnmodifiableScores.

Clearly, clients to the code could cast down to Scores and change values at their will. It would still be possible to change the values in the central repository and break the whole thing. But it would save a LOT of copying.

I think for our purposes, the naming convention will be enough to remind us not to modify the scores. If we release code as a library, though, I'm not as confident. Is there some way to make it so that only a few privileged classes can see the read/write interface? This central repository needs it, and my server needs it (two different packages), but everyone else can make do with the read-only interface. Is there any clever way to do this? Any analog of friend from C++?

Riley Lark
  • 20,660
  • 15
  • 80
  • 128

3 Answers3

1

I would seriously consider making Score immutable. It makes reasoning about your program much easier, and you don't have to worry about changes made by other code.

PS A note on class names: UnmodifiableScore would be better called ReadableScore, because a subclass isn't necessarily unmodifiable.

artbristol
  • 32,010
  • 5
  • 70
  • 103
0

In java there is no equivalent for friend.

More info at : Is there a way to simulate the C++ 'friend' concept in Java?

Now given that, you need to change your design in order to prevent client from making modification to data, you can provide a client ClientScoreView interface where you dont have setter and make Score as package protected or protected so that client doesnt get hold of Score.

Community
  • 1
  • 1
mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • But if I make `Score` package protected or protected I can only use it from within a single package, right? I need it in two different packages - my client-side datastore, and my server-side datastore. – Riley Lark Dec 14 '11 at 16:05
0

It is possible to create a Score Class (not interface) that has a set method that is package private, allowing you to lock down the number of classes that can call the set method. This is somewhat limiting for you, but doable.

The down-side is that if someone is willing to actually downcast in your example, they may be just as willing to use reflection to get at the value as well.

rfeak
  • 8,124
  • 29
  • 28