The architecture of a software system
refers to its overall design.
Examples of architectural patterns include
pipelines, open systems, client-server, peer-to-peer, agent-based, Model-View
Controller, etc.
The simplest one is the Layered
Architecture:
The business layer (also called the domain
layer) contains business logic and data. Business doesn't necessarily mean
"commercial activity". For example, in Maze Challenge the Maze class
which keeps track of the number of moves made and the positions of the exit and
the player. It also provides the "business logic" for moving the
player.
This layer provides general services to
the layers above. In Maze Challenge these services might include:
· Saving and reading mazes to files,
· Providing notification to observers of any changes
in the Maze
· Providing utility functions such as a random number
generator, functions that pop up dialog boxes, etc.
Hints
· Consider adding an abstract Model class to
the framework layer that Maze will inherit from. The Model class contains
details about file names, unsaved changes, observer notification, etc.
· Consider using a utility class for other
services. Recall that the members of a utility class are static.
The presentation layer is all about user
input and output. It contains the program's user interface (frame) and its
components: views, menus, and control panels.
Maze Challenge's UI is built using Java's
Swing library. It consists of the Maze Challenge frame (a JFrame
in Swing) and it's three children: the menu bar (JMenuBar),
the control panel with its buttons and text fields (JPanel),
and its view (JCompnent) that shows the rooms of the
maze and the position of the player.
While the presentation layer is concerned
with user input and output, it's the job of the control layer to act on user
inputs coming from the presentation layer. It does this by interacting with the
business layer and ultimately produces output which is sent back to the
presentation layer for display.
Swing uses a method called Event
Delegation. In this scheme listener objects are assigned to controls (menus,
buttons, test fields, etc. ) A listener is
automatically notified when any of its assigned controls is activated by the
user.
Here's a sequence diagram showing the flow
of control:
Notice the dashed arrows in the package
diagram. These are called dependency arrows. Package p1 depends on package p2
if p1 uses some of the stuff defined in p2; if p1 imports stuff from p2.
Notice that the dependency arrows only
point down, never up. That's because:
A layer never
depends on the layers above it!
For example, we might want to changes to
the MazeView class in the presentation layer. But if
the Maze class in the business layer depends on the MazeView
class, then these changes could break it.
To put it another way, we want each layer
to be as reusable as possible. When we export a class to another project we
must also export all of the classes it depends on, both directly and
indirectly. (This is called the encumbrance of a class.) We might want to reuse
our Maze class in another application with different use cases and views. This
won't be possible if the encumbrance of Maze includes views, panels, and
listeners from the original application.