WEEK 6

Software Architecture, Just Enough

Week 6 · Decide what is expensive to change

WEEK 6

Team A: seven services

Team A: seven services

WEEK 6

Team B: one deployable

Team B: one deployable

WEEK 6

Two teams, one specification

Ask the room

Both deliver every use case. Both pass every functional test. Which one should the client get?

WEEK 6

The use cases cannot tell them apart

  • Who runs this after you graduate? One instructor, no operations staff.
  • How many users? About 75 a term.
  • What is the worst thing that can happen? One student sees another's evaluations.
  • What changes most often? Features, added by next year's students.
Key point

Team B is Project Pulse. Team A is what an agent proposes when nobody tells it those four answers.

WEEK 6

Functionality tells you what components you need

Key point

Quality attributes tell you how to arrange them.

WEEK 6

What architecture is

The significant design decisions that shape a system, where significant is measured by cost of change.

Grady Booch

WEEK 6

The reversibility test

Decide now Decide later, against real code
One deployable or several Class and method names
Where the data lives Endpoint shapes
How users sign in Table columns
Which external systems Validation library
How code is divided into modules Screen layout
Where the trust boundary sits Error wording
WEEK 6

Breadth-complete, depth-shallow

Breadth-complete

Every use case area, every component, every external system named. No holes in the map.

Depth-shallow

Each part described to its responsibility and no further. Nothing designed before anyone has built against it.

Pitfall

The map with holes: two people build the same thing. The map that is too deep: you committed to guesses.

WEEK 6

Twin Peaks

The Twin Peaks model

WEEK 6

Seven attributes, seven pushes

Attribute Project Pulse says So the architecture has
Security a student sees only their own team's work a trust boundary; every query scoped
Maintainability a new feature edits no sibling module packages by domain
Availability up 99% of a term one instance, and that is enough
Performance 500 ms at the 95th percentile no needless network hops
Scalability about 75 users, 100 at once one deployable; uploads in object storage
Robustness a crash loses at most 10 seconds a save to the server at least every 10 seconds
Operability one instructor, no operations team one container, a staging slot
WEEK 6

Quality attributes decide it

  • Delivered by shape, not by a component. No class makes Project Pulse secure.
  • They conflict. One deployable buys simple operations and costs independent scaling.

An architecture that maximizes every quality attribute is like a car that is the fastest, the cheapest, and the safest. Ask to see it.

WEEK 6

Architecturally significant requirements

The few where a wrong guess costs a redesign, not a bug fix.

Rank each on two axes:

Importance to the client

A privacy breach: high. 1.5 seconds instead of 1: low.

Difficulty to achieve

75 users: low. 75,000 concurrent: high.

WEEK 6

Project Pulse's top four

Rank Requirement Handles Drives
1 Student records stay confidential (FERPA) SEC-authorization, SEC-ferpa, CO-ferpa KD-ram-module, KD-self-issued-jwt
2 One instructor, no operations team AVL-uptime, CO-no-ops-team KD-modular-monolith, KD-relational-graph
3 Next year's students can extend it MNT-feature-locality, MNT-service-layer KD-ram-module, KD-no-codegen, KD-vertical-slices
4 No lost work under concurrent editing ROB-no-overwrite KD-section-locking
Key point

Reuse the identifiers you already have. Include at least one SEC-*.

WEEK 6

Your architecture-of-record: arc42

You write

1.2 Quality goals · 3 Context · 4 Solution strategy · 5 Building blocks · 6 Runtime · 7 Deployment · 8 Crosscutting · 9 Decisions · 10.2 Quality scenarios · 11 Technical risks

You link

1.1 Requirements · 1.3 Stakeholders · 2 Constraints · 10.1 Quality attributes · 12 Glossary

Key point

A fact written in two places is soon wrong in one.

WEEK 6

One architecture, four views

Template section Answers Drawn at
3. Context and Scope What is it, who uses it, what does it talk to? Checkpoint 1
5. Building Block View What is it made of, and who owns what? Checkpoint 1
6. Runtime View How do the parts carry out one use case? Checkpoint 2
7. Deployment View Where does it run, and how does a change get there? Checkpoint 3

arc42: what to write · C4: how to draw it

WEEK 6

Draw what you can know

