Static factory method doesn't work -- non-static does!

M

Matthias Kaeppler

Howdy,

I have a strange problem:

I want to implement a factory class, which has a static creation method
taking an enum type which defines what type will be created.
The problem is, as soon as I /do/ make this method static, the program
behaves very strange, in that calls on the returned object are never
executed.

Here's some code for illustration:

class Factory {

enum Type {
TYPE_1,
TYPE_2
}

public static Product createProduct( Type t ) {
switch( t ) {
case( TYPE_1 ) return new Type1Product();
case( TYPE_2 ) return new Type2Product();
}
}
}

Type1Product and Type2Product extend Product.
Now I somewhere pass the reference to the newly created object to some
other object's ctor:

Foo obj = new Foo( Factory.createProduct( Factory.Type.TYPE_1 ) );

Inside obj, all calls on the object returned by the factory method fail,
in that they are never executed!
However, if I make the factory method non-static, and instantiate the
whole Factory class first, then everything works just fine!

I can't even remotely imagine what is causing this, can you?
Any help greatly appreciated.

Cheers,
Matthias
 
M

Matthias Kaeppler

Matthias said:
public static Product createProduct( Type t ) {
switch( t ) {
case( TYPE_1 ) return new Type1Product();
case( TYPE_2 ) return new Type2Product();
}
}
}

Erm, please ignore the bad syntax in the switch statement... :D
Of course I have it right here.
 
V

Vincent Vollers

Well, I dont know what you are doing exactly... but I wrote a small test
program, and it works perfectly:

the following code produces, as expected:

getNum in ProductTypeOne
1
getNum in ProductTypeTwo
2

===========================
abstract class Product {
protected int num;

abstract public int getNum();
}

class ProductTypeOne extends Product {
public ProductTypeOne() {
num = 1;
}

public int getNum() {
// TODO Auto-generated method stub
System.out.println("getNum in ProductTypeOne");
return num;
}
}

class ProductTypeTwo extends Product {
public ProductTypeTwo() {
num = 2;
}

public int getNum() {
// TODO Auto-generated method stub
System.out.println("getNum in ProductTypeTwo");
return num;
}
}

class TestContainer {
private Product product;

public TestContainer(Product p) {
this.product = p;
System.out.println(p.getNum());
}
}

class TestFactory {
enum Type {
TEST1,
TEST2
}

public static Product generateProduct(Type t) {
switch(t) {
case(TEST1): return new ProductTypeOne();
case(TEST2):
default: return new ProductTypeTwo();
}
}
}

public class TestProgram {

public TestProgram() {
new TestContainer(TestFactory.generateProduct(TestFactory.Type.TEST1));
new TestContainer(TestFactory.generateProduct(TestFactory.Type.TEST2));
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestProgram();
}

}
===========================
 
R

Ross Bamford

Howdy,

I have a strange problem:

I want to implement a factory class, which has a static creation method
taking an enum type which defines what type will be created.
The problem is, as soon as I /do/ make this method static, the program
behaves very strange, in that calls on the returned object are never
executed.

Sorry, your problem /is/ strange - works here as expected. However,
while playing around with it I came up with this, which I've not seen
anywhere before but has probably already been done...? It might help, or
it might not...

Imagine an Enum type:


// -----
enum AbstractClassType {
FIRST_CLASS (FirstClass.class),
SECOND_CLASS (SecondClass.class);
// ... etc

Class<? extends AbstractClass> classType;
ClassType(Class<? extends AbstractClass> theClass) {
classType = theClass;
}
public AbstractClass instantiate() throws InvocationTargetException {
try {
return classType.newInstance();
} catch (Exception e) {
throw(new InvocationTargetException(e));
}
}
}
// -----


And then imagine a base-class / factory:


// -----
abstract class AbstractClass {
public static AbstractClass getInstance(ClassType classType)
throws InvocationTargetException
{
return classType.instantiate();
}

public abstract Object someMethod(); // ... etc.
}
// -----


Cut out the middleman, so to speak. Of course you use it simply:

AbstractClass mine =
AbstractClass.getInstance(AbstractClassType.FIRST_CLASS);

or whatever.

?
 
J

John C. Bollinger

Matthias said:
I want to implement a factory class, which has a static creation method
taking an enum type which defines what type will be created.
The problem is, as soon as I /do/ make this method static, the program
behaves very strange, in that calls on the returned object are never
executed.

How about you post an example of what you're trying to do that _doesn't_
work. We can point out errors that you may be making in that case, but
when we only have an example of some similar thing that does work, we
can only speculate about what mistake you may have made in converting it.
 
A

Andrew Thompson

Andrew Thompson coughed up:

Andrew, you should put a counter on that page.

I have considered using counters at one time or another, but resisted
(thus far) for two reasons.
1) They are inherently inaccurate (with caching + 100 other factors)
2) They are considered (in web design circles) to mark a page as made
by an 'enthusiastic amateur'.
..I'd like to see how many times it's been visited.

