Chapter 13: Usability – Creating User-Centered Architecture

0:00 / 0:00
Report an issue

Welcome to Last Minute Lecture!

This free chapter overview is designed to help students review and understand key concepts.

These summaries supplement not replaced the original textbook and may not be redistributed or resold.

For complete coverage, always consult the official text.

Welcome to the Deep Dive.

If you've ever used a piece of software and just, well, immediately felt frustrated, you know exactly what we're talking about today.

We are taking a deep dive into the foundational architectural concept of usability.

And we're moving beyond just, you know, the visual design, because like the architect Frank Chimera said, people ignore design that ignores people.

We're really going to explore the serious architectural commitment required to build systems that are actually genuinely easy to use.

That really is the critical distinction, isn't it?

Usability, it's often just pushed aside as an interface problem, you know, something the front team handles near the end.

But our sources really confirm it's fundamentally an architectural quality attribute.

It has to be baked into the design like from day one.

So our mission today is to give you that shortcut really to the specific architectural foundations, the tactics,

the patterns,

everything you need to build systems that actually satisfy the end user.

Okay, so before we jump into the structure and tactics, let's unpack what usability really covers.

It sounds like it's broader than just making things look nice.

Oh, it definitely is.

We can break usability requirements down to say, five core measurable areas.

First up, there's learning system features.

So if you're a first time user, what support is actually there?

Does the system guide you provide useful help?

Right.

And second is using a system efficiently.

This sounds like power user stuff, maybe like being able to suspend a task, jump somewhere else and then come back without losing your place.

Exactly.

Hassle free continuation.

Third, and this one's maybe the most immediately visible, is minimizing the impact of user errors.

This is your safety net, right?

Right.

The reliable cancel button or the ability to undo something, making sure a simple mistake doesn't, you know, become a disaster.

Okay.

Fourth is adapting the system to user needs.

We see this quite a bit now, don't we?

Systems that sort of intelligently adapt, maybe auto -filling fields based on what you've typed before.

Precisely.

That really improves efficiency.

And finally, number five is increasing confidence and satisfaction.

The system needs to communicate clearly that it's working, especially during waits.

The classic example is the progress bar, showing you accurately how much is left.

Okay.

Let's take into something really interesting.

You mentioned the strong link the sources draw between usability and modifiability.

Why is that connection so critical?

Is usability basically a way to force better architectural flexibility?

That's a sharp way to put it.

And architecturally, yeah, you could say it kind of is.

The basic truth about UI design is, well, it's iterative.

Inherently so.

You just can't nail the user experience perfectly on the first try.

You have to design, test it out, find where it falls short, and then correct those things.

Now, if your underlying architecture is rigid,

if it wasn't designed with separation of concerns,

then every single little UI improvement, even just changing a menu item, it becomes painful, expensive, time -consuming.

So, to really sustain usability over the product's life, the architecture must be built from the get -go to make modifications easy.

You achieve usability by prioritizing modifiability.

They're completely intertwined.

Okay.

That makes sense.

So, to help architects talk about these requirements formally, our sources introduce this idea of initiative and human -computer interaction.

It's about who's driving the interaction.

Right.

We define three types.

First is user initiative.

That's straightforward.

The human starts the action, like clicking a download button.

Then there's system initiative.

This is when the software acts proactively.

Maybe flashing a low battery warning or automatically correcting a spelling mistake.

And then the third one, which sounds interesting, mixed initiative.

So, both the user and the system are involved in one operation.

Exactly.

The classic example they give is canceling a command.

The user hits cancel.

That's user initiative.

But while the system is actually processing that cancellation,

freeing resources, closing things down, it usually shows a progress indicator or maybe a spinning wheel.

That display part, that system initiative.

Understanding this distinction is really vital because it tells you which architectural tactics you'll need.

Got it.

Now, the source material also formalizes these usability requirements using something called the general scenario structure.

It details specific elements you have to define.

Sounds pretty formal.

But doesn't making requirements that formal carry a risk,

like over -engineering things.

Especially if you're on a small team or have tight deadlines.

Oh, and absolutely can carry that risk.

