-
Notifications
You must be signed in to change notification settings - Fork 797
AIMA3e Architecture and Design
Architecture and design decisions within AIMA3e are driven by the following design goals:
-
Algorithms should semantically be implemented as close as possible to the textbook.
-
The design should be flexible and extendable. A wide range of experiments with existing algorithms should be supported as well as experiments with own extensions / variants of existing algorithms.
-
Redundancy should be avoided where possible.
-
Object-oriented design is assumed to be key for reaching goals 2 and 3.
-
The implementation of the core algorithms should not depend on example applications, GUI stuff etc.
-
The implementation of the core algorithms should be efficient enough to be applicable in serious application scenarios, not just for demonstration purposes.
Goals 2 and 3 force to add architecture to the set of algorithms presented in the textbook. Common aspects of algorithms must be factored out. In an object-oriented design (Goal 4) this leads to a distribution of responsibilities to different objects. This is why a one-to-one mapping from pseudocode to Java code cannot always be expected.
AIMA3e consists of three main sub-projects and an additional helper sub-project which form the top-level directories of the project:
- aima-core (implements most algorithms from the textbook in an extendable and reusable way)
- aima-gui (provides command line demos and graphical applications based on Swing and JavaFX)
- aimax-osm (provides example applications based on OpenStreetMap data)
- aima-all (provides ant-scripts for creating releases)
The sub-projects use Maven directory layout. When defining source paths manually, remember that in most cases two directories are needed: src/main/java
and src/main/resources
. Sub-project aima-core additionally contains unit test sources in directories src/test/java
and src/test/resources
.
The three main sub-projects are organized as layered architecture. There are no dependencies from bottom to top:
The usual Java naming conventions are applied, especially:
- Package names are all lower case.
- Class and interface names are written in UpperCamelCase.
- Attribute, method, and variable names are written in lowerCamelCase.
For detailed rules on styling, see Google Java Style Guide.
Additionally, special endings are used for names of runnable classes with a static main method:
- ...App : An application with GUI (JavaFX or Swing).
- ...Demo : A command line demo program.
To increase extendibility and readability at the same time, Gang-of-Four design patterns (see Design Patterns. Elements of Reusable Object-Oriented Software. Gamma et al.) are extensively used. Some examples are listed here:
-
Observer
- In AbstractEnvironment, method
step
: Inform interested views about changes in the environment without becoming dependent on the concrete listener implementations. - In NodeFactory (part of every search implementation): Inform interested listeners about
getSuccessors
calls (e.g. for progress visualization) without becoming dependent on the concrete listener implementations. - In CspSolver: Support progress analysis and visualization.
- In AbstractEnvironment, method
-
Template Method
- In AbstractEnvironment, method
step
: Implement agent simulation independent of what the agent sees and how his actions change the state in a concrete environment. - In SimpleProblemSolvingAgent, method
act
: Provide a general implementation for (offline) problem solving and let subclasses decide, how to formulate a goal and a problem, and which search algorithm to use. - In IterativeDeepeningAlphaBetaSearch, method
makeDecision
: Provide a general game-independent implementation for making decisions in limited time and give room for tuning in specialized implementations. - In AbstractBacktrackingSolver, method
backtrack
: Define a general backtracking strategy for CSPs independent from implementation details of heuristics and inference methods.
- In AbstractEnvironment, method
-
Factory Method
- In IntegrableApplication, method
createRootPane
: Provide general infrastructure for an application and delegate the construction of the root pane content to subclasses. Here, methodstart
is also an example of a template method.
- In IntegrableApplication, method
-
Strategy
- In FlexibleBacktrackingSolver: Make algorithms for selecting variables, ordering domains, and inference easily exchangeable.
-
Bridge
- In QueueBasedSearch, QueueSearch: Separate node prioritization from controlling search execution.
-
Builder
-
IntegratedAppBuilder: Create an integrated demo application by registering classes of command line demos and FX demo applications and let a builder create a common menu-based starter for all those demos (e.g. IntegratedAimaFxApp).
-
TaskExecutionPaneBuilder: Define logical elements for an application (parameters, methods for initialization and running the task, state view) on a high level of abstraction and let a builder do the rest (create panes and controls, arrange the elements, ...). See VacuumAgentApp, method
createRootPane
for an example.
-
-
Adapter
- MapAdapter: Provide a simple Map implementation for a complex Open Street Map based OsmMap and by that make real-world data available for aima-core MapAgents.
-
Visitor
- In Model, method
isTrue(Sentence)
: Evaluate truth of different kinds of sentences without polluting sentence representation with evaluation code and without downcasts. - In OsmMap, method
visitEntities
: Give a wide range of processors access to the different map entities, e.g. map renderers and export modules.
- In Model, method
As an extensive study of taxonomies of animals will not necessarily lead to a good understanding of a living ecosystem, understanding complex object-oriented software by just code reading is difficult, too. A hybrid approach of studying code and code documentation together with watching execution step by step by means of a debugger might have more chances of success. Command line demos (see package demo) and unit tests (see package unit) are good starting points. Breakpoints help to reach interesting execution phases quickly.
More detailed design documentation can be found at the following pages: