You are viewing a plain text version of this content. The canonical link for it is here.
Posted to api@directory.apache.org by Emmanuel Lecharny <el...@apache.org> on 2010/03/13 17:02:21 UTC

Immutable objects, what's best ?

Hi,

we have many objects that we want to be immutable. What's the best solution
to produce  those immutable objets ?

- For DN, we would like to use valueOf(), and the DN() constructor, but no
setter
- For Entry, a constructor is not enough, as we may have to inject new
attributes. We may need to have two different classes, one immutable, one
mutable. The immutable class could be associated with a factory, or we can
use a constructor with the list of attributes as a parameter.
- For attributes, we have the same problem : we may have more than one
value.

DO any of you guys have a strong opinion ?

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com

Re: Immutable objects, what's best ?

Posted by Ersin Er <er...@gmail.com>.
The builder will pass all the properties that it "collected" to Entry's
constructor in one-shot when you call build(). So there is not that much
plumbing I see.

And this is a very common pattern. But you may find this complicated still.

On Sun, Mar 14, 2010 at 16:08, Emmanuel Lécharny <el...@apache.org>wrote:

> On 3/14/10 2:56 PM, Ersin Er wrote:
>
>> You might consider builder pattern with a DSL like syntax:
>>
>> Entry entry = new EntryBuilder().add("objectClass", "top").build();
>>
>> where Entry is immutable.
>>
>>
> That means you have to use a factory to build an entry, and that this
> factory returns a mutable object. To get an immutable object out of it, you
> have to call a third method.
>
> Isn't it a bit too complicated ? (even if we don't consider the last method
> to create a immutable object).
>
>
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.nextury.com
>
>
>


-- 
Ersin ER
http://www.ersiner.net

Re: Immutable objects, what's best ?

Posted by Emmanuel Lécharny <el...@apache.org>.
On 3/14/10 2:56 PM, Ersin Er wrote:
> You might consider builder pattern with a DSL like syntax:
>
> Entry entry = new EntryBuilder().add("objectClass", "top").build();
>
> where Entry is immutable.
>    
That means you have to use a factory to build an entry, and that this 
factory returns a mutable object. To get an immutable object out of it, 
you have to call a third method.

Isn't it a bit too complicated ? (even if we don't consider the last 
method to create a immutable object).


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com



Re: Immutable objects, what's best ?

Posted by Ersin Er <er...@gmail.com>.
You might consider builder pattern with a DSL like syntax:

Entry entry = new EntryBuilder().add("objectClass", "top").build();

where Entry is immutable.

On Sun, Mar 14, 2010 at 15:27, Emmanuel Lecharny <el...@gmail.com>wrote:

> On 3/14/10 2:19 PM, Stefan Seelmann wrote:
>
>> Emmanuel Lecharny wrote:
>>
>>
>>> On 3/14/10 9:46 AM, Stefan Seelmann wrote:
>>>
>>>
>>>> Emmanuel Lecharny schrieb:
>>>>
>>>>
>>>>
>>>>> Hi,
>>>>>
>>>>> we have many objects that we want to be immutable. What's the best
>>>>> solution
>>>>> to produce  those immutable objets ?
>>>>>
>>>>> - For DN, we would like to use valueOf(), and the DN() constructor,
>>>>> but no
>>>>> setter
>>>>> - For Entry, a constructor is not enough, as we may have to inject new
>>>>> attributes. We may need to have two different classes, one immutable,
>>>>> one
>>>>> mutable. The immutable class could be associated with a factory, or
>>>>> we can
>>>>> use a constructor with the list of attributes as a parameter.
>>>>> - For attributes, we have the same problem : we may have more than one
>>>>> value.
>>>>>
>>>>> DO any of you guys have a strong opinion ?
>>>>>
>>>>>
>>>>>
>>>> Entry and Attribute object created by the user of the API shouldn't be
>>>> immutable. As user of the API I want to create an Entry object and add
>>>> attribute and values to it. So the API must provide setters.
>>>>
>>>>
>>>>
>>> I came to the same conclusion, but with another idea : create two Entry
>>> objects, one for the client, one for the server. It's close to what we
>>> have on ADS, but the more I think about it, the more I find it complex
>>> and bothersome.
>>> Now, let's think about another option : what if we add a parameter in
>>> the constructor to create Immutable Entries ? Something like :
>>> Entry immutableEntry = new EntryImpl( DN, true ); // True =>  the entry
>>> is immutable ?
>>>
>>>
>>>
>>>> So I think if Entry and Attribute are interfaces we just define the
>>>> getter methods.
>>>>
>>>>
>>>>
>>> Smart ! That could do the trick, sure ! But is it better than the
>>> previous solution?
>>>
>>> My idea was to forbid a setter to be called if the Immutable flag is
>>> set, a solution I find a bit more strong than hiding the setter though
>>> the interface, but it forces the user to add a flag to the constructor.
>>>
>>> Again, what do you think is the best approach ?
>>>
>>>
>> I don't like it if a setXXX() method is provided and if I call it some
>> "YouIdiotAreNotAllowedToCallThisMethodException" is thrown.
>>
>> So IMO having the interface which provides read-only methods is best.
>>
>> And if using the EntryImpl you have all the setters and the setters work.
>>
>> Then you can obtain an immutable Entry from that EntryImpl, see below.
>>
>>
>>
>>> The default implementations of those classes (e.g. ClientEntry and
>>>> ClientAttribute) additional have setters the user can use when
>>>> constructing the objects.
>>>>
>>>> The Entry objects returned from the API (e.g. from a search) should be
>>>> immutable to protect them from being casted by the user, e.g. by
>>>> wrapping a created ClientEntry into an ImmutableEntry implementation.
>>>>
>>>>
>>>>
>>> Hmmm... Do you suggest that we should define 2 different classes ? (one
>>> immutable, one mutable). Wouldn't it be better to have one single
>>> implementation, with a limited interface, forcing the user to cast to be
>>> able to use the setters ? Or should we have a ClientEntry class
>>> extending a ServerEntry class ?
>>>
>>>
>> I wouldn't call it ClientEntry and ServerEntry, sorry that I used that
>> name before ;-)
>>
>> In the public API I would define an default implementation (not sure
>> about the name, we discussed some names before) which is mutable. This
>> implementation is used by the user because I don't think he wants to use
>> an immutable implementation.
>>
>> The immutable implementation just works like the java.util.Collections
>> class, there are static methods like unmodifyableSet(Set set). So we can
>> have some Utils class which wraps the default mutable class into an
>> immutable. Or the default Entry implmentation could provide a method
>> "toImmutableEntry()". The immutable implementation shouldn't be part of
>> the public API.
>>
>> wdyt?
>>
>>
>
> Sounds good. I will update the wiki with such a proposal.
>
>
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.nextury.com
>
>
>


-- 
Ersin ER
http://www.ersiner.net

Re: Immutable objects, what's best ?