Now, from the specification

Context. Building blocks. These are the decisions you are making this week.

Later, from real code

Runtime, after the proving slice. Deployment, after the pipeline.

Key point

A sequence diagram of code nobody has written describes a guess.

WEEK 6

Drawing it

Ask the room

Who has seen an architecture diagram they could not read without its author in the room?

WEEK 6

C4: abstractions before notation

  • Software system: the whole thing your team builds
  • Container: anything that runs or stores data (not a Docker container)
  • Component: related functionality behind one responsibility
  • Code: the classes

One diagram per level: Context · Containers · Components · Code

WEEK 6

Level 1: context (template section 3)

Project Pulse system context diagram

WEEK 6

Level 2: containers (template section 5.1)

Project Pulse container diagram

Key point

What runs, what stores data, which technology, and the protocol on every arrow.

WEEK 6

Level 3: components

Project Pulse shared-foundation component diagram

WEEK 6

Level 3 and 4

Components: a table, template section 5.2

One row per use case area. Responsibility, dependencies, status.

Code: never by hand

Your IDE and your agent draw it from the code when you need it.

WEEK 6

Diagrams that stand alone

  • A title that says what and which kind
  • Every box: name, type, technology, one-line responsibility
  • Every arrow labelled with what it does
  • Strip the colors: does it still read?
  • A key for anything beyond boxes and arrows
  • Icons supplement text, never replace it

A diagram made of cloud-provider icons tells you exactly what was bought and nothing about why.

WEEK 6

The two views that wait

Runtime

Sign-in, a two-hour JWT, then an ownership or membership check on every request

Deployment

One Azure Web App, one container, a staging slot swapped into production

Key point

Real endpoints, real token lifetimes, real slots: facts that exist only once the code and the pipeline do.

WEEK 6

Monday, in one line

Key point

Architecture is the expensive decisions, chosen by quality attributes, drawn so it reads without you.

WEEK 6

Where components come from

Key point

Your use case areas.

WEEK 6

Project Pulse, area by area

Use case area Package
WAR, EVA, RUB activity, evaluation, rubric
SEC, TEA, STU, INS section, team, student, instructor
The RAM areas five packages under ram/
Cross-cutting security, system, course
WEEK 6

By layer, or by domain?

By domain: Project Pulse

activity/
├── Activity.java
├── ActivityCategory.java
├── ActivityController.java
├── ActivityRepository.java
├── ActivitySecurityService.java
├── ActivityService.java
├── ActivitySpecs.java
├── ActivityStatus.java
├── converter/
└── dto/

By layer: the same files, rearranged

controller/ActivityController.java
service/ActivityService.java
service/ActivitySecurityService.java
repository/ActivityRepository.java
repository/ActivitySpecs.java
model/Activity.java
model/ActivityCategory.java
model/ActivityStatus.java
dto/ActivityDto.java
converter/ActivityDtoToActivityConverter.java
converter/ActivityToActivityDtoConverter.java
Ask the room

The most common change on any project is "change how this one feature works." How many folders do you open in each?

WEEK 6

Nobody demos maintainability

Key point

60 to 90% of what software costs is spent changing it after it ships.

WEEK 6

Domain first, layers inside

Layers as the top-level modules, marked wrong, beside full-stack modules each layered inside, marked right

WEEK 6

One slice of the cake

Project Pulse's backend as a layer cake: web, business logic, and data access layers run across every package on one shared database, and the activity package is a slice pulled out, holding ActivityController with its converters and DTOs, ActivityService and ActivitySecurityService, ActivityRepository and the Activity entity

WEEK 6

The compiler can hold the line

package team.projectpulse.activity;

interface ActivityRepository        // no "public"
        extends JpaRepository<Activity, Integer> { }
Key point

Package by domain, and the compiler keeps other features out of your repository.

WEEK 6

The deletion test

Ask the room

Delete activity/ from Project Pulse. What breaks?

WEEK 6

Features lean on the foundation

Project Pulse performance-tracking component diagram

WEEK 6

Divide the team the same way

Key point

A defect where two layers meet belongs to nobody when the layers belong to different people.

WEEK 6

One deployable or several?

Ask the room

Your template requires exactly one decision by Friday. This is it.

WEEK 6

