2. 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
3. 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
• Layer N is at the top and contains classes that interact
directly with the system's clients
Client Layer N
Layer N-1
Layer 2
Layer 1
4. 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
– Layer J raises the level of
abstraction by one level
Client Layer N
Layer N-1
Layer 2
Layer 1
5. 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
Layer 3
Component Component
Component
Component
Layer 2
Component Component
Component
Component
Layer 1
Component Component
Component
Component
6. Dynamic Behavior
• Scenario I
– The most common case
– Request at Layer N travels down through each
successive layer, finally reaching Layer 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)
– Results from below are combined to produce a
higher-level result that is passed to the layer
above
Client Layer N
Layer N-1
Layer 2
Layer 1
7. 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 pre-
computes results
Client Layer N
Layer N-1
Layer 2
Layer 1
8. 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
– 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
Client Layer N
Layer N-1
Layer 2
Layer 1
9. 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
10. 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
11. Known Uses: Typical layered
application architecture
Hardware
Operating System
Data Storage/Retrieval Networking GUI Toolkit
Utilities
Application Logic
User Interface
12. Known Uses: Virtual machines - Java
Hardware A
Operating System A
Java Virtual
Machine A
Native
Application A
Java Libraries
Hardware B
Operating System B
Java Virtual
Machine B
Native
Application B
Java
Application
Java Libraries
Java
Application
13. Known Uses: Virtual machines -
VMware
Hardware A
Operating System A
Native
Application A
VMware Virtualization Layer
Operating
System B
Operating
System C
Operating
System D
Native
Application B
Native
Application C
Native
Application D
14. Known Uses: Networking protocol stacks
HTTP
TCP
IP
Ethernet
HTTP
TCP
IP
Ethernet
Physical Connection
Ethernet Protocol
IP Protocol
TCP Protocol
HTTP Protocol
Browser Web Server
15. 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
16. 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
class Manager {
Worker m_worker;
public void setWorker(Worker w) {
m_worker=w;
}
public void manage() {
m_worker.work();
}
}
Layer J – 1
class Worker {
public void work() {
// ....working
}
}
What if we need to change worker?
17. Solution: Dependency Inversion
Don’t wire the lamp directly in.
Make the lamp implement an interface
Class Y Class Z
Subsystem A Subsystem B
Class Y Class Z
Subsystem B
Subsystem A
«interface»
Interface W
Notification
Up-Call
18. Solution: Dependency Inversion
• Don’t depend on concrete – Depend on Abstractions
Layer J
interface IWorker {
public void work();
}
class Manager {
IWorker m_worker;
public void setWorker(IWorker w) {
m_worker=w;
}
public void manage() {
m_worker.work();
}
}
Layer J – 1
class Worker implements IWorker{
public void work() {
// ....working
}
}
class SuperWorker implements IWorker{
public void work() {
//.... working much more
}
}