Posted by Emmanuel Lecharny <el...@gmail.com>.
On 3/14/10 2:19 PM, Stefan Seelmann wrote:
> Emmanuel Lecharny wrote:
>    
>> On 3/14/10 9:46 AM, Stefan Seelmann wrote:
>>      
>>> Emmanuel Lecharny schrieb:
>>>
>>>        
>>>> Hi,
>>>>
>>>> we have many objects that we want to be immutable. What's the best
>>>> solution
>>>> to produce  those immutable objets ?
>>>>
>>>> - For DN, we would like to use valueOf(), and the DN() constructor,
>>>> but no
>>>> setter
>>>> - For Entry, a constructor is not enough, as we may have to inject new
>>>> attributes. We may need to have two different classes, one immutable,
>>>> one
>>>> mutable. The immutable class could be associated with a factory, or
>>>> we can
>>>> use a constructor with the list of attributes as a parameter.
>>>> - For attributes, we have the same problem : we may have more than one
>>>> value.
>>>>
>>>> DO any of you guys have a strong opinion ?
>>>>
>>>>          
>>> Entry and Attribute object created by the user of the API shouldn't be
>>> immutable. As user of the API I want to create an Entry object and add
>>> attribute and values to it. So the API must provide setters.
>>>
>>>        
>> I came to the same conclusion, but with another idea : create two Entry
>> objects, one for the client, one for the server. It's close to what we
>> have on ADS, but the more I think about it, the more I find it complex
>> and bothersome.
>> Now, let's think about another option : what if we add a parameter in
>> the constructor to create Immutable Entries ? Something like :
>> Entry immutableEntry = new EntryImpl( DN, true ); // True =>  the entry
>> is immutable ?
>>
>>      
>>> So I think if Entry and Attribute are interfaces we just define the
>>> getter methods.
>>>
>>>        
>> Smart ! That could do the trick, sure ! But is it better than the
>> previous solution?
>>
>> My idea was to forbid a setter to be called if the Immutable flag is
>> set, a solution I find a bit more strong than hiding the setter though
>> the interface, but it forces the user to add a flag to the constructor.
>>
>> Again, what do you think is the best approach ?
>>      
> I don't like it if a setXXX() method is provided and if I call it some
> "YouIdiotAreNotAllowedToCallThisMethodException" is thrown.
>
> So IMO having the interface which provides read-only methods is best.
>
> And if using the EntryImpl you have all the setters and the setters work.
>
> Then you can obtain an immutable Entry from that EntryImpl, see below.
>
>    
>>> The default implementations of those classes (e.g. ClientEntry and
>>> ClientAttribute) additional have setters the user can use when
>>> constructing the objects.
>>>
>>> The Entry objects returned from the API (e.g. from a search) should be
>>> immutable to protect them from being casted by the user, e.g. by
>>> wrapping a created ClientEntry into an ImmutableEntry implementation.
>>>
>>>        
>> Hmmm... Do you suggest that we should define 2 different classes ? (one
>> immutable, one mutable). Wouldn't it be better to have one single
>> implementation, with a limited interface, forcing the user to cast to be
>> able to use the setters ? Or should we have a ClientEntry class
>> extending a ServerEntry class ?
>>      
> I wouldn't call it ClientEntry and ServerEntry, sorry that I used that
> name before ;-)
>
> In the public API I would define an default implementation (not sure
> about the name, we discussed some names before) which is mutable. This
> implementation is used by the user because I don't think he wants to use
> an immutable implementation.
>
> The immutable implementation just works like the java.util.Collections
> class, there are static methods like unmodifyableSet(Set set). So we can
> have some Utils class which wraps the default mutable class into an
> immutable. Or the default Entry implmentation could provide a method
> "toImmutableEntry()". The immutable implementation shouldn't be part of
> the public API.
>
> wdyt?
>    

Sounds good. I will update the wiki with such a proposal.


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com



Re: Immutable objects, what's best ?

