Architectural Design¶
Based on Chp 6 of Sommerville “Software Engineering” (9th edition)
Architecture¶
software architecture is about the overall design of a system
architectural decisions usually must be made early on in a project, and often cannot be easily changed afterwards
this is often modeled using a “box and lines” diagrams that names the main components of a system and give some idea of how they relate
- the exact meaning of the lines and boxes is often (intentionally) not made clear
- yet this can be useful because it is a way to talk about the system among
stakeholders, forces some up-front thinking to be done, and may even be able
to be re-used in later similar systems
- e.g. some popular high-level architectures, like client-server, model-view-control, layers, peer-to-peer, etc.
Questions to Consider when Architecting a System¶
- Can a standard architectural pattern be used for the system (like client-server)?
- How will the system be distributed among multiple computers?
- think about how Google’s web search handles something like this
- from the point of view of the user, it seems like Google has one giant computer that handles all searches
- but that’s not the case: they have thousands of computers working together to do searches
- think about how all these computers get updates to the search index
- or when a search request from a user comes in, how is it determined which computer will get the request?
- what happens if one or more of the computer are down? or the computers run at different speeds?
- How will the system be de-composed into smaller parts?
- How will these parts be controlled?
- How will the architecture help with the non-functional requirements?
- How can the architecture be documented?
- How can the architecture be evaluated?
Architecture and Non-functional Requirements¶
architectural decisions can have an impact on non-functional requirements
- e.g. suppose security is one of the major non-functional requirements for your system
- this mean, for instance, that you might use encryption throughout the system, and so need to take into account things like safely storing keys and passwords
- things like performance or usability might have a lower priority than safety because of the architecture
Architecture Validation¶
validating software architecture means determining if it does the right thing, and also that it does not do anything that it should do
- contrast validation with verification: verification is about if the
software is built correctly, if what it does is error-free
- it’s quite possible that software could be verified, but also invalid!
since software architecture is often done before there is any working code, it can be a especially challenging to validate
one good approach is to develop a concrete set of scenarios, i.e. common uses cases, and review the architecture with these scenarios in mind
- all stakeholders can walk through the scenarios, checking that there needs are met
another approach that can sometimes be helpful is to run a simulation
- e.g. if performance is important in you system, then running a simulation
that checks performance might be possible and helpful
- you wouldn’t simulate the whole system, just the performance-critical parts of it
Common Architectures¶
for many systems, it is wise to use a well-known architecture instead of making up a brand new one
- avoid re-inventing the wheel — especially for very important aspects of a system!
- common architectural patterns can be thought of as encapsulating best practices
common architectures have well-known pros and cons that you don’t have to re-discover
The Model-View-Controller (MVC) Architecture¶
MVC architecture is often used as an overall architecture of interactive graphics systems
- like web browsers, or word processors, or windows-like interfaces
the model contains the state
- when state changes, it notifies the view component
the view renders the model
- the view draws the visual representation of the mode on the screen
- it draws based on the model state, and changes when the model changes
the controller manages user interaction, e.g. it handles mouse movements and key-presses
- e.g. moving a slider on-screen causes the state of that slider to change
of course, there are many details left unsaid here!
but the point is that it gives a high-level description, grouping concerns and constraining how they interact
by deciding upon an architecture like this for a system, you have some initial design work already done, can get ideas from other projects that have use the same architecture
Layered Architecture¶
the idea of a layered architecture is to structure your system into a series of carefully constructed layers
typically the first layer is close to the machine, and is the lowest-level
the next layer is built on top of the preceding layer
layers keep being added, with, usually, the user interface being the top-level layer
in the purest form, a layer only communicates with the layer directly above or below it
here’s an example of a library system:
Repository Architecture¶
the repository architecture is a way to get multiple components to interact
instead of having the components directly interact with each other, the components interact though a shared repository
the repository is could be a database, or something more complex consisting of multiple databases and interior components
e.g. consider the example of a modern integrated development environment with many complex components
Client-server Architecture¶
client-server architecture structures modules into servers that provide services, and clients that use services
one server can “talk” to many clients
- servers don’t talk to servers, clients don’t talk to clients
- in contrast, peer-to-peer architecture lets everyone talk to everyone
servers typically
- include a database
- don’t have a significant user-interface (since end-users don’t deal with them directly)
- have to deal with multiple clients at once
- have to run efficiently and securely
- cause problems for lots of clients if they crash or have bugs
- introduce privacy concerns: how can you trust the owner of the server your client is using?
for example, the web uses a client-server architecture
- web browsers are the clients
- pages are stored on web servers
for example, email is usually client-server
- email client is where you read and write email
- email server stores emails
Transaction Processing Systems¶
transactions are an important idea that appear in many practical applications that use databases
consider the example of withdrawing $100 from an online bank
- the command to withdraw $100 is sent to the bank
- the withdrawal is logged in a special separate logging database
these two operations must both succeed for the withdrawal to go through
if one, or both, of these fail, then the withdrawal fails
also, while these actions are running, no other actions can run (since they might interfere and corrupt this transaction)
together, these two examples form one transaction
in general, a transaction is a set of actions that are treated as a single group, and all actions must succeed for the transaction to succeed
practically all e-commerce systems use transaction processing — very imporant stuff!
Language Processing Systems¶
sometimes a programming language, or language-like system, is an appropriate idea
languages provide tremendous flexibility, although that comes at the cost of complexity
- programmers are already familiar with the idea of programming languages, and so may have some bias to this sort of architecture
for example, web pages uses HTML, a text-based mark-up language
- more generally, XML is a mark-up language that can be used to make different kinds of HTML-like languages
for example, many large and complex pieces of software (think PhotoShop, or Word) have scripting languages associated with them that allow for users to automate parts of it
another common example is regular expressions to help with text matching
- regular expressions can be thought of as a special-purpose language for customized for string matching
for example, spreadsheets provide a language for mathematical formulas
- a mix of algebraic and visual, i.e. visual cells contain algebraic expressions that can refer to other cells
for example, TeX is a language for type-setting technical documents
- TeX is very much like a programming language, but customized for typesetting technical documents
for example, chatbots have to process and generate natural language to communicate with users
- understanding a natural language, like English, is one of the grand problems of computer science
- haven’t achieved it yet, but perhaps limited forms of language interaction could be useful
programming language design and implementation is its own field of study in computer science, and many aspects of language-oriented architecture is well understood
Compiler Architecture¶
the notion of a compiler can be a useful architecture
essentially, a compiler transforms one chunk of data into another chunk of data
- e.g. C++ source code into machine-language code
for example, a compiler-like approach to architecture are so-called static website generators, like Sphinx, Hugo, Jekyll, etc.
roughly, these tools require that you create folders and files that contain the content of your website
then you run the tool on these files and folders to generate the website
this is very much like a compiler for websites
you could generalize the idea of a compiler to other systems
- e.g. consider the creation of an on-line course for teaching
- it has assignments, quizzes, marks, students, discussion groups, etc.
- but there is no one template that all teachers like
- different course consist of different activities
- so what you could do is provide a language-like specification of a course, and then compile that specification into a course
- if the course specification is inconsistent, incomplete, or somehow problematic, the compiler might be able to catch that error before creating the course
Interpreter Architecture¶
another idea from programming languages is an interpreter
an interpreter is essentially an interactive loop where the programmer can type expressions that get immediately evaluated
for example, Python and JavaScript can both be used as interpreted languages
in a command-line console for both, you can type in almost any Python/JavaScript expression and get immediate feedback
this is great for testing small pieces of code, or doing little calculations
it is generally much easier to use an interpreter for humans
in programming languages, interpreters tend to produce slower code because expressions get evaluated again and again;
the interpreter pattern could be useful in some situations
for example, a desktop calculator could be implemented as an interpreter
- as opposed to (or in addition to) a graphical copy of a traditional calculator
- the interpreter architecture makes it natural to track history, and even have variables to store values
- the Python interpreter is quite useful when used just as a calculator in this way
for example, consider a file system, such as the Windows file system or the Linux file system
one way to interact with the file system is through a command-line terminal, where you can issue various commands to list files, display files, change directories, etc.
the command-line terminal is a kind of interpreter that makes a lot of sense for interacting with the file system, at least in certain ways
- some operations, such as moving folders or arbitrary groups of files, might be more easily accomplished in a GUI
command-line-like interpreters have also shown up in places like web browser search boxes
- e.g. the address bar in Chrome is pretty smart, and knows some special commands, and even defaults to searching Google if it doesn’t
another example, in the Canvas student grades list, there is search-as-you-type that quickly filters out names that don’t match what you are typing
- thus you can easily find students by different kinds of search criteria
- the interactive experience very much feels like a little interpreter
- realizing that, it is then not hard to think what other ideas from interpreters may be applied to it