What I do in Scala:

case class Person(val firstName : String, val lastName : String)

then I get correct equals, hashCode, a toString and pattern-matching and a
concise creation syntax:

val person = Person("Keith","Haber")

So instead of 30+ lines of Java, I get 1 line of Scala, with more
functionality ;)

</endShamelessPlug>

:)

On Thu, Dec 4, 2008 at 5:45 PM, Keith Haber <[EMAIL PROTECTED]> wrote:

>
> When I want to make an immutable type with a lot of attributes.  I
> generally like to use a static inner class as a builder object.
> Here's an example with just two attributes.
>
>
> public final class Person{
>
>   private final String firstName;
>   private final String lastName;
>
>   public Person(String firstName, String lastName){
>      super();
>      this.firstName = firstName;
>      this.lastName = lastName;
>   }
>
>   public String getFirstName(){return firstName;}
>   public String getLastName(){return lastName;}
>
>
>   public static class Builder {
>      private String firstName;
>      private String lastName;
>
>      public Builder setFirstName(String firstName){
>          this.firstName = firstName;
>          return this;
>      }
>
>      public Builder setLastName(String lastName){
>          this.lastName = lastName;
>          return this;
>      }
>
>      public Person newPerson(){
>          return new Person(firstName, lastName);
>      }
>  }
>
> }
>
>
> Then in my client code, I would do:
>
>    Person keith = new Person.Builder().setFirstName
> ("Keith").setLastName("Haber").newPerson();
>
> Or if I need to instantiate a lot of similar objects, I can hang on to
> my Builder object.  (Could be handy for constructing relatives, I
> suppose.)
>
> A nice thing about this approach is that I get the benefit of readable
> setters instead of working with long lists of meticulously ordered
> constructor arguments (not so big a deal with two attributes, but very
> helpful when working with six or more attributes), but my immutable
> objects don't have setters at all.
>
> And by making the builder class a static inner class, it's obvious
> which builder classes go with which immutable types -- it's always
> named <immutable type name>.Builder.
>
> In episode 219 they talked about objects having a "construct phase"
> with setters and a "use phase" when the object construction is
> "finished."  To my mind this approach is reasonably close to that
> idea.
>
> Keith
>
>
> On Dec 3, 10:58 pm, hlovatt <[EMAIL PROTECTED]> wrote:
> > In 219 there was a long discussion about setting up an object and then
> > making it immutable. There are a couple of ways of doing this in Java
> > already:
> >
> > public class FooArgs {
> >   public int x = 1; // 1 is default
> >   public int y = 2;
> >   public int z = 3;
> >   ...
> >
> > }
> >
> > public class Foo {
> >   public Foo( FooArgs args ) { ... }
> >   ...
> >
> > }
> >
> >   Foo foo = new Foo( new FooArgs() {{ x = 2 }} );
> >
> > Another option is an immutable and mutable versions that inherit from
> > a common base and implement a standard conversion interface. First the
> > standard interface:
> >
> > public interface ImmutableValueConversions {
> >   Immutable toImmutable() throws IllegalStateException;
> >   Value toValue();
> >
> > }
> >
> > Below is an integer example that uses an abstract class as the base of
> > the hierarchy. You can also use interfaces. The abstract class is:
> >
> >     8:public abstract class AbstractInteger extends AbstractValue
> >     9:    implements ImmutableValueConversions, InstanceFactory {
> >    10:    public abstract int getValue();
> >    11:
> >    12:    public abstract AbstractInteger instanceOfSelf( int value );
> >    13:
> >    14:    public AbstractInteger add( final int rhs ) {
> >    15:        return instanceOfSelf( getValue() + rhs );
> >    16:    }
> >    17:}
> >
> > Then the immutable version:
> >
> >     9:public final class ImmutableInteger2 extends AbstractInteger
> >    10:    implements Immutable {
> >    11:    private final int value;
> >    12:
> >    13:    public ImmutableInteger2( final int value ) {
> >    14:        this.value = value;
> >    15:    }
> >    16:
> >    17:    public int getValue() {
> >    18:        return value;
> >    19:    }
> >    20:
> >    21:    public Immutable toImmutable() {
> >    22:        return this;
> >    23:    }
> >    24:
> >    25:    public Value toValue() {
> >    26:        return new ValueInteger( value );
> >    27:    }
> >    28:
> >    29:    public AbstractInteger instanceOfSelf( final int value ) {
> >    30:        return new ImmutableInteger2( value );
> >    31:    }
> >    38:}
> >
> > And the value version:
> >
> >     9:public final class ValueInteger extends AbstractInteger {
> >    10:    // Not final, this is the value version
> >    11:    private int value;
> >    12:
> >    13:    public ValueInteger( final int value ) {
> >    14:        this.value = value;
> >    15:    }
> >    16:
> >    17:    public int getValue() {
> >    18:        return value;
> >    19:    }
> >    20:
> >    21:    // Setter, this is the value version!
> >    22:    public void setValue( final int value ) {
> >    23:        this.value = value;
> >    24:    }
> >    25:
> >    26:    public Immutable toImmutable() {
> >    27:        return new ImmutableInteger2( value );
> >    28:    }
> >    29:
> >    30:    public Value toValue() {
> >    31:        return new ValueInteger( value );
> >    32:    }
> >    33:
> >    34:    public AbstractInteger instanceOfSelf( final int value ) {
> >    35:        return new ValueInteger( value );
> >    36:    }
> >    37:
> >    38:    // Set and add combined (+=), this is the value version!
> >    39:    public ValueInteger setAdd( final int rhs ) {
> >    40:        value += rhs;
> >    41:        return this;
> >    42:    }
> >    49:}
> >
> > Then you can use these classes like this:
> >
> >   ImmutableInteger i = (ImmutableInteger)( new ValueInteger().setValue
> > ( 2 ).toValue() );
> >
> > My own pet project, PEC, is an extensible compiler that can enforce
> > patterns, the above immutable pattern can be enforced. More details
> > from:
> >
> >  http://pec.dev.java.net/nonav/frontpage.html
> >
> > What do others do?
> >
>


-- 
Viktor Klang
Senior Systems Analyst

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to