Skip to main content
Software Engineering

Architectural Design: Control Models

Published: 2026-08-15
Level: postgraduate
Audience: Postgraduate students in Software Engineering

Prerequisite Knowledge

This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.

Previously Covered in This Subject

  • Architectural design and why it matters — covered in Lecture 5 (Architectural Design)
  • The three stages of the architectural design process — system structuring, control modeling, and modular decomposition, covered in Lecture 5
  • Structural models — layered, repository, client server, and pipes and filters, covered in Lecture 5
  • Application architectures — transaction processing and language processing systems, covered in Lecture 5
  • Box-and-line diagrams and architectural design decisions — covered in Lecture 5

6.1 Architectural Design: Role, Stages, and Models

6.1.1 The role of architectural design in the development process

Why does architecture matter? A system can be functionally correct and still fail in practice — too slow, too hard to change, or too easy to break. The architecture is where those "quality" characteristics get decided, so a small mistake here can be expensive to fix later.

Architectural design establishes the overall structure of a software system: the way the components and modules are designed, the interfaces between them, and the communications between the various components. It sits between requirements engineering and the design phases of software engineering. Requirements engineering decides what the system must do; architectural design decides the shape of the system that will do it; the design phases that follow fill in the details of that shape.

We need several different models to describe an architecture because one diagram cannot carry structure, runtime behavior, and data flow at the same time. A single picture is like a single photograph of a building: it shows one angle, but an architect needs floor plans, wiring diagrams, and plumbing layouts before the building can be built. Architectural design also supports reuse: a good architecture carries across products of a similar category within the application domain. Systems in the same domain often share the same skeleton, so the architecture itself becomes a reusable asset. The previous session covered the importance of architecture, architectural models drawn as box and line diagrams, and architectural design decisions.

The organization of a system reflects the basic strategy used to structure the system. So the overall organizational model has to be decided early in the design process — early enough to structure the requirements engineering process itself. In other words, the high-level shape of the system is often chosen while requirements are still being gathered, because the requirements discussion is easier when stakeholders can point at large components. The system organization may show up directly in the subsystem structure and in how the subsystems are interconnected. Even so, the subsystem model usually carries more detail than the overall architectural structural model. There is also no simple mapping between the subsystem structural models and the overall system organizational architecture: the same high-level organization can be realized by very different subsystem structures.

In the wider discipline, architecture is seen as the dominant influence on non-functional characteristics such as performance, security, safety, availability, and maintainability. Components deliver the functional requirements; the way those components are organized decides whether the system is fast enough, secure enough, and cheap enough to maintain.

6.1.2 The three stages of the architectural design process

The architectural design process has three steps. They are usually tackled in this order, though in practice the stages feed back into each other as new information appears.

  1. System structuring: decompose the system into several subsystems and identify the communications between these subsystems. Several architectural styles are used to structure the system into subsystems. This is the stage where the architect picks the big skeleton — layered, repository, client server, pipes and filters, and so on — and decides which subsystems talk to which.
  2. Control modeling: model the control relationships between different parts of the system while the system is in execution, that is, at runtime. Structuring says what exists; control modeling says who drives whom when the system runs. This stage is the focus of the rest of this session.
  3. Modular decomposition: after system structuring, decompose the subsystems into modules. Each subsystem is broken into smaller, individually designable and implementable units, which become the targets for detailed design and coding.

The three stages answer three different questions about the same system: how it is divided, how it is controlled, and how each piece is built in detail.

6.1.3 The variety of architectural models

Depending on what we want to communicate, we can build different kinds of models. Each model type answers one kind of question, and an architecture is usually described with several of them together:

  • a static structural model based on some architectural pattern — this shows the system as a set of components and subsystems and how they are connected, without worrying about when anything runs;
  • a dynamic process model, which is the control model — this shows how control moves between subsystems while the system is executing, and it is the subject of the next section;
  • an interface model — this defines the services each subsystem offers and the contracts the other subsystems rely on when they use those services;
  • a data flow model that shows the flow of information and the relationships between entities — this tracks where data is produced, transformed, and consumed.

The useful mental model: the structural model is a map of the system, the control model is the schedule, the interface model is the contract, and the data flow model is the movement of goods on that map. No single one of these replaces the others.

6.1.4 Structural models from the previous session