What microservices buy

  • Scale one part without the rest
  • Deploy one part without the rest
  • One team per service, in any language
  • One failure does not take down the rest
WEEK 6

Where that pays off

Tmall, Singles' Day, November 11, 2019

Key point

544,000 orders per second at peak.

WEEK 6

What they cost

  • Every call is a network call: slow, failing, or half done
  • A transaction across three services is no longer a transaction
  • A bug report needs tracing across services
  • Every service needs its own pipeline, monitoring, and on-call
Pitfall

None of it delivers a use case.

WEEK 6

Monolith first

Fowler

Almost every successful microservice system started as a monolith that was split. Almost every one built as microservices from day one got into serious trouble.

Prime Video, 2023

Moved a monitoring service from distributed serverless components into one process. Infrastructure cost fell by over 90%.

WEEK 6

The one to aim for

Three deployment shapes side by side. Monolith: one deployable with no boundaries inside and one database; to move a boundary, untangle the code first. Modular monolith, marked as the one to aim for and as Project Pulse: one deployable divided into domain packages (activity, team, evaluation) that call each other in-process, one database; to move a boundary, move a package. Microservices: separate deployables with a database each, calling each other over the network; to move a boundary, migrate data between databases, and each service needs its own pipeline, monitoring, and on-call

WEEK 6

The question for your project

Key point

Which requirement would force several deployables?

WEEK 6

Patterns you will meet

  • You have met two already: layered and microservices
  • A pattern: a reusable solution to a problem that keeps occurring
  • Two you will use: layered, pipes and filters
  • Six to recognize, so you can tell when an agent reaches for one without a reason

Microservices: the shape Project Pulse will need on the day it becomes every capstone course's go-to tool. We expect that any semester now.

WEEK 6

Layered

Layered

WEEK 6

Three layers, three jobs

Layer Its job Never here
Controller Translate HTTP to the application Business logic
Service Carry out a use case: the business logic, the transaction HTTP
Repository Load and store data Business logic
WEEK 6

Where layering goes wrong

  • Fat controller: business logic every other way in skips
  • Skipped layer: controller calls the repository directly
  • Database row on the wire: return a DTO instead
  • HTTP in the service: callable only from a controller
  • Logic hidden in queries: access rules where no reviewer looks
WEEK 6

Pipes and filters

Pipes and filters

WEEK 6

Suppose Project Pulse takes off

Key point

500 universities. 150,000 students. Every reminder at 9:00 a.m. Monday.

Pitfall

None of the next six slides exists in Project Pulse's code today.

WEEK 6

Broker

Broker

You need it when: Many services, located and replaced dynamically.

In practice: Kubernetes Services, Consul, Eureka.

WEEK 6

Publish-subscribe

Publish-subscribe

You need it when: Work that can wait, spikes to absorb, many independent consumers of one event.

In practice: Kafka, Azure Service Bus topics, Spring events.

WEEK 6

Message queue

Message queue

You need it when: A job longer than a user will wait, or bursts the database cannot absorb.

In practice: RabbitMQ, Amazon SQS, Azure Service Bus queues.

WEEK 6

Source-replica

Source-replica

You need it when: Reads far above writes, or an availability target one server cannot meet.

In practice: MySQL replication, Azure MySQL read replicas.

WEEK 6

Main-worker

Main-worker

You need it when: Batch computation that can be parallelized.

In practice: Apache Spark, Jenkins agents.

WEEK 6

API gateway

API gateway

You need it when: You have already chosen microservices.

In practice: Spring Cloud Gateway, Kong, Azure API Management.

WEEK 6

Read that line as a requirement

Key point

If your specification contains none of those needs, your system uses none of those patterns. That is a correct architecture, not an unambitious one.

WEEK 6

The trust boundary

Between what you control and what you do not.

  • How does a user prove who they are?
  • What may each role see, beyond its role?
  • Where does sensitive data live?
WEEK 6

