-
Notifications
You must be signed in to change notification settings - Fork 4
Programming in AgentSpring
In AgentSpring they are three main types of packages: domain, role, repository. Other helper packages can also exist.
All "category of things" in the simulation should be defined as classes the domain package, "things" are than instances of these classes. This package should have subpackages, if it helps to structure the logic of the simulation. For example:
- domain.agent -> should contain all agents with complex behaviour
- domain.technology -> should contain all technologies
- domain.market -> should contain all market related "things"
Domain classes should not have complex methods, only methods that give information about the class itself, or its properties. Everything else belongs into a Role Example: double cash;
- public double getCash(){return this.cash}
- public void setCash(double cash){ this.cash = cash}
- public double getCashInDollar(){ return this.cash * conversionRate}
Repositories are convenient gateways to get information about instances (or lists thereof) of classes defined in the domain packages.
Repositories are interfaces, and extensions of GraphRepository and should be named after the class that it give information about
public interface BidRepository extends GraphRepository<Bid> {
//contains the queries that we give to the database
}
Some queries like findAll() are predefined for all repositories. These predefined queries can be found
in this API
*The Queries within are defined as methods, which most of the times return primitives (double, int, etc), or Iterables of the type ClassItGiveInformationAbout (Iterable is a sort of list)
- The Queries should be named in such a way that it is clear what exactly we are searching for, and give it precisely the information it needs to find what we are searching for (Tick = Time step of simulation)
Thus a simple example could be:
public interface BidRepository extends GraphRepository<Bid> {
Iterable<Bid> findAllBidsByEnergyProducerInTick(EnergyProducer producer, long tick)
}
The name of the method should start with findAll in case we want to find more than one, and findOne if we are sure there should be only one thing of that type in the database
Contains classes with information about behaviour.
The class names should have descriptive names and end in Role, e.g. BidIntoMarketRole. It should inheret from AbstractRole and implement Role, and be specified for the agent that acts this role:
public class BidIntoMarketRole extends AbstractRole<AgentThatActsThisRole> implements Role<AgentThatActsThisRole> {
public void act(AgentThatActsThisRole agent){
//put the agents behaviour in this method
// you can add other methods to the role
// and call them from within act():
Bid currentBidForPlant = createBidForOnePowerPlant(plant)
}
Bid createBidForOnePowerPlant(PowerPlant plant){//some logic}
}
Roles are always specific about the agent that is given to the function act(Agent agent) If we want information or change information about properties of that agent, we use the getters/setters of that class:
double cashOfTheAgent = agent.getCash();Set<PowerPlant> allPowerPlantsOfThatAgent = agent.getPowerPlantSet();
If we want more complex information, or information that is not a property of that agent (i.e. there is no method in the agent to give us this information), we need to use the repositories. In a first step we just create pseudo-code by calling the repository of the type of domain class we need, and than call a method with the fitting name. Let’s say we want THE (in the sense of Single) Market Clearing point of the current period:
`ClearingPoint cp = clearingPointRepository.findOneClearingPointInTick(long tick)`
More can be found in the Repository section.