At a high level, architectural design is informally expressed as a box and line diagram. This is a very high level abstract view of the systems and subsystems and their interaction. It gives little detail about the type of interaction or the flow of control or information between them. More specific models show how the subsystems are structured, how they share data, how they are distributed, and how they interface with each other. The main structural models are:

  • Layered model: the system is arranged in layers, each layer offering services to the one above it. A layer only relies on the layer immediately beneath it, so a change inside one layer does not ripple through the whole system. Real-world: a typical web application — browser interface, business logic, and database support sit in separate layers, and each can be replaced independently.
  • Shared repository model (shared data model): subsystems share data through a central store that all of them access. Components do not talk to each other directly; they communicate through the repository. Real-world: an integrated development environment (IDE) where editors, compilers, and debuggers all read and write the same project data. The downside is that the repository is a single point of failure.
  • Client server model: a distributed system model with a number of clients and servers. Clients request services; servers provide them, usually over a network with a request–reply pattern. Real-world: a film or photo library where separate servers manage the catalog, video, and pictures, and browsers act as clients.
  • Pipes and filters model: a sequence of processing elements that transform input data at various stages into the output. Each filter takes a stream, transforms it, and passes the result to the next filter through a pipe. It is usually suitable for batch processing of data. It also suits applications where the format of the data is consistent across all the processes. Real-world: an invoicing batch — read issued invoices, identify payments, issue receipts, find payments due, issue reminders — where each step is one filter.

The four patterns are not rivals for the same job; each answers a different need:

Model Core idea Choose it when
Layered Services flow upward, layer by layer You want portability, multilevel security, or several teams each owning a layer
Shared repository All subsystems access one central store Large volumes of shared data are generated and reused for a long time
Client server Clients ask servers for services over a network Many clients need shared services from different locations
Pipes and filters Data streams through a sequence of transforms Batch processing with a consistent data format across stages

Real-world: beyond these, patterns such as the MVC architectural pattern and the microservices pattern are familiar from everyday application development work. You will use them in your regular work as part of application development. MVC splits a system into model (data), view (presentation), and controller (user interaction), so the data can change independently of how it is shown; microservices split a large system into small, independently deployable services that talk over a network.

6.1.5 Application architectures from the previous session

Application architectures are the structures that recur across whole categories of applications. They are the same shapes appearing in system after system within a domain, so a designer can start from the known shape instead of inventing one from nothing.

  • Transaction processing systems: these process user requests that read from or update a database. They include e-commerce applications; an ATM is an example. A customer's cash withdrawal is treated as one transaction: check the balance, modify it, and dispense the cash — either all happens or none does.
  • Information systems: these allow controlled access to a large base of information such as a library catalog or patient records. They typically use layered architectures, with a user interface layer on top, application logic in the middle, and a database at the bottom.
  • Language processing systems: these translate a language into another representation. They can use pipes and filters, a repository model, or a hybrid of the two. A compiler is the classic case.

Worked example — the compiler as a language processing system. Consider a compiler for a programming language, built from the familiar phases.

Repository version: a central repository holds the symbol table (the names of variables, classes, and functions) and the syntax tree (the internal structure of the program being compiled). The modules work on this shared data:

  • the lexical analyzer reads the source text and converts tokens into an internal form;
  • the syntactic analyzer checks the grammar and builds the syntax tree;
  • the semantic analyzer uses the syntax tree and the symbol table to check semantic correctness;
  • the code generator walks the tree and produces machine code.

Every phase reads and updates the same repository, so the phases do not need to pass data to each other directly.

Pipes and filters version: the same phases are arranged as a pipeline — lexical analysis feeds syntactic analysis, which feeds semantic analysis, which feeds code generation — with each phase transforming the stream and passing it on.

Hybrid: in practice a compiler is often a hybrid: the phases act as a pipeline of processes, but they all still access the repository holding the symbol table and the syntax tree.

Final answer: one compiler can be modeled either way — repository, pipes and filters, or the hybrid of both. Sense-check: each phase consumes the output of the previous phase in the pipeline view, while in the repository view all phases share one structure — both describe the same working compiler, so the choice of model depends on what the diagram should communicate.

Anyone who has worked on compiler design will recognize this. Compiler design is typically studied in undergraduate work. Some students have also built compiler modules as part of a project or an assignment — at least a lexical analyzer, a syntactic analyzer, and a semantic analyzer. Building those modules means choosing an architecture very much like this one: typically the repository architecture, which is applicable to a variety of systems. The same compiler can also be modeled with pipes and filters, so one system can be shown either way.

Recap: Architectural design is the bridge between requirements engineering and detailed design, and it has three stages — system structuring, control modeling, and modular decomposition. Structural models (layered, repository, client server, pipes and filters) and application architectures (transaction processing, information systems, language processing) describe the shape of the system. But the shape alone does not say who is in charge at runtime — that is the job of the control model, the next topic.

6.2 Control Models: How the System Behaves at Runtime

6.2.1 Control models vs structural models

Control models describe the runtime behavior of the software, and they are distinct from structural models. Structural models are concerned with how a system is decomposed into subsystems and then into modules. Control models are concerned with the control flow between subsystems while the system operates — in short, how the system is controlled when it is running.

For the subsystems to work together as a system, they must be controlled so that their services are delivered to the right place at the right time. A bank's subsystems might be perfectly structured on paper, but unless something decides when the cash-dispensing unit runs, when the account check runs, and in what order, the ATM delivers nothing. That "something" is the control model.

Think of it like traffic on a city's streets. The structural model is the street map: it shows the roads, the neighborhoods, and how they are connected. The control model is the traffic-light timing and the dispatch schedule: it decides which vehicle moves, when it moves, and in which order. A map alone never tells a car when to go; a schedule alone never tells it where the roads are. The two views describe the same city but answer different questions. The analogy breaks in one way: a street map is static, while the control model is about time — it only exists while the system is running.

None of the structural patterns we saw — repository, layered, pipes and filters, client server — includes control information. The architect must organize the subsystems according to some control model that supplements the structural model being used.

Q: Why can't the control information just live inside the structural model? A: Because the structural patterns describe only how the system is decomposed into subsystems and modules; they do not include control information. A repository model says "subsystems share one store," but it never says who starts, who stops, or who runs first. Control models are a separate view of how the system is controlled when it is operating. The architect picks a control model that supplements the chosen structural model — the two views are used together, not instead of each other.

6.2.2 Two generic control types

Two generic control types cover most software systems.

  1. Centralized control: one subsystem has overall responsibility for control and starts and stops other subsystems. It may hand control to another subsystem, but it expects the control responsibility to come back to it, the way control returns in a normal program. One boss, giving orders and expecting them to be executed and reported back.
  2. Event-driven control: used when the system must respond to externally generated events. Instead of control being embedded in one subsystem, each subsystem is programmed to respond to externally generated events. These events may come from other subsystems or from the environment of the system. No single boss: each part reacts when something happens, and the "something" can arrive at any time.

The two types answer the same question — "who decides what runs next?" — in opposite ways:

Dimension Centralized control Event-driven control
Who holds control One designated subsystem with overall responsibility No fixed owner; each subsystem reacts on its own
When decisions happen On a schedule: the controller polls, checks, and dispatches On demand: an event triggers a response
Where the trigger comes from Inside the controlling subsystem's loop Outside the responding subsystem — other subsystems or the environment
Typical fit Sequential and soft real-time systems Interactive, distributed, and hard real-time systems
Failure mode Everything stalls if the controller fails A subsystem may not know whether its event was ever handled

When to pick which: choose centralized control when the work follows a predictable sequence or a soft deadline and one coordinator can manage it; choose event-driven control when the system must react to things that can happen at any moment, especially from outside the system.

The rest of this session looks at each type in detail: the two flavors of centralized control first, then the two flavors of event-driven control.

6.3 Centralized Control

6.3.1 The call-return model

In a centralized control model, one subsystem is designated the system controller and has the responsibility for managing the execution of the other subsystems. Centralized control models fall into two types, depending on whether the controlled subsystems execute sequentially or in parallel. For sequential systems we use the call-return model; for concurrent systems we use the centralized management model.

The call-return model is the familiar top-down subroutine model. Control starts at the top of the subroutine hierarchy, the main function. Through subroutine calls — the main program calls routine 1, which in turn calls subroutine 1.1 — control passes to lower levels of the hierarchy. When subroutine 1.1 completes its task, control returns to routine 1. When that routine completes its task, control returns to the main program, which may then invoke the next routine.

Worked example — a three-level call chain. Suppose the main program must process two reports, and each report is prepared by a routine that delegates its printing to a subroutine.

  1. The main program starts and calls routine 1 ("prepare first report").
  2. Routine 1 does its own work, then calls subroutine 1.1 ("print report").
  3. Subroutine 1.1 runs to completion, then returns control to routine 1 — the module that called it.
  4. Routine 1 finishes its remaining work and returns control to the main program.
  5. The main program now calls routine 2 ("prepare second report"), and the same pattern repeats.

Final answer: every call returns to its caller, so control always comes back up the same chain it went down. Sense-check: at no point does control jump sideways to a routine that never asked for it — that is exactly the discipline the model enforces.

This model is applicable only to sequential systems, where one set of instructions is executed at a time. Anyone who has written programs in a language like C knows the pattern. Think of a large program: you have a main module and many submodules or functions. Once a function is called, its task is executed, and control returns to the calling module or the main module — the same shape as this hierarchy. The model describes the dynamics of the program — how control moves — not a structural model of the code. A subroutine that is called by another subroutine does not need to be physically nested inside it: subroutine_1_1 may live anywhere in the code, and it is the call that links it to routine 1, not its location.

Think of it like a chain of command. The main program is the manager who hands out tasks. Each worker (routine) may delegate part of the task to a junior (subroutine), but the junior reports back to the worker who delegated it, and the worker reports back to the manager. You never walk away from your desk, hand your result to someone in another department, and leave — that would break the chain. This is why the model feels natural to anyone who has written ordinary programs: the calling convention of C and Java produces exactly this shape.

The currently executing subroutine holds the responsibility for control: it can call other subroutines or return to its parent. Returning control to some other point in the program rather than to the calling module is poor programming style. It bypasses the caller, which may still have cleanup to do, and it makes the flow of control unpredictable. If you have ever seen a program that used an unconditional jump or a long jump to "escape" out of a deeply nested call, you have seen this anti-pattern in practice.

The call-return model can be used at the module level to control functions or objects. Subroutines called by other subroutines are naturally functions in functional programming; in object-oriented systems, the operations of objects — methods — are implemented as procedures or functions. When a Java object requests a service from another object, it does so by calling an associated method: object A invokes b.calculate() and expects control to come back to A when the call finishes. The same top-down discipline applies at the object level.

6.3.2 Strengths and weaknesses of the call-return model

The model is a little bit rigid and restricted, and that shows up as one clear strength and one clear weakness.

The strength: it is relatively simple to analyze the control flows and work out how the system will respond to particular inputs. Because every call returns to its caller, the path a request takes is a tree that can be traced by hand: follow the calls down, follow the returns up, and the response to any input is predictable. This makes the model easy to reason about, to test, and to explain to a new member of the team.

Pitfall — the weakness that follows from the rigidity: exceptions to normal operations are sometimes difficult to handle, and exception handling can be hard to program. In C, for example, there is no built-in exception mechanism, so a routine deep in the hierarchy that hits an error must signal it by returning a special error code — and every routine above it must check that code and pass it upward, one level at a time. Handling a rare failure inside a ten-level call chain can mean editing all ten levels. In languages with exceptions, the model still shapes the thinking: an exception unwinds the call chain, and the handler lives in the caller, so the hierarchy is still the backbone of the design.

6.3.3 The centralized management model

The centralized management model (the manager model) is used for concurrent systems, often in soft real-time systems that do not have very tight time constraints. One system component acts as a monitor or manager that watches the other subsystems and controls the starting, stopping, and coordination of the other processes. Unlike the call-return model, the managed processes may run in parallel; the manager does not wait for one process to finish before dealing with another.

A process, in this context, is a subsystem or a module that can execute in parallel with other processes.

Worked example — building and home monitoring systems. A building monitoring system protects a building against intrusion and fire. All processes run under one central controller.

The controller manages several kinds of processes:

  • sensor processes — read smoke detectors, heat sensors, door and window contacts;
  • actuator processes — control alarms, sprinklers, door locks;
  • computation processes — analyze readings, decide whether a situation is dangerous;
  • a user interface — shows the building state to the guard;
  • a fault handler — reacts when a component misbehaves.

Now trace a fire during the night:

  1. The controller starts the sensor processes, the user interface, and the fault handler when the system boots; the alarm actuator stays stopped.
  2. A smoke sensor process reads a rising smoke level and stores the reading as a system state variable.
  3. The controller notices the state change, decides that the fire condition holds, and starts the alarm actuator process — the siren sounds.
  4. The controller passes the sensor information to the computation processes for processing, so the location of the fire can be estimated and shown on the user interface.
  5. The controller starts the intrusion alarm process too if a door sensor trips while the alarm is active.
  6. When the smoke readings return to normal, the controller stops the alarm actuator process again.

Final answer: every process start and stop is a decision made by the central controller based on the system state variables. Sense-check: if the smoke sensor dies, the controller can hand the problem to the fault handler — the decision still happens in one place, which is exactly what "centralized" means here.

The controller also checks whether other processes have produced information to be processed, and passes information to them for processing — the manager is not just a start/stop switch; it is also the traffic director for data between the managed processes.

A form of this model may also be applied in sequential systems. A management routine calls particular subsystems depending on the values of some state variables, usually implemented as a case statement — if these conditions hold, activate these subsystems. This is the sequential cousin of the manager model: the same "look at the state, then decide" logic, but executed as a plain switch rather than as parallel process management.

6.3.4 The event loop model

The controller usually loops continuously, pulling sensors and other processes for events or state changes. For this reason, the model is sometimes called the event loop model. It is the usual choice for soft real-time systems that run several processes concurrently.

Q: In the manager model, how does the central controller know when something has happened? A: It does not wait for signals. It loops continuously, pulling sensors and other processes for events or state changes — that is why the model is sometimes called the event loop model. The controller repeats a cycle: poll every process it manages, read the state variables, decide whether anything needs starting or stopping, act, and loop again. Nothing is delivered to it; it goes and fetches.

Picture the loop as a circle: poll (ask each process what its state is), analyze (compare against the conditions that matter), act (start or stop processes, pass data on), then repeat from the top. The loop never ends while the system is running, and the shorter the loop time, the faster the system notices a change — but also the more processor time the polling consumes.

Recap: Centralized control puts one subsystem in charge. For sequential systems, the call-return model hands control down a subroutine hierarchy and gets it back at every level. For concurrent soft real-time systems, the manager model continuously polls its processes and starts or stops them as the state demands. The polling loop is so typical that this model also carries the name "event loop model." Next we turn the picture around: instead of the controller checking for changes, the system waits and reacts when a change arrives on its own.

6.4 Event-Driven Control

6.4.1 What counts as an event

Event-driven systems respond to internally or externally generated events in real time. In centralized control models, the control decisions are usually determined by the value of some system state variables. In event-driven control systems, the system is activated and driven by externally generated events. The difference is the direction of initiative: a central controller checks whether something needs doing; an event-driven subsystem is interrupted in its work when something needs doing.

The term event does not just mean a binary signal. It may be a signal that can take a range of values, or a command input from a menu. The distinction between an event and a simple input is that the timing of the event is outside the control of the process that handles that event. An external or internal event can occur at any time; a signal can arrive at any moment.

Think of it like a ringing phone. You cannot predict the moment it rings, and you cannot make it ring on your schedule — the caller decides. The same is true of an event: the process that handles it does not control when it arrives. A simple input, by contrast, is like a form you fill out: you feed it in when you are ready to process it. The content matters less than the timing — even a plain signal becomes an event if it can arrive at an unpredictable moment.

Q: Isn't an event just a binary signal? A: No. An event may be a signal that can take a range of values, or a command input from a menu. What makes it an event is that its timing is outside the control of the process that handles it. A temperature reading of 57 degrees is not binary, yet it is a perfectly good event for a monitoring system; a "save file" menu command is a meaningful event for an editor even though the user can trigger it at any moment. The defining property is when it arrives, not what it contains.

6.4.2 Kinds of event-driven systems

Many kinds of systems are event-driven.

  • Editors, including program editors, driven by user interface events that signify editing commands. Every key press and menu selection is an event that the editor turns into an editing action.
  • Rule-based production systems, used in AI applications, where a condition becoming true can trigger an action. The system has a set of rules; when a fact changes and a rule's condition becomes true, that rule fires.
  • Active objects, where changing the value of an object's attribute triggers some action. The object notices that one of its properties changed and reacts without being asked.
  • Spreadsheets, where a change in one value correspondingly changes the related values in the spreadsheet. The user edits one cell; the spreadsheet recomputes every dependent cell on its own.

The pioneering text on software architectures by Garlan and Shaw discusses these kinds of event-driven systems. (The name is sometimes transcribed as "Garland".)

Worked example — spreadsheet value propagation. A small sheet has three cells: C1 holds the formula A1 + B1, and C2 holds the formula C1 × 2.

  1. Initially A1 = 2, B1 = 3, so C1 = 2 + 3 = 5 and C2 = 5 × 2 = 10.
  2. The user changes A1 from 2 to 7. This edit is an event for the spreadsheet.
  3. The spreadsheet recomputes the dependents of A1: C1 becomes 7 + 3 = 10, and because C1 changed, C2 becomes 10 × 2 = 20.
  4. The user then changes B1 from 3 to 1. C1 becomes 7 + 1 = 8, and C2 becomes 8 × 2 = 16.

Final answer: one edit (A1 = 7) rippled into C1 = 10 and C2 = 20; a second edit (B1 = 1) moved them to 8 and 16. Sense-check: every changed cell triggered recomputation of the cells that depend on it — the spreadsheet did not wait for a central controller to tell it to recalculate; the change itself drove the work.

We look at two event-driven control models: the broadcast model and the interrupt-driven model. Broadcast models work well for integrating subsystems distributed across different computers on a network, while interrupt-driven models are used in real-time systems with very stringent timing requirements.

6.4.3 The broadcast model

In a typical broadcast model, subsystems register an interest in specific events — in this respect it works like a client server model. When those events occur, control is transferred to the subsystem that can handle the event.

The distinction from the centralized control model used for soft real-time systems: the control policy is not embedded in the event and message handler. Subsystems decide which events they require, and the event and message handler ensures that those events are sent to them. The events are broadcast; the subsystems that are programmed to respond to a specific event respond to it. Nobody prescribes from above which subsystem must react to which event — each subsystem declares its own interests.

All events could be broadcast to all subsystems, but that would impose a great deal of processing overhead. More often, the event and message handler maintains a register of subsystems and the events of interest to each subsystem. A subsystem generates an event indicating, perhaps, that some data is available for processing. The handler detects the event, consults the event register, and passes the event to the subsystems that declared an interest.

The event handler also usually supports point-to-point communication: a subsystem can explicitly send a message to another subsystem. Broadcast and point-to-point are both available, so subsystems can either shout an event to whoever is listening or whisper directly to a named partner.

Worked example — event listeners in a personal computer. A desktop computer is driven by user interface events from the mouse and the keyboard. Explicit event listener subsystems listen for events from the mouse and the keyboard, and translate these events into more specific commands.

  1. The user clicks the "File" menu. The mouse listener detects the click, looks it up, and emits the specific command "open the File menu."
  2. The user presses Ctrl+S. The keyboard listener recognizes the key combination and emits the command "save the current document" instead of the plain "type the letter S."
  3. While the user drags a scroll bar, the mouse listener emits a stream of "scroll by N pixels" commands, each triggered by a fresh mouse event.

Final answer: the raw hardware events — a click at coordinates (120, 45), a key press — are translated by listeners into meaning-specific commands that the rest of the system can act on. Sense-check: the applications never read raw mouse positions themselves; they register for the translated commands, so they stay independent of the hardware details.

6.4.4 Advantages and drawbacks of the broadcast model

The advantages of the broadcast model:

  • Evolution is relatively simple. A new subsystem that handles particular classes of events is integrated by registering its events with the event handler. No existing subsystem has to change — the new one simply declares its interests.
  • Any subsystem can activate any other subsystem without knowing its name or location. The sender never needs an address book; it generates the event and the handler delivers it.
  • Subsystems can be implemented on distributed machines, and the distribution need not be known to the subsystems: it is transparent. They simply interact over a network as they normally do, whether they sit on the same computer or in different buildings.

The drawbacks of the broadcast model:

  • Subsystems do not know if or when events will be handled. When a subsystem generates an event, it does not know which other subsystems registered an interest in that event. The sender cannot rely on a reply, so it cannot easily verify that its work was consumed.
  • Different subsystems can register for the same events, which can cause conflicts when the results of handling an event by multiple subsystems are made available. Two subsystems may both react to "data available" and both try to process the same data, stepping on each other.
  • The model does not fit real-time systems. Systems that must handle externally generated events very quickly must be event-driven in the interrupt sense, covered next.

Pitfall: the most common beginner mistake is treating broadcast delivery as guaranteed. Because the sender does not know who registered — or whether anyone registered — a system that depends on a reply will hang or corrupt its state when the intended consumer is missing. Design for the case where nobody responds.

6.4.5 The interrupt-driven model

Real-time systems that require externally generated events to be handled very quickly must be event-driven. Consider a real-time system controlling the safety systems in a car. It must detect a possible crash and inflate an airbag before the driver's head would hit the steering wheel. Providing that rapid response requires interrupt-driven control.

There are a known number of interrupt types, each a class of external events with a specific handler defined for it. Each type of interrupt is associated with a memory location where its event handler's address is stored. When an interrupt of a particular type is received, a hardware switch causes the control to be transferred immediately to its event handler. The interrupt handler may then start or stop other processes in the system in response to the event signaled by the interrupt. In the car example, the crash interrupt invokes a process that inflates the airbag immediately, before the driver's head can move toward the steering wheel.

Worked example — the automotive airbag system. The car's safety system must react to a collision faster than the human body can move.

The timing chain:

  1. At time 0, the vehicle crashes. Impact sensors in the front of the car detect the sudden deceleration and raise a crash interrupt.
  2. The hardware recognizes the interrupt type and immediately transfers control to the memory location holding the crash handler's address — this is a hardware switch, not a software poll, so there is no waiting for the main program to notice.
  3. The crash handler runs: it starts the process that fires the airbag inflator, and the airbag begins to fill.
  4. The airbag is fully inflated within a few tens of milliseconds — well before the driver's head, still moving forward from the impact, reaches the steering wheel.

Final answer: the interrupt cut the detection-to-response delay down to the bare hardware time, and the airbag inflated before the driver's head reached the steering wheel. Sense-check: with polling, the response would have to wait until the controller's loop happened to check the sensor — a delay measured in whole loop cycles, which is far too slow for a crash. That is why the interrupt path bypasses the loop entirely.

This model is mostly used in real-time systems where an immediate response to some event is necessary. It may be combined with the centralized management model: the central manager handles the normal running of the system, and interrupt-based control handles specific emergencies. The manager keeps the routine processes running in its polling loop, while the interrupt handler jumps in the moment a critical event arrives.

6.4.6 Strengths and drawbacks of interrupt-driven control

The strength: it allows very fast responses to events to be implemented.

The drawbacks:

  • It is complex to program and difficult to validate, because a separate event handler is needed for each and every exceptional event that may occur. Every handler is a small program of its own, with its own assumptions about the state of the rest of the system, and every one of them has to be written and checked.
  • It may be impossible to replicate patterns of interrupt timing during system testing. A handler may work perfectly in a thousand tests and still fail on the one timing pattern that the tests never reproduced — two interrupts arriving almost together, for example.
  • Systems built with this model are hard to change when the number of interrupts is limited by the hardware. Once the limit is reached, no other types of events can be handled.

Pitfall: beginners assume the fast response is free. In reality every new exceptional event adds a handler, a hardware interrupt assignment, and a new set of timing interactions — the fast path is bought with complexity, and that complexity is exactly what makes validation so hard.

6.4.7 Interrupt mapping and its limits

The hardware limit can sometimes be worked around by mapping several types of events onto a single interrupt. The handler then works out which event has occurred and invokes the corresponding process. Instead of needing a separate hardware interrupt for each event type, the system groups several related events under one interrupt number and lets the handler disambiguate them.

But interrupt mapping may be impractical when a very fast response to individual interrupts is required, as in an automotive crash prevention system. The disambiguation step costs time: the handler must first discover which event occurred and then dispatch to the right process. In a crash, those extra microseconds are precious, so each safety-critical event type keeps its own dedicated interrupt.

Recap: Event-driven control flips the initiative: the system reacts when an event arrives instead of checking for changes. In the broadcast model, subsystems register their interests and the event handler delivers events to them — flexible and distributed, but with no delivery guarantees. In the interrupt-driven model, hardware jumps straight to a handler on a specific interrupt — extremely fast, but complex and hard to validate. When an event demands very fast response, choose the interrupt path; when flexibility and distribution matter more, choose broadcast. Next we close the session with the third stage of architectural design.

6.5 Modular Decomposition and Where Architectural Design Goes Next

6.5.1 Modular decomposition: the third stage

After system structuring and control modeling, the third stage of the architectural design process is modular decomposition: decomposing the subsystems into modules. Where system structuring divided the whole system into large subsystems, modular decomposition now takes each subsystem and breaks it into smaller, self-contained modules with well-defined interfaces. Each module becomes a unit that can be designed, implemented, and tested separately, which is why modular decomposition is the natural bridge from architecture into detailed design.

Large systems typically have composite architectural styles: each module may be developed using a different architectural style, because what suits one subsystem — a repository for the shared data, pipes and filters for the batch pipeline — may not suit its neighbor. The architecture of a big system is a mixture of styles rather than a single pure pattern.

The discussion of this stage was announced and then the session closed with the key points below. Architectural design is a very detailed topic, and detailed design comes in the subsequent sessions. The control models examined in this session — centralized and event-driven — decide how execution is directed; modular decomposition decides how the units that execute are shaped.

6.5.2 Key points and what comes next

  • Architectural design is an important aspect of the software development process: it interfaces between the requirements engineering and the design phases of software engineering.
  • As part of the process we derive a structural system model, develop a control model, and produce a modular decomposition model.
  • Large systems typically have composite architectural styles, because each module may be developed using a different architectural style.
  • Systems can be structured using patterns and styles such as MVC, the repository model, the client server model, the layered model, and the microservices pattern.
  • The control of system execution can be structured with either centralized control or event-driven control.
  • Certain application architectures recur; transaction processing systems and language processing systems are the ones we saw.

Exam note: questions on architectural design can be posted. The regular exam is on 23rd of September, and the makeup exam comes two weeks later. The exam is less than a month away, with two or three more classes before the mid-semester exam. Study advice: go through the textbook chapters on architectural design and the courseware, and follow the material delivered for this topic.

Exam Guidance Summary

  • Exam note: the regular exam is scheduled for 23rd of September; the makeup exam comes two weeks later. The exam is less than a month away, so start revising now rather than waiting for the last classes.
  • Study advice: study the textbook chapters on architectural design and the courseware, and follow the material delivered for this topic. The exam follows the delivered material, so the lecture content is your primary guide.
  • Exam note: two or three more classes remain before the mid-semester exam — use them to resolve any doubts on architectural design.
  • Exam note: questions on architectural design can be posted and answered, so ask early instead of carrying confusion into the exam.

Key Industry Applications

  • Real-world: transaction processing systems cover e-commerce applications; an ATM is a familiar example. Every cash withdrawal is a transaction that must complete as one unit.
  • Real-world: information systems typically use layered architectures, with the user interface, application logic, and database in separate layers.
  • Real-world: language processing systems, such as compilers, use a repository model, pipes and filters, or a hybrid of both. The repository holds the symbol table and the syntax tree.
  • Real-world: building monitoring systems and home monitoring systems use the centralized management model. A controller starts and stops sensor, actuator, computation, user interface, and fault handler processes, and raises alarms for intrusion or fire.
  • Real-world: personal computers use event listener subsystems that translate mouse clicks and keyboard events into specific commands.
  • Real-world: automotive safety systems use interrupt-driven control to inflate airbags on crash detection, because the response must happen in milliseconds.
  • Real-world: editors, rule-based production systems in AI, active objects, and spreadsheets are event-driven systems.
  • Real-world: Java object method calls follow the call-return model at the object level: one object asks another for a service by calling a method, and control returns when the call finishes.

