2

I have some closed component which is working over some XML object. I need to expose this object outside of this component, but I don't want to allow changes on it outside of my component. How can I complete this?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
bel
  • 439
  • 1
  • 5
  • 17
  • Make the class and all its fields `final`. This way you can create the object and initialize all fields just one time, you won't be able to modify the attributes. – BackSlash Apr 16 '14 at 07:52

3 Answers3

4

Ensure your object has a copy constructor that allows you to make a deeply-cloned copy of your class.

Then call this when you return the object, e.g.

SomeClass instance = // ....


public SomeClass getInstance() {
  return new SomeClass(instance);
}

This won't make the returned object immutable. But it doesn't need to be - you just don't want the external code making changes to your copy of the data.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • The accepted solution is more like suggested here. I just created new object from class object and return it from method. – bel Apr 16 '14 at 11:23
  • 1
    The semantics of returning a mutable object are a bit muddy, since it's not obvious whether the object may safely be regarded as a view of an object owned by the supplier, as a new object independent from the supplier, or neither. If the method is returning a new instance, I prefer to explicitly say that in the name. – supercat Apr 16 '14 at 18:00
2

Well, here is the access level's advocate ;-)

If you just wish to prevent the caller from making changes, it doesn't mean that it has to be immutable [in your package] - it just means that it shouldn't have a [public] way to mutate it :) I'm actually a growing fan of returning a limiting public interface.

For instance:

// Option A with a "limiting public interface"
public interface Awesome {
    public String getText();
}

class MyAwesome implements Awesome {
    public String getText() {
       // ..
    }
    // Option B is to make setText non-public
    public void setText() {
       // ..
    }
}

Then your code can return Awesome which doesn't [directly] provide a way mutate the object.

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • +1 I tend to forget about this pattern, but I'm starting to like it too. – Duncan Jones Apr 16 '14 at 08:17
  • One difficulty with this approach is that it provides no indication to the caller as to whether the returned object may be persisted as a means of persisting its state. – supercat Apr 16 '14 at 17:54
1

I think you need to create another class which is immutable, taking your object as a parameter (maybe in constructor). Then you should only expose the instance of your new class.

Here's some tips to make an object immutable: Immutable class?

Community
  • 1
  • 1
Utku Özdemir
  • 7,390
  • 2
  • 52
  • 49
  • "*Then you should only expose the instance of your new class*" > Can you explain this sentence? – Duncan Jones Apr 16 '14 at 07:56
  • Sure, the asker needs to expose an object: `"I need to expose this object outside of this component"`. I am telling that he/she should create another class, which is immutable, create an instance of that new class and expose that newly created object instead of the object he wanted to expose. – Utku Özdemir May 20 '14 at 00:22