OK.. Just checked the PhySci.org server stats for April 2005.

In the list of 'Top 30 of 1059 Total URLs' recorded as visited,
the SSCCE document comes in at 27th with 867 hits.

Thoughts, ..comments?
 
R

Ross Bamford

OK.. Just checked the PhySci.org server stats for April 2005.

In the list of 'Top 30 of 1059 Total URLs' recorded as visited,
the SSCCE document comes in at 27th with 867 hits.

Thoughts, ..comments?

If it's not the posters reading it, then who is?

"I have this problem in some code that kind of goes...
IF this THEN do this ..."
 
A

Andrew Thompson

On Tue, 2005-05-24 at 00:12 +0000, Andrew Thompson wrote:
(T.G.M.) ....
If it's not the posters reading it, then who is?

Aaahh! The first signs of why you should treat such numbers
with extreme caution. What does 'reading' mean? It is certainly
a subset of 'hits'..

The figure of 867 -hits- includes every time the page was called from
the server, including the times ..
- I myself checked the exact wording (of some part of it) prior to
posting the link in reponse to a question.
- The client was a search engine spider.
- Visitors clicked the link and then thought, 'No - this isn't what I
was after!' and left the page.
- Visitors read part of the page but got bored, called away, had
power failure..
- Visitors that read the entire page but failed to understand it, or
it's deeper message.

So, in the end, these numbers amount to
"lies, damned lies, ..and statistics!" ;-)
 
T

Thomas G. Marshall

Andrew Thompson coughed up:
Aaahh! The first signs of why you should treat such numbers
with extreme caution. What does 'reading' mean? It is certainly
a subset of 'hits'..

Not necesarily. You can have more readings than hits if someone leaves the
page up on a monitor and walks away screaming "you gotta read this penthouse
forum story!"
 
A

Andrew Thompson

On Tue, 24 May 2005 02:55:21 GMT, Thomas G. Marshall wrote:

(A.T.)
Not necesarily. You can have more readings than hits if someone leaves the
page up on a monitor and walks away screaming "you gotta read this penthouse
forum story!"

LOL - sure! But I do not think that happens regularly with the
SSCCE page, it does not generate -that- level of enthusiasm.

And I just couldn't resist this..

"Of course, I only read Penthouse for the articles - I browse
the site with 'images off'.."
 
M

Matthias Kaeppler

John said:
How about you post an example of what you're trying to do that _doesn't_
work. We can point out errors that you may be making in that case, but
when we only have an example of some similar thing that does work, we
can only speculate about what mistake you may have made in converting it.

Well, apart from the naming, the real code is the same, with the factory
method being static.

class VisualizationFactory {

enum DiagramType {
LINE_DIAGRAM,
BAR_DIAGRAM,
COL_DIAGRAM
}

public static Diagram createDiagram( DiagramType type ) {
switch( type ) {
case LINE_DIAGRAM:
System.out.println( "Line Diagram requested" );
return new LineDiagram();
default: // the other classes don't yet exist
System.out.println( "unexpected" );
break;
}

return null;
}

}

public abstract class Diagram {

public abstract void paint( Graphics g );
public abstract void foo(); // for testing, it is never actually
called, though invoked!

}

import java.awt.*;

public class LineDiagram extends Diagram {

public void paint( Graphics g ) {
System.out.println( "painting line diagram" );
}

public void foo() {
System.out.println( "foo" );
}

}

public class MainWindow extends JFrame {

public static void main( String[] args ) {
// [...]
Diagram diagram =
VisualizationFactory.createDiagram(VisualizationFactory.DiagramType.LINE_DIAGRAM);

VisualizationFrame intFrame = new DiagramFrame("Viz", diagram );

}

}

The newly created diagram is passed to a DiagramFrame, which is a
JInternalFrame and supposed to draw diagrams.
Now inside this DiagramFrame's paint() method:

class DiagramFrame extends VisualizationFrame {

public DiagramFrame( String title, Diagram diagram ) {
super( title );
assert( diagram != null );
this.diagram = diagram;
}

public void paint( Graphics g ) {
super.paint( g );

//Graphics2D g2d = (Graphics2D) g;
//diagram.paint( g );
System.out.println( "frame paint" );
diagram.foo();
}

private Diagram diagram;

}

The program outputs "frame paint" on each window update, but the text I
am outputting in foo() is NEVER displayed. It is however displayed as
soon as I for example replace the call to the factory's creation method
with a normal "new LineDiagram()". Then everything works as expected.
It also works when I make the creation method non-static and then
instantiate the factory class first.

Odd, isn't it.
 
H

hiwa

A ratio at a beginners' forum:
When I refer twenty poeple to the SSCCE page, one among them post an SSCCE
compliant example code of good quality. Other nineteen keep eternal silence
thereafter.
 
C

Chris Uppal

Matthias said:
Well, apart from the naming, the real code is the same, with the factory
method being static.

class VisualizationFactory {
[...]
}

The program outputs "frame paint" on each window update, but the text I
am outputting in foo() is NEVER displayed.

Works fine for me (once I'd added a dummy VisualizationFrame class, the
necessary imports, and added a call to initFrame.show() in main() so that the
window was actually displayed and its paint() method called).

Output looks like:
Line Diagram requeste
frame paint
foo
frame paint
foo
frame paint
foo
frame paint
foo
...


-- chris
 
J

John McGrath

John C. Bollinger wrote:
public class MainWindow extends JFrame {

public static void main( String[] args ) {
// [...]
Diagram diagram =
VisualizationFactory.createDiagram(VisualizationFactory.DiagramType.LINE_
DIAGRAM);

VisualizationFrame intFrame = new DiagramFrame("Viz", diagram );
}
}
The program outputs "frame paint" on each window update

There are quite a few problems with this code:

1) It is missing imports, so it will not compile as is.
2) It contains references to a VisualizationFrame class that is not
included.
3) The only main() method just constructs a Diagram and a DiagramFrame.
It does not show the frame, so the program terminates when the main()
method returns.
4) The code consists of multiple source files,

The following article should help you to produce a more useful example:

http://www.physci.org/codes/sscce.jsp
 
R

Ross Bamford

Aaahh! The first signs of why you should treat such numbers
with extreme caution. What does 'reading' mean? It is certainly
a subset of 'hits'..

The figure of 867 -hits- includes every time the page was called from
the server, including the times ..
- I myself checked the exact wording (of some part of it) prior to
posting the link in reponse to a question.
- The client was a search engine spider.
- Visitors clicked the link and then thought, 'No - this isn't what I
was after!' and left the page.
- Visitors read part of the page but got bored, called away, had
power failure..
- Visitors that read the entire page but failed to understand it, or
it's deeper message.

So, in the end, these numbers amount to
"lies, damned lies, ..and statistics!" ;-)

:))
 
A

Andrew Thompson

A ratio at a beginners' forum:
When I refer twenty poeple to the SSCCE page, one among them post an SSCCE
compliant example code of good quality. Other nineteen keep eternal silence
thereafter.

So 95% gain a 'debugging tool' powerful enough to enable them
to solve their -own- code problems? Way cool!

[ ;-) ]
 
T

Thomas G. Marshall

Andrew Thompson coughed up:
A ratio at a beginners' forum:
When I refer twenty poeple to the SSCCE page, one among them post an
SSCCE compliant example code of good quality. Other nineteen keep
eternal silence thereafter.

So 95% gain a 'debugging tool' powerful enough to enable them
to solve their -own- code problems? Way cool!

[ ;-) ]


I've *often* wondered if there wasn't a way for a pluggin (or somesuch) to
take an example from a post and run it.

Now, it would be fraught with peril, but I also had this concept.

An application that takes a potentially large part of a post broken down
using some formalism or other:

----[gurgle.spit.Splat.java]----
(code here)
----[END: gurgle.spit.Splat.java]---

----[gurgle.hack.Lougy.java]---
(etc.)
----[END (etc)


So you do a potentially massive (but hopefully small) cut and paste into
this application's window, and it separates it into files and directories,
and runs the thing.

Presumably on the front end, the same application would allow you to specify
a package and compile + running options, and combine it all into a CnP-able
string of text to plop into your message.

Just for examples, etc.

Of course, you'd have to be careful some @#$%wad didn't put in something to
erase your HD...
 
T

Thomas G. Marshall

Thomas G. Marshall coughed up:
Andrew Thompson coughed up:
A ratio at a beginners' forum:
When I refer twenty poeple to the SSCCE page, one among them post an
SSCCE compliant example code of good quality. Other nineteen keep
eternal silence thereafter.

So 95% gain a 'debugging tool' powerful enough to enable them
to solve their -own- code problems? Way cool!

[ ;-) ]


I've *often* wondered if there wasn't a way for a pluggin (or
somesuch) to take an example from a post and run it.

Now, it would be fraught with peril, but I also had this concept.

An application that takes a potentially large part of a post broken
down using some formalism or other:

----[gurgle.spit.Splat.java]----
(code here)
----[END: gurgle.spit.Splat.java]---

----[gurgle.hack.Lougy.java]---
(etc.)
----[END (etc)


So you do a potentially massive (but hopefully small) cut and paste
into this application's window, and it separates it into files and
directories, and runs the thing.

Presumably on the front end, the same application would allow you to
specify a package and compile + running options, and combine it all
into a CnP-able string of text to plop into your message.

Just for examples, etc.

Of course, you'd have to be careful some @#$%wad didn't put in
something to erase your HD...


Note that what I certainly would *not* advocate is having all this hidden by
base64....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top