Yeah.

If you get too hung up on the formalism itself.

Yeah.

But the real value here isn't just checking boxes on a form.

It's about forcing the architect to define the measure.

How do you quantify success?

That's the bit that often gets skipped.

So, let's quickly run through the key elements.

You start with the source, which is usually the end user.

And the stimulus, what they want to achieve.

Efficiency, learning, minimizing errors, maybe adapting the system.

Okay.

Source and stimulus.

And the artifacts are the system parts being used.

GUI, command line, voice interface, whatever.

And these actions happen in the environment, either at runtime or maybe during configuration.

Right.

Then the response is, what do you want the system to do?

Provide features, anticipate needs, give feedback.

And finally, the crucial part,

the response measures.

These are the actual metrics, task time, number of errors, how long it takes someone to learn something, user satisfaction, subjective, but important.

They even mention measuring the actual time or data lost if an error occurs.

Wow.

That clarity lets you write really specific, measurable scenarios.

Like the example, the user downloads a new application and is using it productively after two minutes of experimentation.

That one sentence really ties together the user, the goal, the system's response and that specific measure, two minutes.

Very clear.

Exactly.

So, with that foundation of scenarios and initiative, we can now look at the architectural tactics.

These are the specific design strategies you use to actually achieve those measurable usability goals.

And we can organize them based on whether they support user initiative or system initiative.

Makes sense.

Let's start with supporting user initiative.

Giving the user control, especially when maybe things go wrong or take too long.

We mentioned cancel earlier.

It sounds simple, just stopping something.

But architecturally, what makes it such a headache?

It's got to be more than just hitting stops, right?

Oh, it's significantly more complex under the hood.

The core difficulty, really, is that to even allow cancellation, the system needs some component acting as a constant listener.

And crucially, that listener must never be blocked by the long running activity itself.

If the listener gets blocked, well, the user can't send the cancel signal.

Beyond that, the cancellation routine itself has to guarantee two critical things.

One, all the resources that were allocated get properly freed up.

And two, maybe even more importantly, the system isn't left in some weird, inconsistent, partially completed state.

Dealing with, say, nested transactions or avoiding resource deadlocks if it's not handled comically, that's where the real architectural challenge bites.

Then you have undo, another user safety net.

This tactic requires the system to maintain enough state information so it can revert back to an earlier stable point.

This is often done either by taking periodic snapshots of the state, like checkpoints, or by keeping a log, a record of operations that can be reversed.

Okay, and here's where I think the architectural complexity really shows.

You mentioned that example.

If I change all the A's to B's in a huge document, I can't just reverse that changing all B's back to A's because some B's might have already been there.

So what does that kind of complexity force the architect to design?

It really forces the system towards something like a transaction logging approach, or maybe using the command pattern.

Instead of just storing the before state and the after state of the data, which might not be enough, the architecture has to log the intent of the change.

It records something like, user executed the global search and replace command at time t with these parameters.

Reversing that means processing the logical negative of that command,

which can be computationally expensive.

Yeah, and it forces your state management into a potentially deep, heavy structure.

Yeah.

It's a definite trade -off because giving the user the ability to step back through multiple previous states, multi -level undo uses up way more memory than just a simple single undo.

Got it.

Next up were the efficiency boosters, pause resume and aggregate.

Right.

Pause resume is pretty necessary for those really long resource heavy operations.

Think large data sinks or big downloads.

The ability to pause lets the system temporarily free up those specific resources, maybe network bandwidth, maybe memory buffers, so they can be reallocated to other things the user's actively doing in the foreground.

And aggregate is all about efficiency through grouping things.

It lets users bundle up lower level objects, for instance, selecting, say, 15 different shapes on a presentation slide.

So you can then apply one single operation like changing the font size or the color to the group at once.

It minimizes that repetitive clicking and drastically cuts down the chances of making a mistake.

Okay.

So those handle user control and efficiency.

Now we shift gears to supporting system initiative.

If the last set was about putting the user in charge, this next set seems to be about how the system can intelligently, maybe proactively help the user by anticipating their needs.