SE Lecture 6 notes · Architectural Design: Control Models

Software Engineering· postgraduate· 2026-08-15

Sections Breakdown

16.1 Architectural Design: Role, Stages, and Models

The role of architectural design, its three stages (system structuring, control modeling, modular decomposition), the variety of architectural models, and the structural models and application architectures reviewed from the previous session.

26.2 Control Models: How the System Behaves at Runtime

Control models as the runtime behavior of the system, distinct from structural models, and the two generic control types: centralized and event-driven.

36.3 Centralized Control

The call-return model for sequential systems and the centralized management (manager) model with its polling event loop for concurrent soft real-time systems.

46.4 Event-Driven Control

What counts as an event, the broadcast model, and the interrupt-driven model with its strengths, drawbacks, and interrupt-mapping limits.

56.5 Modular Decomposition and Where Architectural Design Goes Next

Modular decomposition as the third stage of architectural design, the session's key points, and what comes next.

6Exam Guidance Summary

Exam logistics and study advice for the upcoming mid-semester exam.

7Key Industry Applications

Real-world systems that use each architectural and control model.

Postgraduate students in Software Engineering

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

Architectural Design: Role, Stages, and Models

Must-know: Architectural design is the bridge between requirements engineering and design, with three stages: system structuring, control modeling, and modular decomposition. Structural models (layered, repository, client server, pipes and filters) and application architectures (transaction processing, information systems, language processing) describe the system's shape, not its runtime control.

⚠️ Top pitfall: Confusing the structural model with the control model: repository, layered, client server, and pipes and filters carry no control information; a separate control model supplements them.

Self-check: Name the three stages of the architectural design process and the model type each one produces.

Connects to: control models, modular decomposition

Control Models: How the System Behaves at Runtime

Must-know: Structural patterns contain no control information; the architect selects a separate control model that supplements the structural model. The two generic control types are centralized control and event-driven control.

⚠️ Top pitfall: Assuming control information is part of the structural pattern — a repository or layered model says nothing about who starts, stops, or runs first.

Self-check: Why must a control model be chosen in addition to a structural model?

Connects to: centralized control, event-driven control

Centralized Control

Must-know: Call-return: control starts at the main function, moves down through subroutine calls, and returns to each caller — applicable only to sequential systems; simple to analyze but exception handling is hard. Manager model: a central controller starts/stops parallel processes based on state variables and continuously polls them (event loop model), suiting soft real-time systems.

⚠️ Top pitfall: Returning control to some other point in the program instead of the calling module (poor programming style), and assuming the call-return model handles exceptions easily.

Self-check: How does the central controller in the manager model know that something has happened?

Connects to: control models, event-driven control

Event-Driven Control

Must-know: An event is not just a binary signal; its defining property is that its timing is outside the control of the handling process. Broadcast model: subsystems register interest with the event handler; advantages are simple evolution, activation without knowing names or locations, and transparent distribution; drawbacks are unknown delivery, conflicts from multiple registrations, and no fit for real-time. Interrupt-driven model: each interrupt type has a stored handler address and hardware transfers control immediately; very fast but complex to program, hard to validate, and limited by hardware interrupt count.

⚠️ Top pitfall: Treating broadcast delivery as guaranteed (the sender never knows who, if anyone, handled its event), and assuming fast interrupt response is free — every new exceptional event adds a handler and timing complexity.

Self-check: Why is interrupt-driven control required to inflate an airbag, and what can interrupt mapping not achieve?

Connects to: control models, centralized control

Modular Decomposition and Where Architectural Design Goes Next

Must-know: Modular decomposition decomposes subsystems into modules after system structuring and control modeling. Large systems have composite architectural styles; each module may use a different style. Control of execution is either centralized or event-driven.

⚠️ Top pitfall: Expecting one architectural style to fit an entire large system — composite styles are the norm.

Self-check: What is the third stage of architectural design, and where does it lead next?

Connects to: architectural design, control models

Exam Guidance Summary

Must-know: The regular exam is on 23rd of September, the makeup exam comes two weeks later, and the exam is less than a month away.

⚠️ Top pitfall: Leaving revision until the last classes — two or three classes remain before the exam.

Self-check: When is the regular exam, and when is the makeup exam?

Connects to: modular decomposition

Key Industry Applications

Must-know: Compilers use repository, pipes and filters, or a hybrid; building and home monitoring use the centralized management model; personal computers use event listeners; automotive safety systems use interrupt-driven control; Java object method calls follow the call-return model.

⚠️ Top pitfall: Remembering each model in the abstract without its anchor application — tie every model to the industry system that uses it.

Self-check: Which control model powers automotive airbag inflation, and which model organizes a compiler's phases?

Connects to: architectural design, centralized control, event-driven control

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.