I think you are wanting the following design:
- An interface called
GenericParticle
. - Enums that give the most basic implementations.
- A factory/builder where you can make whatever you want.
You can achieve this with the following code:
enum Component {
ELECTRON, PROTON, NEUTRON;
}
interface GenericParticle {
List<String> getNames();
List<Component> getComponents();
}
enum BasicGenericParticle implements GenericParticle {
ELECTRON(
Arrays.asList("electron", "e"),
Arrays.asList(Component.ELECTRON)
),
HYDROGEN(
Arrays.asList("hydrogen", "h"),
Arrays.asList(Component.ELECTRON, Component.PROTON)
)
;
private final List<String> names;
private final List<Component> components;
private BasicGenericParticle(final List<String> names, final List<Component> components) {
this.names = names;
this.components = components;
}
@Override
public List<String> getNames() {
return new ArrayList<>(names);
}
@Override
public List<Component> getComponents() {
return new ArrayList<>(components);
}
}
class GenericParticleBuilder {
private List<String> names = new ArrayList<>();
private List<Component> components = new ArrayList<>();
public GenericParticleBuilder name(final String name) {
names.add(name);
return this;
}
public GenericParticleBuilder component(final Component component) {
components.add(component);
return this;
}
public GenericParticle build() {
return new GenericParticleImpl(names, components);
}
private static class GenericParticleImpl implements GenericParticle {
private List<String> names = new ArrayList<>();
private List<Component> components = new ArrayList<>();
public GenericParticleImpl(final List<String> names, final List<Component> components) {
this.names = names;
this.components = components;
}
@Override
public List<String> getNames() {
return new ArrayList<>(names);
}
@Override
public List<Component> getComponents() {
return new ArrayList<>(components);
}
}
}
Used as:
GenericParticle electron = BasicGenericParticle.ELECTRON;
GenericParticle hydrogen = BasicGenericParticle.HYDROGEN;
GenericParticle water = new GenericParticleBuilder()
.name("water").name("h2o2")
.component(/*components*/)
.build();
You do need to take precautions on your set for the following facts:
- No illegal particles should be constructable, unless of course a client implements
GenericParticle
on his own, but for that you have documentation to ensure he does the correct things. - The performance of defensive copying is not the best, but you absolutely want the strings to be immutable. You could consider either implementing an immutable list yourself (it should not be possible to change the elements in the list), or use one provided by a library such as guava (preferable). I wouldn't use a String array as they put a lot of burden on other developers and yourself, I would prefer objects.