Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #30579 > unrolled thread

a question about factory method

Started byJohn <xsli2@yahoo.com>
First post2014-12-18 05:57 -0800
Last post2014-12-18 13:43 -0800
Articles 10 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  a question about factory method John <xsli2@yahoo.com> - 2014-12-18 05:57 -0800
    Re: a question about factory method Robert Klemme <shortcutter@googlemail.com> - 2014-12-18 15:28 +0100
    Re: a question about factory method Silvio <silvio@internet.com> - 2014-12-18 15:43 +0100
    Re: a question about factory method Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-18 10:37 -0500
      Re: a question about factory method John <xsli2@yahoo.com> - 2014-12-18 08:04 -0800
        Re: a question about factory method Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-18 12:04 -0500
          Re: a question about factory method John <xsli2@yahoo.com> - 2014-12-18 10:43 -0800
            Re: a question about factory method Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-18 14:24 -0500
              Re: a question about factory method Robert Klemme <shortcutter@googlemail.com> - 2014-12-19 01:39 +0100
    Re: a question about factory method Roedy Green <see_website@mindprod.com.invalid> - 2014-12-18 13:43 -0800

#30579 — a question about factory method

FromJohn <xsli2@yahoo.com>
Date2014-12-18 05:57 -0800
Subjecta question about factory method
Message-ID<ff7f0941-582f-4a6f-83fd-2fa71434ff46@googlegroups.com>
Hi:

I am reading a very good web site
http://www.javapractices.com/topic/TopicAction.do?Id=21

I have a question about the following code:

public final class ComplexNumber {

  /**
  * Static factory method returns an object of this class.
  */
  public static ComplexNumber valueOf(float aReal, float aImaginary) {
    return new ComplexNumber(aReal, aImaginary);
  }

  /**
  * Caller cannot see this private constructor.
  *
  * The only way to build a ComplexNumber is by calling the static 
  * factory method.
  */
  private ComplexNumber(float aReal, float aImaginary) {
    fReal = aReal;
    fImaginary = aImaginary;
  }

  private float fReal;
  private float fImaginary;

  //..elided
} 

The code uses a private constructor and the factory method. I also notice this class is an immutable class. If I write this class, I would simply have a public constructor, like:

public final class ComplexNumber {

  public ComplexNumber(float aReal, float aImaginary) {
    fReal = aReal;
    fImaginary = aImaginary;
  }

  private float fReal;
  private float fImaginary;

  //..elided
} 

Could you explain to me why their code is better than mine? If theirs is singleton, I would agree. But in this case, it does not make sense for using singleton. The only thing I can think of is using their code is more like following a trend, e.g. String.valueOf(xxx).

I guess most people will do what I do here.

[toc] | [next] | [standalone]


#30581

FromRobert Klemme <shortcutter@googlemail.com>
Date2014-12-18 15:28 +0100
Message-ID<cfg6l5Fpp47U1@mid.individual.net>
In reply to#30579
On 18.12.2014 14:57, John wrote:

 > I am reading a very good web site
 > http://www.javapractices.com/topic/TopicAction.do?Id=21

> The code uses a private constructor and the factory method. I also
> notice this class is an immutable class. If I write this class, I
> would simply have a public constructor, like:
> Could you explain to me why their code is better than mine? If
> theirs  is singleton, I would agree. But in this case, it does not make sense
> for using singleton. The only thing I can think of is using their code
> is more like following a trend, e.g. String.valueOf(xxx).

By using this method authors of that class gain a lot of freedom, notably

  - regarding the type of return value
  - regarding the point in time when an instance will be created

For example: it may make sense to have different classes for the cases 
that imaginary part is 0 and is not 0.

Then, it may be later decided to optimize allocation of Complex 
instances and use something like an internal pool (e.g. similar for 
small Integer values).  If you use a constructor there will be a new 
instance _every time_.

By providing the factory method the API for obtaining Complex instances 
can stay the same while internally more changes can be done.

Btw. these properties are mentioned at the top of the page that you linked.

> I guess most people will do what I do here.

