Transcript Layers
Layers Architecture Pattern
Source: Pattern-Oriented Software Architecture, Vol. 1, Buschmann, et al
Problem
• You are designing a system that needs to handle a mix of low-level and
high-level issues
– Low-level: hardware traps, sensor input, file I/O
– High-level: user interface, application logic
• High-level operations rely on lower-level ones
• User-visible functionality must be mapped onto the target platform
• Several levels of abstraction must be spanned to perform this mapping
• The system is large, and a methodical approach to organizing it is needed
to keep it understandable
Solution
•
Structure the system into an appropriate number of layers,
and place them on top of each other
•
Each layer represents a level of abstraction
•
Classes are placed in layers based on their levels of
abstraction
•
Layer 1 is at the bottom and contains classes closest to the
hardware/OS
Client
Layer N
Layer N-1
Layer 2
•
Layer N is at the top and contains classes that interact
directly with the system's clients
Layer 1
Solution
•
•
Layer J uses the services of Layer J-1
and provides services to Layer J+1
Most of Layer J's services are
implemented by composing Layer J-1's
services in meaningful ways
Client
Layer N
Layer N-1
– Layer J raises the level of
abstraction by one level
Layer 2
Layer 1
Structure
•
Layer J's services are used by
Layer J+1
•
Classes in Layer J may also use
each other
•
There are no other direct
dependencies between layers
Component
Component
Layer 3
Component
Component
Component
Component
Layer 2
Component
Component
Component
Component
Layer 1
Component
Component
Dynamic Behavior
•
Scenario I
– The most common case
Client
– Request at Layer N travels down through each
successive layer, finally reaching Layer 1
Layer N
Layer N-1
– The top-level request results in a tree of
requests that travel down through the layers
(each request at Layer J is translated into
multiple requests to Layer J-1)
Layer 2
– Results from below are combined to produce a
higher-level result that is passed to the layer
above
Layer 1
Dynamic Behavior
•
Scenario II
– Request at Layer N travels
down through successive
layers until it reaches Layer J,
which can satisfy the request
without the help of Layer J-1
– Examples
• Layer J caches previous
results
• Layer J pre-fetches or precomputes results
Client
Layer N
Layer N-1
Layer 2
Layer 1
Dynamic Behavior
•
Scenario III
– Events generated at Layer 1 travel up
through successive layers, finally reaching
Layer N
– Examples
• Interrupt generated by device driver
• Asynchronous I/O operation completes
• Signal received from OS
Client
Layer N
Layer N-1
Layer 2
– Event may stop before reaching Layer N if it
can be handled by some intermediate layer
– Multiple events at Layer J may be combined
into a single higher-level event which is sent
to Layer J+1
Layer 1
Implementation
• Determine the number of layers (i.e., abstraction levels)
• Name the layers and assign responsibilities to them
• Define the interface for each layer
• Error handling strategy
– Part of a layer's interface is the set of errors it might return
– The errors returned by a layer should match its level of abstraction
– Errors received from the layer below should be mapped into
higher-level errors that are appropriate for the layer above
– Low-level errors should not be allowed to "leak out" and become
visible to high-level layers
Relaxed Layers
• Layer J can call directly into any layer below it, not just Layer J-1
• Pros
– More flexible and efficient than strict layers
– Easier to build than strict layers
• Cons
– Less understandable and maintainable than strict layers
Known Uses: Typical layered
application architecture
User Interface
Application Logic
Utilities
Data Storage/Retrieval
Networking
Operating System
Hardware
GUI Toolkit
Known Uses: Virtual machines - Java
Java
Application
Java
Application
Java Libraries
Java Libraries
Java Virtual
Machine A
Native
Application A
Java Virtual
Machine B
Native
Application B
Operating System A
Operating System B
Hardware A
Hardware B
Known Uses: Virtual machines VMware
Native
Application A
Native
Application B
Native
Application C
Native
Application D
Operating
System B
Operating
System C
Operating
System D
VMware Virtualization Layer
Operating System A
Hardware A
Known Uses: Networking protocol stacks
Browser
Web Server
HTTP
HTTP Protocol
HTTP
TCP
TCP Protocol
TCP
IP
IP Protocol
IP
Ethernet
Ethernet Protocol
Ethernet
Physical Connection
Consequences
• Dependencies are organized in an understandable way
• Individual layers can be reused, modified, or replaced
– Peel off UI layer, replace with different style of UI
– Modify data storage layer to use a different database
– Lower layers can be reused in an entirely different application
• Lower efficiency
– Overhead involved in moving between layers
Consequences
• Dependencies between layers can cause problems when a layer needs
to be modified.
– Layers above and below may be affected, and so on….
• Example
Layer J
Layer J – 1
class Manager {
Worker m_worker;
public void setWorker(Worker w) {
m_worker=w;
}
public void manage() {
m_worker.work();
}
}
class Worker {
public void work() {
// ....working
}
}
What if we need to change worker?
Subsystem A
Subsystem B
Class Y
Class Z
Solution: Dependency Inversion
Notification
Up-Call
Subsystem A
Subsystem B
Class Y
Class Z
«interface»
Interface W
Don’t wire the lamp directly in.
Make the lamp implement an interface
Solution: Dependency Inversion
• Don’t depend on concrete – Depend on Abstractions
Layer J
Layer J – 1
interface IWorker {
public void work();
}
class Manager {
IWorker m_worker;
class Worker implements IWorker{
public void work() {
// ....working
}
}
public void setWorker(IWorker w) {
m_worker=w;
}
public void manage() {
m_worker.work();
}
}
class SuperWorker implements IWorker{
public void work() {
//.... working much more
}
}