I have a class called Machine
. It contains a list of parts and a list of actions. The list of parts will contain instances of the Part
class subclasses and the list of actions will contain instances of my Action
class subclasses. Each Part
subclass will have its corresponding Action
subclass. None of the subclasses are available at compile time. When a Machine
instance starts all its parts should perform their action.
An action will perform the same manipulation for each Part
subclass so I am trying to create a factory class that will create a single instance for each Action
subclass. My first thought was to use an interface for Action
, but then I would have to create an Action
instance for each Part
instance I create, or make each class that implemented Action
responsible for making itself a singleton. I am not sure if a factory is the best solution and if I am implementing the pattern correctly.
Neither Action
nor Part
subclasses are available to me so I am using generics. I am new to Java so I am not sure if I am using them correctly - Eclipse gives me several Raw type warnings (I indicated where). Here is my code:
import java.util.ArrayList;
public class GenericsTest
{
public static void main(String[] args) throws InstantiationException,
IllegalAccessException
{
ArrayList<Part> parts = new ArrayList<Part>();
Rotate rotate = ActionFactory.getAction(Rotate.class);
Move move = ActionFactory.getAction(Move.class);
int i;
for (i = 0; i < 1000; i++)
{
Gear gear = new Gear();
gear.value1 = i;
gear.actions.add(rotate);
parts.add(gear);
Lever lever = new Lever();
lever.value2 = i + 2000;
lever.actions.add(move);
parts.add(lever);
}
Machine machine = new Machine();
machine.parts.addAll(parts);
machine.start();
}
}
class Machine
{
public void start()
{
for (Part part : parts)
{
// Raw type warning
for (Action action : part.actions)
{
// Raw type warning
action.execute(part);
}
}
}
public ArrayList<Part> parts = new ArrayList<Part>();
}
abstract class Part
{
// Raw type warning
public ArrayList<Action> actions = new ArrayList<Action>();
}
abstract class Action<T extends Part>
{
abstract public void execute(T part);
}
class ActionFactory<T extends Action>
{
public static <T> T getAction(Class<T> c) throws InstantiationException,
IllegalAccessException
{
T returnAction = null;
for (Action action : actions)
{
if (action.getClass() == c)
{
// Unchecked cast warning
returnAction = (T) action;
}
}
if (returnAction == null)
{
returnAction = c.newInstance();
actions.add((Action) returnAction);
}
return returnAction;
}
private static ArrayList<Action> actions = new ArrayList<Action>();
}
/*
* Subject1, Subject2, Action1 and Action2, somewhere else:
*/
class Gear extends Part
{
public int value1;
}
class Lever extends Part
{
public int value2;
}
class Rotate extends Action<Gear>
{
@Override
public void execute(Gear part)
{
System.out.println("rotate action executed, value 1: " + part.value1);
}
}
class Move extends Action<Lever>
{
@Override
public void execute(Lever part)
{
System.out.println("move action executed, value 2: " + part.value2);
}
}