Posted by Stefan Seelmann <se...@apache.org>.
Emmanuel Lecharny wrote:
> On 3/14/10 9:46 AM, Stefan Seelmann wrote:
>> Emmanuel Lecharny schrieb:
>>   
>>> Hi,
>>>
>>> we have many objects that we want to be immutable. What's the best
>>> solution
>>> to produce  those immutable objets ?
>>>
>>> - For DN, we would like to use valueOf(), and the DN() constructor,
>>> but no
>>> setter
>>> - For Entry, a constructor is not enough, as we may have to inject new
>>> attributes. We may need to have two different classes, one immutable,
>>> one
>>> mutable. The immutable class could be associated with a factory, or
>>> we can
>>> use a constructor with the list of attributes as a parameter.
>>> - For attributes, we have the same problem : we may have more than one
>>> value.
>>>
>>> DO any of you guys have a strong opinion ?
>>>      
>> Entry and Attribute object created by the user of the API shouldn't be
>> immutable. As user of the API I want to create an Entry object and add
>> attribute and values to it. So the API must provide setters.
>>    
> I came to the same conclusion, but with another idea : create two Entry
> objects, one for the client, one for the server. It's close to what we
> have on ADS, but the more I think about it, the more I find it complex
> and bothersome.
> Now, let's think about another option : what if we add a parameter in
> the constructor to create Immutable Entries ? Something like :
> Entry immutableEntry = new EntryImpl( DN, true ); // True => the entry
> is immutable ?
> 
>> So I think if Entry and Attribute are interfaces we just define the
>> getter methods.
>>    
> Smart ! That could do the trick, sure ! But is it better than the
> previous solution?
> 
> My idea was to forbid a setter to be called if the Immutable flag is
> set, a solution I find a bit more strong than hiding the setter though
> the interface, but it forces the user to add a flag to the constructor.
> 
> Again, what do you think is the best approach ?

I don't like it if a setXXX() method is provided and if I call it some
"YouIdiotAreNotAllowedToCallThisMethodException" is thrown.

So IMO having the interface which provides read-only methods is best.

And if using the EntryImpl you have all the setters and the setters work.

Then you can obtain an immutable Entry from that EntryImpl, see below.

>> The default implementations of those classes (e.g. ClientEntry and
>> ClientAttribute) additional have setters the user can use when
>> constructing the objects.
>>
>> The Entry objects returned from the API (e.g. from a search) should be
>> immutable to protect them from being casted by the user, e.g. by
>> wrapping a created ClientEntry into an ImmutableEntry implementation.
>>    
> Hmmm... Do you suggest that we should define 2 different classes ? (one
> immutable, one mutable). Wouldn't it be better to have one single
> implementation, with a limited interface, forcing the user to cast to be
> able to use the setters ? Or should we have a ClientEntry class
> extending a ServerEntry class ?

I wouldn't call it ClientEntry and ServerEntry, sorry that I used that
name before ;-)

In the public API I would define an default implementation (not sure
about the name, we discussed some names before) which is mutable. This
implementation is used by the user because I don't think he wants to use
an immutable implementation.

The immutable implementation just works like the java.util.Collections
class, there are static methods like unmodifyableSet(Set set). So we can
have some Utils class which wraps the default mutable class into an
immutable. Or the default Entry implmentation could provide a method
"toImmutableEntry()". The immutable implementation shouldn't be part of
the public API.

wdyt?

Kind Regards,
Stefan


Re: Immutable objects, what's best ?

Posted by Emmanuel Lecharny <el...@gmail.com>.
On 3/14/10 9:46 AM, Stefan Seelmann wrote:
> Emmanuel Lecharny schrieb:
>    
>> Hi,
>>
>> we have many objects that we want to be immutable. What's the best solution
>> to produce  those immutable objets ?
>>
>> - For DN, we would like to use valueOf(), and the DN() constructor, but no
>> setter
>> - For Entry, a constructor is not enough, as we may have to inject new
>> attributes. We may need to have two different classes, one immutable, one
>> mutable. The immutable class could be associated with a factory, or we can
>> use a constructor with the list of attributes as a parameter.
>> - For attributes, we have the same problem : we may have more than one
>> value.
>>
>> DO any of you guys have a strong opinion ?
>>      
> Entry and Attribute object created by the user of the API shouldn't be
> immutable. As user of the API I want to create an Entry object and add
> attribute and values to it. So the API must provide setters.
>    
I came to the same conclusion, but with another idea : create two Entry 
objects, one for the client, one for the server. It's close to what we 
have on ADS, but the more I think about it, the more I find it complex 
and bothersome.
Now, let's think about another option : what if we add a parameter in 
the constructor to create Immutable Entries ? Something like :
Entry immutableEntry = new EntryImpl( DN, true ); // True => the entry 
is immutable ?