And it does this using internal models.

Exactly right.

That reliance on internal prediction takes the form of three different kinds of explicit models.

First, the system needs to maintain a task model.

This model basically tracks where the user likely is within a predictable sequence of steps, their context, so the system can offer relevant assistance.

Right.

The classic examples here are things like the predictive type head suggestions you see in search engines, or maybe the really contextual spell correction in an email client.

The system sort of guesses the task you're probably doing.

Precisely.

Second, the system needs to maintain a user model.

This is more personalized.

It explicitly represents that specific user's knowledge, their behavior patterns, maybe even their expected response time.

This is intensely data -driven.

Think about language learning apps, for example.

They often monitor your specific mistakes, your personal weak spots, and then generate exercises tailored to fix those specific issues.

User interface customization, letting you tweak the layout or shortcuts, also relies heavily on storing a user model.

Okay, task model, user model.

And the third one sounds fascinating because it's about the system knowing itself.

Maintain a system model.

Yeah, this one's key for feedback.

The system has to have an explicit model of its own internal workings and its expected behavior.

If it didn't have this self -awareness, it wouldn't know how long a process should take or when it's supposed to finish.

This model is essentially the architecture that drives things like the progress bar.

It lets the system clearly communicate to the user whether things are stalled, just busy, or actually progressing as expected.

Okay, so we've covered the goals with scenarios, the initiative types, and the specific tactics like cancel, undo, and these models.

But you mentioned earlier that none of this is really possible if the architecture isn't flexible enough for that constant iteration.

This seems to be where architectural patterns come in, promoting usability mainly by ensuring separation of concerns, right?

Which makes the UI changes easier.

Exactly.

Let's start with probably the most well -known one.

Model -view -controller MVC.

This pattern, and it's many variants like MVP, MVVM, MVA, it fundamentally separates the model.

That's the business logic, the data, from the view,

the actual UI the user sees, and the controller, which interprets user input and tells the model or view what to do.

And the key benefit for usability is that clear separation, I guess.

You can totally redesign the view, change colors, move buttons around, experiment with layouts ideally without needing to rewrite or even retest the core business logic sitting in the model.

That sounds essential for rapid UI iteration.

It is essential.

The trade -offs, though, are definitely real.

For a very, very simple UI, using the full pattern can feel like unnecessary upfront complexity.

You're building more structure than you might need.

And conversely, for really complex interfaces, the architecture can sometimes become a bit burdensome, maybe with information feeling scattered across too many small components.

And yes, there's always a small amount of latency added just by coordinating between these separate parts, though usually it's negligible for the user.

Okay, and if that MVC architecture is running all in one process, the model usually tells the view about changes using the observer pattern, correct?

That's the common way, yes.

The observer pattern is conceptually pretty simple.

You have subject that's the entity being watched, usually the model in MVC, and it automatically notifies all registered observers, typically the views, whenever its state changes.

It's great for ensuring that separation between the underlying functionality and its presentation, and you can easily change which views are listening at runtime.

What are the catches?

Because I know one potential headache is something you called impedance mismatch.

What's that about?

Ah, the impedance mismatch.

Yeah, that's a key performance trade -off.

But first, the simpler risks are things like memory leaks.

If an observer forgets to unsubscribe or deregister itself when it's no longer needed, its memory might never be freed.

But the impedance mismatch happens when, say, the model is generating lots and lots of very small, fine -grained updates really frequently.

But the view?

Maybe it only needs to refresh itself visually once a second, a much coarser update.

In that scenario, the view ends up wasting processing cycles, constantly getting notified about tiny changes it doesn't actually need to react to immediately.

It leads to performance hits, wasted resources.

Okay, finally, let's turn to the Memento pattern.

If MVC helps with the iteration side of usability, Memento is often the specific pattern architects reach for to implement that complex undo tactic we talked about earlier.

Right, the undo implementer.

Let's clarify the roles here.

The source mentions an originator, a caretaker, and Memento itself.

How do they work together?

Think of it like saving your game.

The originator is the thing whose state is changing the actual document, the data structure, the game world state.

