will factory pattern work here?

M

Mark F

I have a problem where I need one of several types returned depending on
a user selection. I was planning on using a factory pattern as these
types can all be related by a base class. The only problem is my
concrete classes may not have all the same properties. Can I still use
a factory pattern or should I use something else?

Example:

Abstract Class Document:
name
title
subject

Concrete Class Report extends Document:
reportno
keywords

Concrete class Drawing extends Document:
drawingno



Thanks,
-Mark
 
O

Oscar kind

Mark F said:
I have a problem where I need one of several types returned depending on
a user selection. I was planning on using a factory pattern as these
types can all be related by a base class. The only problem is my
concrete classes may not have all the same properties. Can I still use
a factory pattern or should I use something else?

You can still use a factory, expecially if your classes have a common
interface/superclass.

If this is not the case, the users of your factory must do a manual cast.
IMHO, this is only feasible if you can specify the returning class in a
parameter.
 
X

xarax

Mark F said:
I have a problem where I need one of several types returned depending on
a user selection. I was planning on using a factory pattern as these
types can all be related by a base class. The only problem is my
concrete classes may not have all the same properties. Can I still use
a factory pattern or should I use something else?

Example:

Abstract Class Document:
name
title
subject

Concrete Class Report extends Document:
reportno
keywords

Concrete class Drawing extends Document:
drawingno

That really depends on how the client application that
receives the newly created instance will use it. Seems
like you already think that polymorphic instances are
the way to go.

Well then, you'll likely want some interfaces like:
===============================================
public interface DocumentFactory
{
public abstract Document createDocument();

public abstract String getName();

public abstract String getTitle();

public abstract String getSubject();
}

public interface ReportFactory
extends DocumentFactory
{
public abstract Report createReport();

public abstract int getReportNumber();

public abstract String[] getKeywords();
}


public interface DrawingFactory
extends DocumentFactory
{
public abstract Drawing createDrawing();

public abstract int getDrawingNumber();
}
===============================================


The implementations look something like this:
===============================================
public abstract class DocumentFactoryAbstract
implements DocumentFactory
{
protected String name = "";
protected String title = "";
protected String subject = "";

public String getName()
{
return name;
}

public String getTitle()
{
return title;
}

public String getSubject()
{
return subject;
}
}

public abstract class ReportFactoryAbstract
extends DocumentFactoryAbstract
implements ReportFactory
{
protected int reportNumber;
protected String[] keywords = new String[] {};

public Document createDocument()
{
return createReport();
}

public int getReportNumber()
{
return reportNumber;
}

public String[] getKeywords()
{
return keywords;
}
}

public class ReportFactoryDefault
extends ReportFactoryAbstract
{
public Report createReport()
{
return /* whatever to create a Report */;
}
}

public abstract class DrawingFactoryAbstract
extends DocumentFactoryAbstract
implements DrawingFactory
{
protected int drawingNumber;

public Document createDocument()
{
return createDrawing();
}

public int getDrawingNumber()
{
return drawingNumber;
}
}

public class DrawingFactoryDefault
extends DrawingFactoryAbstract
{
public Drawing createDrawing()
{
return /* whatever to create a Drawing */;
}
}
===============================================
btw: I am too lazy to write the setter methods,
so I only included the getter methods.

Create your concrete factory classes that extend
either ReportFactoryAbstract or DrawingFactoryAbstract,
as appropriate. Instantiate the factories once and stuff
them into an array of type DocumentFactory[].

When the user selects an action to create something,
use the index of the selected action to select an object
from the DocumentFactory[]. Then call createDocument() on
that object to get an instance that is appropriate for the
selected action.

If you want to deal directly with the sub-type by using
downcasting, you can avoid using instanceof by using my
"Inheritance Descending" design pattern. If you don't
know that pattern, I can post an example later. It gives
the equivalent of an instanceof and downcast without
explicitly coding the instanceof or the downcast, so you
can work the actual sub-type.


--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 

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

No members online now.

Forum statistics

Threads
474,266
Messages
2,571,087
Members
48,773
Latest member
Kaybee

Latest Threads

Top