> So I think if Entry and Attribute are interfaces we just define the
> getter methods.
>    
Smart ! That could do the trick, sure ! But is it better than the 
previous solution?

My idea was to forbid a setter to be called if the Immutable flag is 
set, a solution I find a bit more strong than hiding the setter though 
the interface, but it forces the user to add a flag to the constructor.

Again, what do you think is the best approach ?
> The default implementations of those classes (e.g. ClientEntry and
> ClientAttribute) additional have setters the user can use when
> constructing the objects.
>
> The Entry objects returned from the API (e.g. from a search) should be
> immutable to protect them from being casted by the user, e.g. by
> wrapping a created ClientEntry into an ImmutableEntry implementation.
>    
Hmmm... Do you suggest that we should define 2 different classes ? (one 
immutable, one mutable). Wouldn't it be better to have one single 
implementation, with a limited interface, forcing the user to cast to be 
able to use the setters ? Or should we have a ClientEntry class 
extending a ServerEntry class ?


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com



Re: Immutable objects, what's best ?

Posted by Alex Karasulu <ak...@gmail.com>.
On Sun, Mar 14, 2010 at 10:46 AM, Stefan Seelmann <se...@apache.org> wrote:
> Emmanuel Lecharny schrieb:
>> Hi,
>>
>> we have many objects that we want to be immutable. What's the best solution
>> to produce  those immutable objets ?
>>
>> - For DN, we would like to use valueOf(), and the DN() constructor, but no
>> setter
>> - For Entry, a constructor is not enough, as we may have to inject new
>> attributes. We may need to have two different classes, one immutable, one
>> mutable. The immutable class could be associated with a factory, or we can
>> use a constructor with the list of attributes as a parameter.
>> - For attributes, we have the same problem : we may have more than one
>> value.
>>
>> DO any of you guys have a strong opinion ?
>
> Entry and Attribute object created by the user of the API shouldn't be
> immutable. As user of the API I want to create an Entry object and add
> attribute and values to it. So the API must provide setters.
>
> So I think if Entry and Attribute are interfaces we just define the
> getter methods.
>
> The default implementations of those classes (e.g. ClientEntry and
> ClientAttribute) additional have setters the user can use when
> constructing the objects.
>
> The Entry objects returned from the API (e.g. from a search) should be
> immutable to protect them from being casted by the user, e.g. by
> wrapping a created ClientEntry into an ImmutableEntry implementation.
>

I agree with Stefan.

-- 
Alex Karasulu
My Blog :: http://www.jroller.com/akarasulu/
Apache Directory Server :: http://directory.apache.org
Apache MINA :: http://mina.apache.org

Re: Immutable objects, what's best ?

Posted by Stefan Seelmann <se...@apache.org>.
Emmanuel Lecharny schrieb:
> Hi,
> 
> we have many objects that we want to be immutable. What's the best solution
> to produce  those immutable objets ?
> 
> - For DN, we would like to use valueOf(), and the DN() constructor, but no
> setter
> - For Entry, a constructor is not enough, as we may have to inject new
> attributes. We may need to have two different classes, one immutable, one
> mutable. The immutable class could be associated with a factory, or we can
> use a constructor with the list of attributes as a parameter.
> - For attributes, we have the same problem : we may have more than one
> value.
> 
> DO any of you guys have a strong opinion ?

Entry and Attribute object created by the user of the API shouldn't be
immutable. As user of the API I want to create an Entry object and add
attribute and values to it. So the API must provide setters.

So I think if Entry and Attribute are interfaces we just define the
getter methods.

The default implementations of those classes (e.g. ClientEntry and
ClientAttribute) additional have setters the user can use when
constructing the objects.

The Entry objects returned from the API (e.g. from a search) should be
immutable to protect them from being casted by the user, e.g. by
wrapping a created ClientEntry into an ImmutableEntry implementation.

Kind Regards,
Stefan