The caretaker is like the game's saveload system.

It asks the originator for a snapshot of its current state, and it holds onto that snapshot.

That snapshot is the Memento.

Crucially, the Memento is usually opaque to the caretaker.

The caretaker doesn't know or care how the state is stored inside the Memento, just that it holds the state.

The big benefit here is abstraction.

The complex job of actually and restoring state is delegated entirely to the originator.

The rest of the system, including the caretaker, doesn't need to know the messy details.

It just passes the Memento back when an undo is requested.

But the memory usage, that sounds like the huge downside, right?

It is the single biggest trade -off, absolutely.

The Memento object itself can potentially consume arbitrarily large amounts of memory.

Imagine you copy and paste a huge high -resolution image into a document,

or maybe a massive chunk of text.

Then you perform some complex operation.

If the system is saving a full Memento snapshot for every single significant change you make during that session,

well, your application's memory usage can spike dramatically, and that can seriously impact the overall performance of the system.

Hashtag Outrag Outro.

Okay, so let's try and quickly wrap up the key takeaways here.

Usability isn't just about looks.

It's a measurable architecture -driven quality.

Achieving it requires specific tactics, things like cancel, undo, pause resume, to make sure the user is efficient and safe.

And it also relies on these predictive models, the task, user, and system models for the system to proactively assist the user.

And critically, underpinning all of this are architectural patterns like MVC, Observer, and Memento, their main job.

Promoting that separation of concerns, which allows for the painful but absolutely necessary continuous iteration of the user interface.

Exactly.

And if we connect this all back to that maintain system model tactic we just discussed, it raises a really interesting question for you to think about as you finish this deep dive.

We said progress bars rely on the system having a model of its own expected completion time.

Given that, why do we so often see progress bars behave erratically, you know, jumping from like 10 % instantly to 90 % and then just stalling at 90 % for ages?

What does that erratic behavior tell you about a potential failure in that underlying system model?

And maybe more importantly, why is accuracy in that feedback, even if the total wait time is long?

Why is that accuracy so fundamentally crucial for maintaining user confidence?

That's a great point.

That kind of flawed feedback really does cost users confidence, doesn't it?

Well, thank you for joining us for this deep dive into the architecture of truly usable systems.

We hope this knowledge helps you build software that people don't just

ⓘ This audio and summary are simplified educational interpretations and are not a substitute for the original text.

Chapter SummaryWhat this audio overview covers
Usability represents a core quality attribute that determines how effectively users can complete their objectives while receiving adequate system support, directly influencing their overall assessment of the software and their satisfaction with the experience. Achieving strong usability demands architectural attention to several dimensions: enabling users to learn and master new capabilities, optimizing task execution speed, allowing personalization based on individual preferences, and reducing the severity of mistakes when they occur. Since user interface development necessarily involves repeated refinement and experimentation, usability achievement becomes tightly coupled with architectural modifiability, requiring design approaches that permit frequent changes without substantial reworking. The framework uses the Usability General Scenario to formalize these concerns, establishing a structure that identifies the end user as the originating stimulus, runtime interactions as triggers, typical output mechanisms like graphical interfaces as relevant artifacts, and concrete success measures such as completion time, error frequency, and user satisfaction ratings. Tactics for realizing usability divide into two strategic approaches: User-Driven Control tactics grant users direct command over system behavior through capabilities such as operation cancellation, reverting to previous states, temporarily stopping and resuming processes, and combining similar operations; System-Directed Support tactics involve the system taking a proactive role by maintaining representations of what tasks users are performing, who is using the system, or what the system is currently doing, enabling intelligent prediction of user needs or timely delivery of status information. Several architectural patterns provide essential structural support for achieving these goals, particularly the Model-View-Controller pattern and related variants that organize code into separable layers, the Observer pattern which enables reactive updates when underlying data changes, and the Memento pattern which provides a mechanism for preserving and restoring previous application states, thereby supporting the critical undo capability that reduces user anxiety and encourages exploration.

Using this chapter to study? Last Minute Lecture is free and student-run. If it helped, consider supporting the project.

Support LML ♥