Probably.  But that does not mean that this solution is better.

Btw. I wonder why they did not make member fields final.  Also it seems, 
Complex could be Serializable.

Kind regards

	robert



-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#30582

FromSilvio <silvio@internet.com>
Date2014-12-18 15:43 +0100
Message-ID<5492e7f9$0$2838$e4fe514c@news.xs4all.nl>
In reply to#30579
The factory can do several thing for you.

One important thing is hiding what the actual class is of the objects it 
creates. As soon as user programs start using "new ComplexNumber" all 
over the place this will be set in stone forever.
Let's say your application uses a significant amount of complex values 
from the real plane only (having an imaginary value of 0). You could 
create a subclass RealComplex that only holds a single float member and 
that always returns 0 for the imaginary part.

Depending on the type of objects the factory creates and their 
immutability it could also be a good idea to reuse/singleton common 
values or use some LRU cache to achieve a certain level of reuse.

And you could do all this as an afterthought without changing any user 
code. It would just require a minor change to your factory method.

Most people might start out doing it the way you intended to and then 
later on suffer the consequences. More experienced people will probably 
prefer the factory method route.

Silvio



On 12/18/2014 02:57 PM, John wrote:
> Hi:
>
> I am reading a very good web site
> http://www.javapractices.com/topic/TopicAction.do?Id=21
>
> I have a question about the following code:
>
> public final class ComplexNumber {
>
>    /**
>    * Static factory method returns an object of this class.
>    */
>    public static ComplexNumber valueOf(float aReal, float aImaginary) {
>      return new ComplexNumber(aReal, aImaginary);
>    }
>
>    /**
>    * Caller cannot see this private constructor.
>    *
>    * The only way to build a ComplexNumber is by calling the static
>    * factory method.
>    */
>    private ComplexNumber(float aReal, float aImaginary) {
>      fReal = aReal;
>      fImaginary = aImaginary;
>    }
>
>    private float fReal;
>    private float fImaginary;
>
>    //..elided
> }
>
> The code uses a private constructor and the factory method. I also notice this class is an immutable class. If I write this class, I would simply have a public constructor, like:
>
> public final class ComplexNumber {
>
>    public ComplexNumber(float aReal, float aImaginary) {
>      fReal = aReal;
>      fImaginary = aImaginary;
>    }
>
>    private float fReal;
>    private float fImaginary;
>
>    //..elided
> }
>
> Could you explain to me why their code is better than mine? If theirs is singleton, I would agree. But in this case, it does not make sense for using singleton. The only thing I can think of is using their code is more like following a trend, e.g. String.valueOf(xxx).
>
> I guess most people will do what I do here.
>

[toc] | [prev] | [next] | [standalone]


#30583

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-12-18 10:37 -0500
Message-ID<m6usaq$6bg$1@dont-email.me>
In reply to#30579
On 12/18/2014 8:57 AM, John wrote:
> Hi:
>
> I am reading a very good web site
> http://www.javapractices.com/topic/TopicAction.do?Id=21
>
> I have a question about the following code:
>
> public final class ComplexNumber {
>
>    /**
>    * Static factory method returns an object of this class.
>    */
>    public static ComplexNumber valueOf(float aReal, float aImaginary) {
>      return new ComplexNumber(aReal, aImaginary);
>    }
>
>    /**
>    * Caller cannot see this private constructor.
>    *
>    * The only way to build a ComplexNumber is by calling the static
>    * factory method.
>    */
>    private ComplexNumber(float aReal, float aImaginary) {
>      fReal = aReal;
>      fImaginary = aImaginary;
>    }
>
>    private float fReal;
>    private float fImaginary;
>
>    //..elided
> }
>
> The code uses a private constructor and the factory method. I also notice this class is an immutable class. If I write this class, I would simply have a public constructor, like:
>
> public final class ComplexNumber {
>
>    public ComplexNumber(float aReal, float aImaginary) {
>      fReal = aReal;
>      fImaginary = aImaginary;
>    }
>
>    private float fReal;
>    private float fImaginary;
>
>    //..elided
> }
>
> Could you explain to me why their code is better than mine? If theirs is singleton, I would agree. But in this case, it does not make sense for using singleton. The only thing I can think of is using their code is more like following a trend, e.g. String.valueOf(xxx).
>
> I guess most people will do what I do here.

     The page mentions some of the things factory methods can do that