September 6, 2026

  • Security rules covered /api/v1/**
  • Actuator lives at /actuator/**
  • It fell through to .anyRequest().permitAll()
  • One anonymous URL returned the production database and mail passwords
Pitfall

The secrets were in a vault and never in git. Every checklist item passed.

WEEK 6

Nobody wrote a rule that made it public

It was the absence of a rule.

Key point

Deny by default. A new API endpoint fails closed until someone writes its rule.

WEEK 6

Every session is a new teammate

The agent

Session 1: {"error": "Not found"}. Session 2: a bare 500. Session 3: LocalDateTime.now().

WEEK 6

Project Pulse's rules, in one table

Concept The rule
API shape /api/v1/<resource>; search is POST /<resource>/search
Envelope Every response is a Result: flag, code, message, data
Errors Services throw; one handler answers for all of them
Caller Who is calling comes from UserUtils, nowhere else
Time Calendar time from the injected Clock
Schema Every change is a new Flyway migration
Code No Lombok, no MapStruct; constructor injection
Client Every browser call goes through one shared HTTP client
WEEK 6

One error shape, everywhere

{ "flag": true,  "code": 200, "message": "Find activity successfully", "data": { "activityId": 7 } }
{ "flag": false, "code": 404, "message": "Could not find activity with Id 999 :(", "data": null }
{ "flag": false, "code": 500, "message": "A server internal error occurs.", "data": "<the exception's own message>" }
Ask the room

Read the last one. What could be in data?

WEEK 6

Logging: the rule nobody wrote

Key point

What is logged, at what level, and what must never be?

Pitfall

Project Pulse: Spring Boot defaults, five log statements, no answer.

WEEK 6

Three places, one owner

  • 8.2 owns the reasoning, written before the agent builds its second component
  • Point at the file that does it right: the agent copies code better than it reads prose
  • The charter carries the one-line rule and cites 8.2: the charter is always in context
  • Let a tool apply or check it where one can: a formatter, a lint rule, an ArchUnit test
Key point

A convention nothing checks is one you are trusting the agent to remember.

WEEK 6

Writing a decision down

  • Driving requirements: by identifier
  • Context: why this was a question at all
  • Decision: one or two sentences
  • Rejected: what you did not choose, and why
  • Trade-off: what it costs
Key point

Without a rejected alternative it is a description. Without a trade-off you have not understood it.

WEEK 6

Rewrite this

KD-database: We use PostgreSQL.

Ask the room

What is missing? Rewrite it in two minutes with your neighbour.

WEEK 6

Follow one requirement down

flowchart LR
    s1["SEC-authorization"] --> s2["ASR-student-record-<br/>confidentiality"] --> s3["KD-self-issued-jwt +<br/>two-layer auth"] --> s4["route guards,<br/>scoped queries"] --> s5["QS-cross-team-<br/>denial"] --> s6["tests pass"]
    m1["MNT-feature-locality"] --> m2["ASR-maintainability-<br/>learnability"] --> m3["KD-vertical-<br/>slices"] --> m4["package<br/>per domain"] --> m5["QS-add-bounded-<br/>context"] -.-> m6["no test:<br/>12 violations"]
    style m6 stroke-dasharray: 5 5
Key point

A chain with no test at the end is a decision you are trusting people to remember.

WEEK 6

Ask the agent for an architecture

The agent

Microservices, a message queue, Kubernetes, a cache, an API gateway. Fluent, correct, and confident.

Ask the room

For each part: which requirement forces it?

WEEK 6

The right-sized spoon

Your app with 0 users

WEEK 6

Friday: Checkpoint 1

  • Your TA reviews your specification with you, about eight minutes a team
  • Your team drafts the architecture-of-record the rest of the hour
  • Merged to main by 11:59 pm
  • Your TA checks it over the weekend, reply by Sunday 8 pm
WEEK 6

Draft in this order

  • The ranked requirements table
  • Context diagram
  • Container diagram
  • Component table, and its two checks
  • Security, 8.1: name the boundary, answer the three questions
  • Crosscutting, 8.2: a rule and a reason for every concept
  • KD-deployment-shape, last
Key point

Your agent draws the diagrams. The ranking and the decision are yours.

WEEK 6

Leave with this

Key point

Decide what is expensive to change. Let quality attributes choose. Cite the requirement, or cut the part.

Software Architecture

→ space PgDn
Next step or slide
← PgUp
Back
↓ S
Skip to the next slide
O
Overview of all slides
N
Speaker notes
B
Black the screen
Ctrl+P
Print / PDF handout, one slide per page