Component based design was originally pioneered in order to avoid annoying class hierarchies that inheritance introduces. The idea in this scenario is that our entity is simply an aggregation of multiple components. These components then define that entity's behavior and attributes. I wrote a small implementation to exemplify how this could be used in an emulation context.
Entity.class
Code:
package org.glasscastle.model.entity;
import java.util.HashMap;
public class Entity {
private int index;
private final HashMap<Class<? extends EntityComponent>, EntityComponent> components = new HashMap<>();
public EntityComponent get(Class<? extends EntityComponent> clazz) {
EntityComponent component = components.get(clazz);
if (component == null)
throw new InvalidComponentException("Component for " + clazz + " could not be located.");
return component;
}
public EntityComponent add(EntityComponent component) {
return components.put(component.getClass(), component);
}
public EntityComponent remove(Class<? extends EntityComponent> clazz) {
return components.remove(clazz);
}
public boolean has(Class<? extends EntityComponent> clazz) {
return components.containsKey(clazz);
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public HashMap<Class<? extends EntityComponent>, EntityComponent> getComponents() {
return components;
}
}
EntityComponent.class
Code:
package org.glasscastle.model.entity;
public abstract class EntityComponent {
}
InvalidComponentException.class
Code:
package org.glasscastle.model.entity;
public class InvalidComponentException extends RuntimeException {
public InvalidComponentException(String message) {
super(message);
}
}
We could use this type of pattern as follows. As you can see, we're not explicitly defining an entity. Instead, we're building it from multiple different components.
Code:
Entity player = new Entity();
player.add(new MutablePositionComponent(3200, 3200, 0));
player.add(new LoginDetailsComponent("Username", "Password", "0.0.0.0"));
MutablePositionComponent position = (MutablePositionComponent) player.get(MutablePositionComponent.class);
LoginDetailsComponent details = (LoginDetailsComponent) player.get(LoginDetailsComponent.class);
System.out.println(details.getUsername() + " is standing at " + position + ".");