constructors cannot, then gives an example that doesn't show off any
of the differences ...  Is that why you call the page "very good?"  :)

     A factory method can have a name, but a constructor cannot.  That
means a class can have only one constructor with a particular argument
"signature," because if it had two constructors with identical calls
there'd be no way to tell which one each `new' wanted to invoke.  If
you wanted to construct ComplexNumbers from either a pair of Cartesian
coordinates ("real and imaginary") *or* from a pair of polar coordinats
("magnitude and phase"), you couldn't do it with two constructors each
taking two `float' arguments.  You could, however, add a factory
method like

	public static ComplexNumber polarValue(float r, float t) {
	    return new ComplexNumber((float) (r * Math.cos(t)),
	                             (float) (r * Math.sin(t)));
	}

     A factory method can recycle existing objects, but a constructor
must always initialize a brand-new object distinct from everything else
that already exists.  This can save memory (and perhaps initialization
time) for immutable "value" objects: How many identical copies of
Boolean.FALSE do you need, anyhow?  Since the internals of ComplexNumber
are a pair of floating-point values there might not be much benefit to
caching a whole lot of them, but perhaps it might be worth while to
use and re-use and re-re-use a few common values:

	public final class ComplexNumber {
	    public static final ZERO = new ComplexNumber(0, 0);
	    public static final ONE = new ComplexNumber(1, 0);
	    public static final I = new ComplexNumber(0, 1);

	    public static ComplexNumber valueOf(float r, float i) {
	        if (r == 0 && i == 0) {
	            return ZERO;
	        else if (r == 1 && i == 0) {
	            return ONE;
	        } else if (r == 0 && i == 1) {
	            return I;
	        } else {
	            return new ComplexNumber(r, i);
	        }
	    }

	    ... constructor and elisions as before ...
	}

     Finally, a factory method can return an instance of any class
that's assignable to its return type, not just an instance of its
very own class.  I can't think of a ComplexNumber variant that would
be a plausible example, but consider something like Calendar.  Its
getInstance() methods usually return a GregorianCalendar instance,
but could (if Locales and so on were set up) return an instance of
MayanCalendar or JulianCalendar or BabylonianCalendar or whatever:
Classes whose names, whose very existence, might not have been known
when the calling code was written.  All the caller cares about is
that the returned object is a Calendar subclass, *any* Calendar
subclass.  True, the caller could use a `switch' or something to
choose which of many class-specific `new' operations to execute,
but then the caller would have to enumerate all the possibilities
in advance -- and would have to issue a code update when NASA sends
colonists to Mars and they invent a MartianCalendar.

     Summary: Constructors are often appropriate, but there are things
factory methods can do that constructors cannot.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#30584

FromJohn <xsli2@yahoo.com>
Date2014-12-18 08:04 -0800
Message-ID<ae5dcc85-b23a-4ee3-94b3-350e585f502d@googlegroups.com>
In reply to#30583
Thank you all for replies.

Can you elaborate a little more about
 Its getInstance() methods usually return a GregorianCalendar instance,
but could (if Locales and so on were set up) return an instance of
MayanCalendar or JulianCalendar or BabylonianCalendar or whatever:
Classes whose names, whose very existence, might not have been known
when the calling code was written.

My guess is something like below. Is that correct? Thank you very much.

public class Calendar {

  /**
  * Static factory method returns an object of this class or subclass. for choice: 1 for GregorianCalendar, 2 for MayanCalendar , 3 for JulianCalendar
  */
  public static Calendar getInstance(Date aDate, int choice) {
    if(choice==1){
      ... //return a GregorianCalendar object
    }
    else if(choice==2) {
      ... //return a MayanCalendar object
    }
    else if(choice==3) {
      ... //return a JulianCalendar object
    }
    else {
      return null;
    }
   
  }

...
}

How can I make it return MayanCalendar or JulianCalendar?

[toc] | [prev] | [next] | [standalone]


#30586

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-12-18 12:04 -0500
Message-ID<m6v1e2$u2d$1@dont-email.me>
In reply to#30584
On 12/18/2014 11:04 AM, John wrote:
> Thank you all for replies.
>
> Can you elaborate a little more about
>   Its getInstance() methods usually return a GregorianCalendar instance,
> but could (if Locales and so on were set up) return an instance of
> MayanCalendar or JulianCalendar or BabylonianCalendar or whatever:
> Classes whose names, whose very existence, might not have been known
> when the calling code was written.
>
> My guess is something like below. Is that correct? Thank you very much.
>
> public class Calendar {
>
>    /**
>    * Static factory method returns an object of this class or subclass. for choice: 1 for GregorianCalendar, 2 for MayanCalendar , 3 for JulianCalendar
>    */
>    public static Calendar getInstance(Date aDate, int choice) {
>      if(choice==1){
>        ... //return a GregorianCalendar object
>      }
>      else if(choice==2) {
>        ... //return a MayanCalendar object
>      }
>      else if(choice==3) {
>        ... //return a JulianCalendar object
>      }
>      else {
>        return null;
>      }
>
>    }
>
> ...
> }
>
> How can I make it return MayanCalendar or JulianCalendar?

     First, you'd need to write MayanCalendar and JulianCalendar
classes (they're not part of Java SE; I just made them up as
examples that someone might add someday).  These new classes would
be subclasses of Calendar:

	public class MayanCalendar extends Calendar { ... }
	public class JulianCalendar extends Calendar { ... }

... so that Calendar.getInstance() -- which must return a Calendar --
could legitimately return them.

     Next, you'd have to make the new classes known to Java.  I haven't
actually tried to do this, but it can (probably) be done somehow:  All
the variants of Calendar.getInstance() eventually wind up with a
TimeZone and a Locale, and from these they're supposed to produce a
suitable Calendar.  Java doesn't specify exactly how suitable Calendars
are found, but if you look at the source code for Calendar.java you'll
find that (in Sun/Oracle's implementation) the heavy lifting happens in
CalendarProvider and LocaleProviderAdapter classes.  (These are not part
of Java SE, but part of Sun/Oracle's implementation of Java SE.)

     I can't explore much further, because the JDK doesn't provide source
for those internal classes; all I can see is the compiled bytecode.  But
I imagine there's a configuration file somewhere that describes the
available Locales and things, and (presumably) there's a way to say
"For the following Locale, use *this* Calendar subclass."  Whether this
actually happens exactly this way with Calendar isn't crucial to the
issue of using a factory method; the point is that a factory method
*could* do something like this, and make a run-time choice of which
precise class it returns.  A constructor couldn't.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#30587

FromJohn <xsli2@yahoo.com>
Date2014-12-18 10:43 -0800
Message-ID<74e17e36-3ccb-45c4-b50a-439d2799e3c7@googlegroups.com>
In reply to#30586
Eric,

Your reply goes off the topic. I didn't mean digging deep into Calendar thing. Since you mentioned it, I use it as an example to ask.

I meant to ask How to use factory method to return different objects(which belong to the same parent class). A couple of repliers, including you, mentioned that as one of several advantages of using factory versus using a public constructor.

Thank you.

[toc] | [prev] | [next] | [standalone]


#30588

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-12-18 14:24 -0500
Message-ID<m6v9k5$5fb$1@dont-email.me>
In reply to#30587
On 12/18/2014 1:43 PM, John wrote:
> Eric,
>
> Your reply goes off the topic. I didn't mean digging deep into Calendar thing. Since you mentioned it, I use it as an example to ask.
>
> I meant to ask How to use factory method to return different objects(which belong to the same parent class). A couple of repliers, including you, mentioned that as one of several advantages of using factory versus using a public constructor.

     Sorry for misunderstanding the thrust of your question.

     As to *how* a factory method might choose which of several classes
to return, you already illustrated one way (paraphrased):

	public static Calendar getInstance(Date aDate, int choice) {
	    if (choice == 1) {
	        ... //return a GregorianCalendar object
	    } else if (choice == 2) {
	        ... //return a MayanCalendar object
	    } else if (choice == 3) {
	        ... //return a JulianCalendar object
	    } else {
	        return null;
	    }
	}

To me, this doesn't seem a huge advantage: The caller who writes
`getInstance(date, 2)' could just as easily write `new MayanCalendar()'
with about the same effect.  So let's think of another possibility
(again, this is largely made-up): The switch from the Julian to the
Gregorian calendar happened at different times in different parts of
the world, so the particular kind of Calendar to use is a function
of both the Date and the Locale.  We might write something like:

	public static Calendar getInstance(Date date, Locale locale) {
	    Date cutover = ...; // locale's Gregorian adoption date
	    if (date.compareTo(cutover) < 0) {
	        return new JulianCalendar(date);
	    } else {
	        return new GregorianCalendar(date);
	    }
	}

The caller needn't worry about determining `cutover' (it's probably not
a one-liner!), he just gets the "right kind" of Calendar for the Date
in question at the specified Locale.

     Approaches like this, though, require the factory method to have an
enumeration of all the possibilities, built right into the Java source.
Another possibility is often used in "provider" or "plugin" styles: The
factory method consults an environment variable or a configuration file
or a database or some such, and gets the name of a suitable class -- as
a String.  Then it can use Class.forName() to load the named class, and
can create an instance by invoking the class' constructor reflectively.
This style requires more effort to set up, but is much more flexible: To
introduce a new class you needn't change a single line of the factory
method or its caller; you write your new class, put it in a .jar (most
likely), and change the environment variable or config file.  This is
(more or less) how Swing loads pluggable look-and-feel implementations,
and similar approaches are used for things like externally-supplied
cryptographic suites.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#30591

FromRobert Klemme <shortcutter@googlemail.com>
Date2014-12-19 01:39 +0100
Message-ID<cfhaduF4j02U1@mid.individual.net>
In reply to#30588
On 18.12.2014 20:24, Eric Sosman wrote:

>      As to *how* a factory method might choose which of several classes
> to return, you already illustrated one way (paraphrased):
>
>      public static Calendar getInstance(Date aDate, int choice) {
>          if (choice == 1) {
>              ... //return a GregorianCalendar object
>          } else if (choice == 2) {
>              ... //return a MayanCalendar object
>          } else if (choice == 3) {
>              ... //return a JulianCalendar object
>          } else {
>              return null;
>          }
>      }
>
> To me, this doesn't seem a huge advantage: The caller who writes
> `getInstance(date, 2)' could just as easily write `new MayanCalendar()'
> with about the same effect.

The crucial point is that the caller does not need to know the criteria 
when to create what type.  That _is_ a huge advantage.

Cheers

	robert


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#30589

FromRoedy Green <see_website@mindprod.com.invalid>
Date2014-12-18 13:43 -0800
Message-ID<7fi69ah7v8pgb7h80d99osufk9k3m1sgce@4ax.com>
In reply to#30579
On Thu, 18 Dec 2014 05:57:30 -0800 (PST), John <xsli2@yahoo.com>
wrote, quoted or indirectly quoted someone who said :

>Could you explain to me why their code is better than mine?

You normally would not bother with a static factory. You use a factory
when you want do create different kinds of object based on the
parameters, or when you think you might in future.  You could convert
to a more complex algorithm without modifying the calls to the
constructor.


Your static constructor for example might look for some magic pairs of
real/imag and return constants instead of creating a new object
-- 
Roedy Green Canadian Mind Products http://mindprod.com
Software is a gas; it expands to fill its container.
~ Nathan Myhrvold (born: 1959-08-03 age: 55) Nathan’s First Law

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web